incubator-awf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmee...@apache.org
Subject svn commit: r1243729 [4/7] - in /incubator/deft/trunk: ./ awf-core/ awf-core/src/ awf-core/src/main/ awf-core/src/main/assembly/ awf-core/src/main/java/ awf-core/src/main/java/org/ awf-core/src/main/java/org/apache/ awf-core/src/main/java/org/apache/aw...
Date Mon, 13 Feb 2012 23:07:51 GMT
Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpRequestParser.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpRequestParser.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpRequestParser.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpRequestParser.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+import java.nio.ByteBuffer;
+
+import org.apache.awf.io.buffer.DynamicByteBuffer;
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Builds HttpRequest using a given ByteBuffer and already existing request object (unfinished).
+ * Uses an HttpBufferedLexer to retrieve Http Tokens and the HttpParsingContext stored in the request
+ * to maintain parsing state.
+ */
+public class HttpRequestParser {
+	
+	private static final Logger LOG = LoggerFactory.getLogger(HttpRequestParser.class);
+
+    private final HttpBufferedLexer lexer;
+
+    public HttpRequestParser(){
+        lexer = new HttpBufferedLexer();
+    }
+
+
+    public HttpRequestImpl parseRequestBuffer(ByteBuffer buffer){
+
+        return parseRequestBuffer(buffer, null);
+    }
+
+    /**
+     * Parse the data in the given buffer as an Http request. It handles segmented buffer
+     * when the given request is not null.
+     *
+     * @param buffer    ByteBuffer containing data to parse
+     * @param result    null if it's a new request or the incomplete request
+     * @return          new HttpRequestImpl if result is null representing a complete or incomplete request
+     *                  on error, it will return a MalformedHttpRequest.
+     */
+	public HttpRequestImpl parseRequestBuffer(ByteBuffer buffer,HttpRequestImpl result){
+
+
+		if (result == null){
+            result = new HttpRequestImpl();
+        }
+        int status = 1;
+        HttpParsingContext context = result.getContext();
+        context.setBuffer(buffer);
+
+        // while no errors and buffer not finished
+        while ((status = lexer.nextToken(context)) > 0){
+           switch (context.currentType){
+               case REQUEST_METHOD: {
+                   result.setMethod(HttpVerb.valueOf(context.getTokenValue()));break;
+               }
+               case REQUEST_URI:{
+                   result.setURI(context.getTokenValue());
+                   break;
+               }
+               case HTTP_VERSION:{
+                   result.setVersion(context.getTokenValue());break;
+               }
+               case HEADER_NAME:{
+                   context.persistHeaderName();break;
+               }
+               case HEADER_VALUE:{
+                   result.pushToHeaders(context.getLastHeaderName(), context.getTokenValue());break;
+               }
+           }
+        }
+
+        // There was an error while parsing request
+        if (status < 0){
+            result = MalFormedHttpRequest.instance;
+        } else if (context.currentType == HttpParsingContext.TokenType.BODY){
+            result.initKeepAlive();
+            // Copy body data to the request bodyBuffer
+            if (result.getContentLength() > 0){
+                pushRemainingToBody(context.buffer, result.getBodyBuffer(), result.getContentLength());
+            }
+            // TODO: Implement chunked encoding here
+        }
+
+
+        // release the context buffer
+        context.setBuffer(null);
+        buffer.clear();
+        return result;
+	}
+
+    /**
+     * Fill's the body buffer with the data retrieved from the given buffer starting
+     * at buffer position and copying given size byte.<br/>
+     * This will ensure that body buffer does not contain more than size byte.
+     */
+	private void pushRemainingToBody(ByteBuffer buffer, DynamicByteBuffer body, int size){
+		// If buffer is empty or there is no clength then skip this
+		if (size == 0 || !buffer.hasRemaining()){
+			return;
+		}
+
+		if (body.position() + buffer.remaining() > size){
+			body.put(buffer.array(),  buffer.position(), size - body.position());
+		}
+		else {
+			body.put(buffer.array(),  buffer.position(), buffer.remaining());
+		}
+	}
+
+}
\ No newline at end of file

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponse.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponse.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponse.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponse.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,188 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http;
+
+import java.io.File;
+
+import org.apache.awf.web.http.protocol.HttpStatus;
+
+/**
+ * An HTTP response build and sent to a client in response to a
+ * {@link HttpRequest}
+ */
+public interface HttpResponse {
+
+    /**
+     * Set the HTTP Response status (return) code, such as 200 for success.
+     * 
+     * @param status the <code>HttpStatus</code> to apply.
+     */
+    void setStatus(HttpStatus status);
+
+    /**
+     * Set an HTTP header value. If the header doesn't exist, it will be added.
+     * 
+     * @param header the unique header key
+     * @param value the string value
+     */
+    void setHeader(String header, String value);
+
+    /**
+     * Set whether ETags should be generated and applied. By default, they are
+     * not.
+     * 
+     * @param create <code>true</code> to generate and apply; <code>false</code>
+     *            otherwise.
+     */
+    void setCreateETag(boolean create);
+
+    /**
+     * Add a cookie to response.
+     * 
+     * @see #setCookie(String, String, long, String, String, boolean, boolean)
+     * @param name name of cookie
+     * @param value value of cookie
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value);
+
+    /**
+     * Add a cookie to response.
+     * 
+     * @see #setCookie(String, String, long, String, String, boolean, boolean)
+     * @param name name of cookie
+     * @param value value of cookie
+     * @param expiration expiration of cookie in seconds
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value, long expiration);
+
+    /**
+     * Add a cookie to response.
+     * 
+     * @see #setCookie(String, String, long, String, String, boolean, boolean)
+     * @param name name of cookie
+     * @param value value of cookie
+     * @param domain cookie domain
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value, String domain);
+
+    /**
+     * Add a cookie to response.
+     * 
+     * @see #setCookie(String, String, long, String, String, boolean, boolean)
+     * @param name name of cookie
+     * @param value value of cookie
+     * @param domain cookie domain
+     * @param path cookie path
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value, String domain, String path);
+
+    /**
+     * Add a cookie to response.
+     * 
+     * @see #setCookie(String, String, long, String, String, boolean, boolean)
+     * @param name name of cookie
+     * @param value value of cookie
+     * @param expiration expiration of cookie in seconds
+     * @param domain cookie domain
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value, long expiration, String domain);
+
+    /**
+     * Add a cookie to response.
+     * 
+     * @see #setCookie(String, String, long, String, String, boolean, boolean)
+     * @param name name of cookie
+     * @param value value of cookie
+     * @param expiration expiration of cookie in seconds
+     * @param domain cookie domain
+     * @param path cookie path
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value, long expiration, String domain, String path);
+
+    /**
+     * Add a cookie to response. The addition of a cookie with a name that was
+     * already inserted, causes the substitution of the previous cookie
+     * 
+     * @param name name of cookie
+     * @param value value of cookie
+     * @param expiration expiration of cookie in seconds
+     * @param domain cookie domain
+     * @param path cookie path
+     * @param secure set <code>Secure</code> property of cookie
+     * @param httpOnly set <code>HttpOnly</code> property of cookie
+     * @throws IllegalArgumentException if cookie name, or value, is not valid
+     */
+    void setCookie(String name, String value, long expiration, String domain, String path, boolean secure,
+            boolean httpOnly);
+
+    /**
+     * Removes a cookie. This method forces the removal of a cookie, by setting
+     * its expiration in the past.
+     * 
+     * @param name name of cookie to delete
+     */
+    void clearCookie(String name);
+
+    /**
+     * The given data data will be sent as the HTTP response upon next flush or
+     * when the response is finished.
+     * 
+     * @return this for chaining purposes.
+     */
+    HttpResponse write(String data);
+
+    /**
+     * The given data data will be sent as the HTTP response upon next flush or
+     * when the response is finished.
+     * 
+     * @param data the data to write.
+     * @return <code>this</code>, for chaining.
+     */
+    HttpResponse write(byte[] data);
+
+    /**
+     * Experimental support.
+     */
+    long write(File file);
+
+    /**
+     * Explicit flush.
+     * 
+     * @return the number of bytes that were actually written as the result of
+     *         this flush.
+     */
+    long flush();
+
+    /**
+     * Should only be invoked by third party asynchronous request handlers (or
+     * by the AWF framework for synchronous request handlers). If no previous
+     * (explicit) flush is invoked, the "Content-Length" and (where configured)
+     * "ETag" header will be calculated and inserted to the HTTP response.
+     * 
+     * @see #setCreateETag(boolean)
+     */
+    long finish();
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponseImpl.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponseImpl.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponseImpl.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpResponseImpl.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,314 @@
+/*
+ *  or more contributor license agreements.  See the NOTICE file
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+
+import org.apache.awf.io.buffer.DynamicByteBuffer;
+import org.apache.awf.util.Closeables;
+import org.apache.awf.util.CookieUtil;
+import org.apache.awf.util.DateUtil;
+import org.apache.awf.util.HttpUtil;
+import org.apache.awf.web.http.protocol.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.awf.web.http.HttpServerDescriptor.WRITE_BUFFER_SIZE;
+
+public class HttpResponseImpl implements HttpResponse {
+
+    private final static Logger logger = LoggerFactory.getLogger(HttpResponseImpl.class);
+
+    private final HttpProtocol protocol;
+    private final SelectionKey key;
+
+    private HttpStatus status = HttpStatus.SUCCESS_OK;
+
+    private final Map<String, String> headers = new HashMap<String, String>();
+    private final Map<String, String> cookies = Maps.newHashMap();
+    private boolean headersCreated = false;
+    private DynamicByteBuffer responseData = DynamicByteBuffer.allocate(WRITE_BUFFER_SIZE);
+
+    private boolean createETag;
+
+    public HttpResponseImpl(HttpProtocol protocol, SelectionKey key, boolean keepAlive) {
+        this.protocol = protocol;
+        this.key = key;
+        headers.put("Server", "Apache AWF/0.4.0-SNAPSHOT");
+        headers.put("Date", DateUtil.getCurrentAsString());
+        headers.put("Connection", keepAlive ? "Keep-Alive" : "Close");
+    }
+
+    @Override
+    public void setStatus(HttpStatus status) {
+        this.status = status;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setCreateETag(boolean create) {
+        createETag = create;
+    }
+
+    @Override
+    public void setHeader(String header, String value) {
+        headers.put(header, value);
+    }
+
+    @Override
+    public void setCookie(String name, String value) {
+        setCookie(name, value, -1, null, null, false, false);
+    }
+
+    @Override
+    public void setCookie(String name, String value, long expiration) {
+        setCookie(name, value, expiration, null, null, false, false);
+    }
+
+    @Override
+    public void setCookie(String name, String value, String domain) {
+        setCookie(name, value, -1, domain, null, false, false);
+    }
+
+    @Override
+    public void setCookie(String name, String value, String domain, String path) {
+        setCookie(name, value, -1, domain, path, false, false);
+    }
+
+    @Override
+    public void setCookie(String name, String value, long expiration, String domain) {
+        setCookie(name, value, expiration, domain, null, false, false);
+    }
+
+    @Override
+    public void setCookie(String name, String value, long expiration, String domain, String path) {
+        setCookie(name, value, expiration, domain, path, false, false);
+    }
+
+    @Override
+    public void setCookie(String name, String value, long expiration, String domain, String path, boolean secure,
+            boolean httpOnly) {
+        if (Strings.isNullOrEmpty(name)) {
+            throw new IllegalArgumentException("Cookie name is empty");
+        }
+        if (name.trim().startsWith("$")) {
+            throw new IllegalArgumentException("Cookie name is not valid");
+        }
+        StringBuffer sb = new StringBuffer(name.trim() + "=" + Strings.nullToEmpty(value).trim() + "; ");
+        if (CharMatcher.JAVA_ISO_CONTROL.countIn(sb) > 0) {
+            throw new IllegalArgumentException("Invalid cookie " + name + ": " + value);
+        }
+        if (expiration >= 0) {
+            if (expiration == 0) {
+                sb.append("Expires=" + DateUtil.getDateAsString(new Date(0)) + "; ");
+            } else {
+                sb.append("Expires=" + CookieUtil.maxAgeToExpires(expiration) + "; ");
+            }
+        }
+        if (!Strings.isNullOrEmpty(domain)) {
+            sb.append("Domain=" + domain.trim() + "; ");
+        }
+        if (!Strings.isNullOrEmpty(path)) {
+            sb.append("Path=" + path.trim() + "; ");
+        }
+        if (secure) {
+            sb.append("Secure; ");
+        }
+        if (httpOnly) {
+            sb.append("HttpOnly; ");
+        }
+        cookies.put(name, sb.toString());
+    }
+
+    @Override
+    public void clearCookie(String name) {
+        if (Strings.emptyToNull(name) != null) {
+            setCookie(name, null, 0);
+        }
+    }
+
+    @Override
+    public HttpResponse write(String data) {
+        return write(data.getBytes(Charsets.UTF_8));
+    }
+
+    @Override
+    public HttpResponse write(byte[] data) {
+        responseData.put(data);
+        return this;
+    }
+
+    @Override
+    public long flush() {
+        if (!headersCreated) {
+            String initial = createInitalLineAndHeaders();
+            responseData.prepend(initial);
+            headersCreated = true;
+        }
+
+        SocketChannel channel = (SocketChannel) key.channel();
+        responseData.flip(); // prepare for write
+        try {
+            channel.write(responseData.getByteBuffer());
+        } catch (IOException e) {
+            logger.error("ClosedChannelException during channel.write(): {}", e.getMessage());
+            Closeables.closeQuietly(protocol.getIOLoop(), key.channel());
+        }
+        long bytesFlushed = responseData.position();
+        if (protocol.getIOLoop().hasKeepAliveTimeout(channel)) {
+            protocol.prolongKeepAliveTimeout(channel);
+        }
+        if (responseData.hasRemaining()) {
+            responseData.compact(); // make room for more data be "read" in
+            try {
+                key.channel().register(key.selector(), SelectionKey.OP_WRITE); // TODO
+                // RS
+                // 110621,
+                // use
+                // IOLoop.updateHandler
+            } catch (ClosedChannelException e) {
+                logger.error("ClosedChannelException during flush(): {}", e.getMessage());
+                Closeables.closeQuietly(protocol.getIOLoop(), key.channel());
+            }
+            key.attach(responseData);
+        } else {
+            responseData.clear();
+        }
+        return bytesFlushed;
+    }
+
+    @Override
+    public long finish() {
+        long bytesWritten = 0;
+        SocketChannel clientChannel = (SocketChannel) key.channel();
+        ByteBuffer buffer = null;
+
+        if (key.attachment() instanceof MappedByteBuffer) {
+            MappedByteBuffer mbb = (MappedByteBuffer) key.attachment();
+            if (mbb.hasRemaining() && clientChannel.isOpen()) {
+                try {
+                    bytesWritten = clientChannel.write(mbb);
+                } catch (IOException e) {
+                    logger.warn("Could not write to channel: ", e.getMessage());
+                    Closeables.closeQuietly(key.channel());
+                }
+            }
+            buffer = mbb;
+        } else {
+            if (clientChannel.isOpen()) {
+                if (!headersCreated) {
+                    setEtagAndContentLength();
+                }
+                bytesWritten = flush();
+            }
+            // close (or register for read) if
+            // (a) DBB is attached but all data is sent to wire (hasRemaining ==
+            // false)
+            // (b) no DBB is attached (never had to register for write)
+            if (key.attachment() instanceof DynamicByteBuffer) {
+                buffer = ((DynamicByteBuffer) key.attachment()).getByteBuffer();
+            }
+        }
+        // Do Not Close the socket if there is more data to send or this is a CONTINUE
+        if ((buffer != null && buffer.hasRemaining()) || HttpStatus.SUCCESS_CONTINUE.equals(status)) {
+            return bytesWritten;
+        }
+        protocol.closeOrRegisterForRead(key);
+        return bytesWritten;
+    }
+
+    private void setEtagAndContentLength() {
+
+        if (createETag && responseData.position() > 0) {
+            setHeader("Etag", HttpUtil.getEtag(responseData.array()));
+        }
+        setHeader("Content-Length", String.valueOf(responseData.position()));
+    }
+
+    private String createInitalLineAndHeaders() {
+        StringBuilder sb = new StringBuilder(status.line());
+        for (Map.Entry<String, String> header : headers.entrySet()) {
+            sb.append(header.getKey());
+            sb.append(": ");
+            sb.append(header.getValue());
+            sb.append("\r\n");
+        }
+        for (String cookie : cookies.values()) {
+            sb.append("Set-Cookie: " + cookie + "\r\n");
+        }
+
+        sb.append("\r\n");
+        return sb.toString();
+    }
+
+    /**
+     * Experimental support.
+     */
+    @Override
+    public long write(File file) {
+        // setHeader("Etag", HttpUtil.getEtag(file));
+        setHeader("Content-Length", String.valueOf(file.length()));
+        long bytesWritten = 0;
+        flush(); // write initial line + headers
+
+        FileInputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            FileChannel fileChannel = in.getChannel();
+            long sizeNeeded = fileChannel.size();
+            bytesWritten = fileChannel.transferTo(0, sizeNeeded, ((SocketChannel) key.channel()));
+
+            if (bytesWritten < sizeNeeded) {
+                // Set channel Position to write rest of data from good starting
+                // offset
+                fileChannel.position(bytesWritten);
+                key.attach(in);
+            } else {
+                // Only close channel when file is totally transferred to
+                // SocketChannel
+                com.google.common.io.Closeables.closeQuietly(in);
+            }
+
+        } catch (IOException e) {
+            logger.error("Error writing (static file {}) to response: {}", file.getAbsolutePath(), e.getMessage());
+
+            // If an exception occurs here we should ensure that file is closed
+            com.google.common.io.Closeables.closeQuietly(in);
+        }
+
+        return bytesWritten;
+    }
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpServerDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpServerDescriptor.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpServerDescriptor.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/HttpServerDescriptor.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http;
+
+/**
+ * This class provides a possiblity to change the tunables used by AWF for the HTTP server configuration.
+ * Do not change the values unless you know what you are doing.
+ */
+public class HttpServerDescriptor {
+
+	/** The number of seconds AWF will wait for subsequent socket activity before closing the connection */
+	public static int KEEP_ALIVE_TIMEOUT = 30 * 1000;	// 30s
+	
+	/**
+	 * Size of the read (receive) buffer.
+	 * "Ideally, an HTTP request should not go beyond 1 packet. 
+	 * The most widely used networks limit packets to approximately 1500 bytes, so if you can constrain each request 
+	 * to fewer than 1500 bytes, you can reduce the overhead of the request stream." (from: http://bit.ly/bkksUu)
+	 */
+	public static int READ_BUFFER_SIZE = 1024;	// 1024 bytes
+	
+	/**
+	 * Size of the write (send) buffer.
+	 */
+	public static int WRITE_BUFFER_SIZE = 1024;	// 1024 bytes
+
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/MalFormedHttpRequest.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/MalFormedHttpRequest.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/MalFormedHttpRequest.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/MalFormedHttpRequest.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http;
+
+import com.google.common.collect.Maps;
+
+public class MalFormedHttpRequest extends HttpRequestImpl {
+
+    public static final MalFormedHttpRequest instance = new MalFormedHttpRequest();
+
+    /* Dummy HttpRequest that represents a malformed client HTTP request */
+    private MalFormedHttpRequest() {
+        super("GET / Mal formed request\r\n", Maps.<String, String> newHashMap());
+    }
+
+    protected boolean isFinished(){
+        return true;
+    }
+
+
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/AsynchronousHttpClient.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/AsynchronousHttpClient.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/AsynchronousHttpClient.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/AsynchronousHttpClient.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,414 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http.client;
+
+import java.io.IOException;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.awf.io.AsynchronousSocket;
+import org.apache.awf.io.IOLoop;
+import org.apache.awf.io.timeout.Timeout;
+import org.apache.awf.util.NopAsyncResult;
+import org.apache.awf.util.UrlUtil;
+import org.apache.awf.web.AsyncCallback;
+import org.apache.awf.web.AsyncResult;
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+
+/**
+ * This class implements a simple HTTP 1.1 client on top of the AWF {@code
+ * AsynchronousSocket}. It does not currently implement all applicable parts of
+ * the HTTP specification.
+ * 
+ * <pre>
+ * E.g the following is not supported.
+ *  - keep-alive
+ * 
+ * </pre>
+ * 
+ * This class has not been tested extensively in production and should be
+ * considered experimental. This HTTP client is
+ * inspired by
+ * https://github.com/facebook/tornado/blob/master/tornado/simple_httpclient.py
+ * and part of the documentation is simply copy pasted.
+ */
+public class AsynchronousHttpClient {
+
+    /** The <code>Logger</code>. */
+    private static final Logger logger = LoggerFactory.getLogger(AsynchronousHttpClient.class);
+
+    private static final long TIMEOUT = 15 * 1000; // 15s
+
+    private static final AsyncResult<Response> nopAsyncResult = NopAsyncResult.of(Response.class).nopAsyncResult;
+
+    private AsynchronousSocket socket;
+
+    private Request request;
+    private long requestStarted;
+    private Response response;
+    private AsyncResult<Response> responseCallback;
+
+    private Timeout timeout;
+
+    private final IOLoop ioLoop;
+
+    static final String HTTP_VERSION = "HTTP/1.1\r\n";
+    static final String USER_AGENT_HEADER = "User-Agent: AWF AsynchronousHttpClient/0.2-SNAPSHOT\r\n";
+    static final String NEWLINE = "\r\n";
+
+    /**
+     * Create an instance of this type.
+     */
+    public AsynchronousHttpClient() {
+        this(IOLoop.INSTANCE);
+    }
+
+    /**
+     * Create an instance of this type, utilising the given <code>IOLoop</code>.
+     * 
+     * @param ioLoop the <code>IOLoop</code> to use.
+     */
+    public AsynchronousHttpClient(final IOLoop ioLoop) {
+        this.ioLoop = ioLoop;
+    }
+
+    /**
+     * Make an asynchronous call as per the given <code>Request</code>, invoking
+     * the passed callback upon completion.
+     * 
+     * @param request the definition of the request to make.
+     * @param callback the callback to execute when the response is received.
+     * @throws IllegalArgumentException where the <code>URL</code> associated
+     *             with the given <code>Request</code> holds a <code>null</code>
+     *             host or invalid port number.
+     */
+    public void fetch(final Request request, final AsyncResult<Response> callback) {
+        this.request = request;
+        doFetch(callback, System.currentTimeMillis());
+    }
+
+    /**
+     * Make an asynchronous HTTP GET request against the specified URL, and
+     * invoke the given callback when the response upon completion.
+     * 
+     * @param url the URL from which to request, e.g.
+     *            <em>http://incubator.apache.org/deft/</em>.
+     * @param callback the callback to execute when the response is received.
+     * @throws IllegalArgumentException where the given URL is parsed to a
+     *             <code>null</code> host or with an invalid port number.
+     */
+    public void get(final String url, final AsyncResult<Response> callback) {
+        request = new Request(url, HttpVerb.GET);
+        doFetch(callback, System.currentTimeMillis());
+    }
+
+    /**
+     * Make an asynchronous HTTP POST request against the specified URL, and
+     * invoke the given callback when the response upon completion.
+     * 
+     * @param url the URL from which to request, e.g.
+     *            <em>http://incubator.apache.org/deft/</em>.
+     * @param body the message body to pass.
+     * @param callback the callback to execute when the response is received.
+     * @throws IllegalArgumentException where the given URL is parsed to a
+     *             <code>null</code> host or with an invalid port number.
+     */
+    public void post(final String url, final String body, final AsyncResult<Response> callback) {
+        request = new Request(url, HttpVerb.POST);
+        request.setBody(body);
+        doFetch(callback, System.currentTimeMillis());
+    }
+
+    /**
+     * Make an asynchronous HTTP POST request against the specified URL, and
+     * invoke the given callback when the response upon completion.
+     * 
+     * @param url the URL from which to request, e.g.
+     *            <em>http://incubator.apache.org/deft/</em>.
+     * @param body the message body to pass.
+     * @param callback the callback to execute when the response is received.
+     * @throws IllegalArgumentException where the given URL is parsed to a
+     *             <code>null</code> host or with an invalid port number.
+     */
+    public void post(final String url, final byte[] body, final AsyncResult<Response> callback) {
+        request = new Request(url, HttpVerb.POST);
+        request.setBody(body);
+        doFetch(callback, System.currentTimeMillis());
+    }
+
+    /**
+     * Make an asynchronous HTTP PUT request against the specified URL, and
+     * invoke the given callback when the response upon completion.
+     * 
+     * @param url the URL from which to request, e.g.
+     *            <em>http://incubator.apache.org/deft/</em>.
+     * @param body the message body to pass.
+     * @param callback the callback to execute when the response is received.
+     * @throws IllegalArgumentException where the given URL is parsed to a
+     *             <code>null</code> host or with an invalid port number.
+     */
+    public void put(final String url, final String body, final AsyncResult<Response> callback) {
+        request = new Request(url, HttpVerb.PUT);
+        request.setBody(body);
+        doFetch(callback, System.currentTimeMillis());
+    }
+
+    /**
+     * Perform the action of making a request against a known URL, before
+     * invoking the given callback type.
+     * 
+     * @param callback the callback to execute when the response is received.
+     * @param requestStarted the current time in milliseconds at which the
+     *            request was begun.
+     */
+    protected void doFetch(final AsyncResult<Response> callback, final long requestStarted) {
+
+        this.requestStarted = requestStarted;
+        try {
+            socket = new AsynchronousSocket(SocketChannel.open());
+        } catch (final IOException e) {
+            logger.error("Error opening SocketChannel: {}" + e.getMessage());
+        }
+
+        responseCallback = callback;
+        int port = request.getURL().getPort();
+        port = port == -1 ? 80 : port;
+
+        startTimeout();
+        socket.connect(request.getURL().getHost(), port, new AsyncResult<Boolean>() {
+            public void onFailure(final Throwable t) {
+                onConnectFailure(t);
+            }
+
+            public void onSuccess(final Boolean result) {
+                onConnect();
+            }
+        });
+    }
+
+    /**
+     * Close the underlaying {@code AsynchronousSocket}.
+     */
+    public void close() {
+        logger.debug("Closing http client connection...");
+        socket.close();
+    }
+
+    private void startTimeout() {
+        logger.debug("start timeout...");
+        timeout = new Timeout(System.currentTimeMillis() + TIMEOUT, new AsyncCallback() {
+            public void onCallback() {
+                onTimeout();
+            }
+        });
+        ioLoop.addTimeout(timeout);
+    }
+
+    private void cancelTimeout() {
+        logger.debug("cancel timeout...");
+        timeout.cancel();
+        timeout = null;
+    }
+
+    private void onTimeout() {
+        logger.debug("Pending operation (connect, read or write) timed out...");
+        final AsyncResult<Response> cb = responseCallback;
+        responseCallback = nopAsyncResult;
+        cb.onFailure(new TimeoutException("Connection timed out"));
+        close();
+    }
+
+    private void onConnect() {
+        logger.debug("Connected...");
+        cancelTimeout();
+        startTimeout();
+        socket.write(makeRequestLineAndHeaders().getBytes(), new AsyncCallback() {
+            public void onCallback() {
+                onWriteComplete();
+            }
+        });
+    }
+
+    private void onConnectFailure(final Throwable t) {
+        logger.debug("Connect failed...");
+        cancelTimeout();
+        final AsyncResult<Response> cb = responseCallback;
+        responseCallback = nopAsyncResult;
+        cb.onFailure(t);
+        close();
+    }
+
+    /**
+     * Create the request lines and header, populating the body where not
+     * <code>null</code>. Ignoring origin of inputs, the output for a POST
+     * request might resemble:
+     * <p>
+     * <code>
+     * POST /path/to/target HTTP/1.1<br/>
+     * Host: hostname<br/>
+     * User-Agent: AWF AsynchronousHttpClient/0.x-SNAPSHOT<br/>
+     * Content-Type: application/x-www-form-urlencoded<br/>
+     * Content-Length: 20<br/>
+     * <br/>
+     * paramName=paramValue<br/>
+	 * </code>
+     * </p>
+     * 
+     * @see HttpVerb#hasRequestBody(HttpVerb)
+     */
+    String makeRequestLineAndHeaders() {
+
+        int length = request.getBody() == null ? 0 : request.getBody().length;
+        final StringBuilder builder = new StringBuilder(length + 1024);
+        builder.append(request.getVerb()).append(" ").append(request.getURL().getPath()).append(" ");
+        builder.append(HTTP_VERSION).append("Host: ").append(request.getURL().getHost()).append(NEWLINE);
+        builder.append(USER_AGENT_HEADER);
+
+        if (request.getBody() != null) {
+            builder.append("Content-Type: ").append(request.getContentType().toString()).append(NEWLINE);
+            builder.append("Content-Length: ").append(length);
+            builder.append(NEWLINE).append(NEWLINE);
+            builder.append(new String(request.getBody(), Charsets.ISO_8859_1));
+        }
+
+        builder.append(NEWLINE);
+        return builder.toString();
+    }
+
+    private void onWriteComplete() {
+        logger.debug("onWriteComplete...");
+        cancelTimeout();
+        startTimeout();
+        socket.readUntil("\r\n\r\n".getBytes(), /* header delimiter */
+        new NaiveAsyncResult() {
+            public void onSuccess(final byte[] headers) {
+                onHeaders(headers);
+            }
+        });
+    }
+
+    private void onHeaders(final byte[] rawResult) {
+        String result = new String(rawResult, Charsets.ISO_8859_1);
+        logger.debug("headers: {}", result);
+        cancelTimeout();
+        response = new Response(requestStarted);
+        final String[] headers = result.split("\r\n");
+        response.setStatuLine(headers[0]); // first entry contains status
+        // line
+        // (e.g. HTTP/1.1 200 OK)
+        for (int i = 1; i < headers.length; i++) {
+            final String[] header = headers[i].split(": ");
+            response.setHeader(header[0], header[1]);
+        }
+
+        final String contentLength = response.getHeader("Content-Length");
+        startTimeout();
+        if (contentLength != null) {
+            socket.readBytes(Integer.parseInt(contentLength), new NaiveAsyncResult() {
+                public void onSuccess(byte[] body) {
+                    onBody(body);
+                }
+            });
+        } else { // Transfer-Encoding: chunked
+            socket.readUntil(NEWLINE.getBytes(), /* chunk delimiter */
+            new NaiveAsyncResult() {
+                public void onSuccess(byte[] octet) {
+                    onChunkOctet(octet);
+                }
+            });
+        }
+    }
+
+    /**
+     * JM: TODO, especially noting the redirects we follow....
+     */
+    private void onBody(final byte[] rawBody) {
+        final String body = new String(rawBody, Charsets.ISO_8859_1);
+        logger.debug("body size: {}", body.length());
+        cancelTimeout();
+        response.setBody(body);
+        if ((response.getStatusLine().contains("301") || response.getStatusLine().contains("302"))
+                && request.isFollowingRedirects() && request.getMaxRedirects() > 0) {
+            final String newUrl = UrlUtil.urlJoin(request.getURL(), response.getHeader("Location"));
+            request = new Request(newUrl, request.getVerb(), true, request.getMaxRedirects() - 1);
+            logger.debug("Following redirect, new url: {}, redirects left: {}", newUrl, request.getMaxRedirects());
+            doFetch(responseCallback, requestStarted);
+        } else {
+            close();
+            invokeResponseCallback();
+        }
+    }
+
+    private void onChunk(final byte[] rawChunk) {
+        final String chunk = new String(rawChunk, Charsets.ISO_8859_1);
+        logger.debug("chunk size: {}", chunk.length());
+        cancelTimeout();
+        response.addChunk(chunk.substring(0, chunk.length() - NEWLINE.length()));
+        startTimeout();
+        socket.readUntil(NEWLINE.getBytes(), /* chunk delimiter */
+        new NaiveAsyncResult() {
+            public void onSuccess(final byte[] octet) {
+                onChunkOctet(octet);
+            }
+        });
+    }
+
+    private void onChunkOctet(final byte[] rawOctet) {
+        final String octet = new String(rawOctet, Charsets.ISO_8859_1);
+        final int readBytes = Integer.parseInt(octet, 16);
+        logger.debug("chunk octet: {} (decimal: {})", octet, readBytes);
+        cancelTimeout();
+        startTimeout();
+        if (readBytes != 0) {
+            socket.readBytes(readBytes + NEWLINE.length(), // chunk delimiter is
+                    // \r\n
+                    new NaiveAsyncResult() {
+                        public void onSuccess(final byte[] chunk) {
+                            onChunk(chunk);
+                        }
+                    });
+        } else {
+            onBody(response.getBody().getBytes(Charsets.ISO_8859_1));
+        }
+    }
+
+    private void invokeResponseCallback() {
+        final AsyncResult<Response> cb = responseCallback;
+        responseCallback = nopAsyncResult;
+        cb.onSuccess(response);
+    }
+
+    /**
+     * Naive because all it does when an exception is thrown is log the
+     * exception.
+     */
+    private abstract class NaiveAsyncResult implements AsyncResult<byte[]> {
+
+        @Override
+        public void onFailure(final Throwable caught) {
+            logger.debug("onFailure: {}", caught);
+        }
+
+    }
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Request.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Request.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Request.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Request.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,190 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http.client;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.awf.web.http.protocol.ContentType;
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Request {
+
+    /** The <code>Logger</code>. */
+    private static final Logger logger = LoggerFactory.getLogger(Request.class);
+
+    /** The <code>URL</code> associated with the current <code>Request</code>. */
+    private final URL url;
+
+    /** The request type. */
+    private final HttpVerb verb;
+
+    /**
+     * Indicates whether 3xx Redirection codes should be followed; defaults to
+     * <code>true</code>.
+     * 
+     * @see AsynchronousHttpClient#onBody
+     */
+    private boolean followRedirects = true;
+
+    /**
+     * The maximum number of redirects to follow, where enabled; defaults to 7.
+     * 
+     * @see #followRedirects
+     */
+    private int maxRedirects = 7;
+
+    /** The body associated with the request. */
+    private byte[] body;
+
+    /** The type of content represented by this request. */
+    private String contentType = ContentType.APPLICATION_FORM_URLENCODED;
+
+    /**
+     * Create an instance of this type with the given <code>URL</code> and
+     * <code>HttpVerb</code>. Follows redirects and to a count as specified by
+     * default.
+     * 
+     * @throws RuntimeException
+     *             where a {@link MalformedURLException} is caught.
+     * @see #Request(String, HttpVerb, boolean, int)
+     */
+    public Request(final String url, final HttpVerb verb) {
+        try {
+            this.url = new URL(url);
+            this.verb = verb;
+        } catch (final MalformedURLException e) {
+            logger.error("Malformed URL: {}", e.getMessage());
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Create an instance of this type with the given <code>URL</code> and
+     * <code>HttpVerb</code>. Redirection behaviour and count are as specified.
+     * 
+     * @param url
+     *            the <code>URL</code> for the request.
+     * @param verb
+     *            the type of request to be made.
+     * @param followRedirects
+     *            <code>true</code> if redirects are to be followed;
+     *            <code>false</code> otherwise.
+     * @param maxRedirects
+     *            where redirects should be followed, the maximum number to
+     *            follow.
+     * @see #Request(String, HttpVerb)
+     * @see AsynchronousHttpClient#onBody
+     */
+    public Request(final String url, final HttpVerb verb, final boolean followRedirects, final int maxRedirects) {
+        this(url, verb);
+        this.followRedirects = followRedirects;
+        this.maxRedirects = maxRedirects;
+    }
+
+    /**
+     * Retrieve the <code>URL</code> associated with this <code>Request</code>.
+     * 
+     * @return the associated <code>URL</code>.
+     */
+    public URL getURL() {
+        return this.url;
+    }
+
+    /**
+     * Retrieve the current type of request.
+     * 
+     * @return the associated <code>HttpVerb</code>.
+     */
+    public HttpVerb getVerb() {
+        return this.verb;
+    }
+
+    /**
+     * Indicates whether 3xx Redirection codes should be followed.
+     * 
+     * @return <code>true</code> if redirects should be followed;
+     *         <code>false</code> otherwise.
+     * @see #followRedirects
+     */
+    public boolean isFollowingRedirects() {
+        return this.followRedirects;
+    }
+
+    /**
+     * Retrieve the maximum number of redirects this <code>Request</code> will
+     * follow.
+     * 
+     * @return an <code>int</code> representing the number of redirects.
+     */
+    public int getMaxRedirects() {
+        return this.maxRedirects;
+    }
+
+    /**
+     * Retrieve the body associated with this <code>Request</code>.
+     * 
+     * @return the associated body; may be <code>null</code>.
+     */
+    public byte[] getBody() {
+        return this.body;
+    }
+
+    /**
+     * Set the body applicable to this <code>Request</code>.
+     * 
+     * @param body
+     *            the body to apply.
+     */
+    public void setBody(final byte[] body) {
+        this.body = body;
+    }
+
+    /**
+     * Set the body applicable to this <code>Request</code>.
+     * 
+     * @param body
+     *            the body to apply.
+     */
+    public void setBody(final String body) {
+        this.body = body.getBytes();
+    }
+
+    /**
+     * Retrieve the content type associated with this <code>Request</code>.
+     * 
+     * @return the associated content type.
+     */
+    public String getContentType() {
+        return contentType;
+    }
+
+    /**
+     * Set the content type associated with this <code>Request</code>.
+     * 
+     * @param contentType
+     *            the content type to apply.
+     */
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Response.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Response.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Response.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/client/Response.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http.client;
+
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+public class Response {
+	
+	private final long requestTime;
+	private String statusLine;
+	private final Map<String, String> headers = Maps.newHashMap();
+	private String body = "";
+	
+	public Response(long requestStarted) {
+		requestTime = System.currentTimeMillis() - requestStarted;
+	}
+	
+	public void setStatuLine(String statusLine) {
+		this.statusLine = statusLine;
+	}
+	
+	public String getStatusLine() {
+		return statusLine;
+	}
+	
+	public void setHeader(String key, String value) {
+		headers.put(key, value);
+	}
+	
+	public String getHeader(String key) {
+		return headers.get(key);
+	}
+	
+	public void setBody(String body) {
+		this.body = body;
+	}
+	
+	public String getBody() {
+		return body;
+	}
+	
+	/**
+	 * @return The total execution time of the request/response round trip.
+	 */
+	public long getRequestTime() {
+		return requestTime;
+	}
+	
+	@Override
+	public String toString() {
+		return "HttpResponse [body=" + body + ", headers=" + headers
+				+ "\n, statusLine=" + statusLine + "]\n" + ", request time: " + requestTime +"ms";
+	}
+
+	void addChunk(String chunk) {
+		body += chunk;
+	}
+	
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/ContentType.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/ContentType.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/ContentType.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/ContentType.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http.protocol;
+
+/**
+ * A collection of known content types, for convenience.
+ */
+public class ContentType {
+
+    /** application/xml */
+    public static final String APPLICATION_XML = "application/xml";
+
+    /** application/json */
+    public static final String APPLICATION_JSON = "application/json";
+
+    /** application/x-www-form-urlencoded */
+    public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
+
+    /** application/octet-stream */
+    public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+
+    /** multipart/form-data */
+    public static final String MULTIPART_FORM_DATA = "multipart/form-data";
+
+    /** text/html */
+    public static final String TEXT_HTML = "text/html";
+
+    /** text/plain */
+    public static final String TEXT_PLAIN = "text/plain";
+
+    /** text/xml */
+    public static final String TEXT_XML = "text/xml";
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpStatus.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpStatus.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpStatus.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpStatus.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,219 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http.protocol;
+
+/**
+ * An <code>Enumeration</code> of all known HTTP status codes.
+ */
+public enum HttpStatus {
+
+	/**
+	 * 100 - CONTINUE
+	 */
+	SUCCESS_CONTINUE(100, "HTTP/1.1 100 Continue"),
+    /**
+     * 200 - OK
+     */
+    SUCCESS_OK(200, "HTTP/1.1 200 OK"),    
+    /**
+     * 201 - Created
+     */
+    SUCCESS_CREATED(201, "HTTP/1.1 201 Created"),
+    /**
+     * 202 - Accepted
+     */
+    SUCCESS_ACCEPTED(202, "HTTP/1.1 202 Accepted"),
+    /**
+     * 203 - Non-Authoritative Information
+     */
+    SUCCESS_NON_AUTHORATIVE_INFORMATION(203, "HTTP/1.1 203 Non-Authoritative Information"),
+    /**
+     * 204 - No Content
+     */
+    SUCCESS_NO_CONTENT(204, "HTTP/1.1 204 No Content"),
+    /**
+     * 205 - Reset Content
+     */
+    SUCCESS_RESET_CONTENT(205, "HTTP/1.1 205 Reset Content"),
+    /**
+     * 206 - Created
+     */
+    SUCCESS_PARTIAL_CONTENT(206, "HTTP/1.1 206 Partial Content"),
+
+    /**
+     * 300 - Multiple Choices
+     */
+    REDIRECTION_MULTIPLE_CHOICES(300, "HTTP/1.1 300 Multiple Choices"),
+    /**
+     * 301 - Moved Permanently
+     */
+    REDIRECTION_MOVED_PERMANENTLY(301, "HTTP/1.1 301 Moved Permanently"),
+    /**
+     * 302 - Found / Moved Temporarily
+     */
+    REDIRECTION_FOUND(302, "HTTP/1.1 302 Found"),
+    /**
+     * 303 - See Others
+     */
+    REDIRECTION_SEE_OTHER(303, "HTTP/1.1 303 See Other"),
+    /**
+     * 304 - Not Modified
+     */
+    REDIRECTION_NOT_MODIFIED(304, "HTTP/1.1 304 Not Modified"),
+    /**
+     * 305 - Use Proxy
+     */
+    REDIRECTION_USE_PROXY(305, "HTTP/1.1 305 Use Proxy"),
+    /**
+     * 307 - Temporary Redirect
+     */
+    REDIRECTION_TEMPORARILY_REDIRECT(307, "HTTP/1.1 307 Temporary Redirect"),
+
+    /**
+     * 400 - Bad Request
+     */
+    CLIENT_ERROR_BAD_REQUEST(400, "HTTP/1.1 400 Bad Request"),
+    /**
+     * 401 - Unauthorized
+     */
+    CLIENT_ERROR_UNAUTHORIZED(401, "HTTP/1.1 401 Unauthorized"),
+    /**
+     * 403 - Forbidden
+     */
+    CLIENT_ERROR_FORBIDDEN(403, "HTTP/1.1 403 Forbidden"),
+    /**
+     * 404 - Not Found
+     */
+    CLIENT_ERROR_NOT_FOUND(404, "HTTP/1.1 404 Not Found"),
+    /**
+     * 405 - Method Not Allowed
+     */
+    CLIENT_ERROR_METHOD_NOT_ALLOWED(405, "HTTP/1.1 405 Method Not Allowed"),
+    /**
+     * 406 - Not Acceptable
+     */
+    CLIENT_ERROR_NOT_ACCEPTABLE(406, "HTTP/1.1 406 Not Acceptable"),
+    /**
+     * 407 - Proxy Authentication Required
+     */
+    CLIENT_ERROR_PROXY_AUTHENTICATION_REQUIRED(407, "HTTP/1.1 407 Proxy Authentication Required"),
+    /**
+     * 408 - Request Timeout
+     */
+    CLIENT_ERROR_REQUEST_TIMEOUT(408, "HTTP/1.1 408 Request Timeout"),
+    /**
+     * 409 - Conflict
+     */
+    CLIENT_ERROR_CONFLICT(409, "HTTP/1.1 409 Conflict"),
+    /**
+     * 410 - Gone
+     */
+    CLIENT_ERROR_GONE(410, "HTTP/1.1 410 Gone"),
+    /**
+     * 411 - Length Required
+     */
+    CLIENT_ERROR_LENGTH_REQUIRED(411, "HTTP/1.1 411 Length Required"),
+    /**
+     * 412 - Precondition Failed
+     */
+    CLIENT_ERROR_PRECONDITION_FAILED(412, "HTTP/1.1 412 Precondition Failed"),
+    /**
+     * 413 - Request Entity Too Large
+     */
+    CLIENT_ERROR_REQUEST_ENTITY_TOO_LARGE(413, "HTTP/1.1 413 Request Entity Too Large"),
+    /**
+     * 414 - Bad Request
+     */
+    CLIENT_ERROR_REQUEST_URI_TOO_LONG(414, "HTTP/1.1 414 Request-URI Too Long"),
+    /**
+     * 415 - Unsupported Media Type
+     */
+    CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE(415, "HTTP/1.1 415 Unsupported Media Type"),
+    /**
+     * 416 - Requested Range Not Satisfiable
+     */
+    CLIENT_ERROR_REQUESTED_RANGE_NOT_SATISFIABLE(416, "HTTP/1.1 416 Requested Range Not Satisfiable"),
+    /**
+     * 417 - Expectation Failed
+     */
+    CLIENT_ERROR_EXPECTATION_FAILED(417, "HTTP/1.1 417 Expectation Failed"),
+
+    /**
+     * 500 - Internal Server Error
+     */
+    SERVER_ERROR_INTERNAL_SERVER_ERROR(500, "HTTP/1.1 500 Internal Server Error"),
+    /**
+     * 501 - Not Implemented
+     */
+    SERVER_ERROR_NOT_IMPLEMENTED(501, "HTTP/1.1 501 Not Implemented"),
+    /**
+     * 502 - Bad Gateway
+     */
+    SERVER_ERROR_BAD_GATEWAY(502, "HTTP/1.1 502 Bad Gateway"),
+    /**
+     * 503 - Service Unavailable
+     */
+    SERVER_ERROR_SERVICE_UNAVAILABLE(503, "HTTP/1.1 503 Service Unavailable"),
+    /**
+     * 504 - Gateway Timeout
+     */
+    SERVER_ERROR_GATEWAY_TIMEOUT(504, "HTTP/1.1 504 Gateway Timeout"),
+    /**
+     * 505 - HTTP Version Not Supported
+     */
+    SERVER_ERROR_HTTP_VERSION_NOT_SUPPORTED(505, "HTTP/1.1 505 HTTP Version Not Supported");
+
+    /** The code associated with this status, for example "404" for "Not Found". */
+    private int code;
+
+    /**
+     * The line associated with this status, "HTTP/1.1 501 Not Implemented".
+     */
+    private String line;
+
+    /**
+     * Create an instance of this type.
+     * 
+     * @param code the status code.
+     * @param phrase the associated phrase.
+     */
+    private HttpStatus(int code, String phrase) {
+        this.code = code;
+        line = phrase;
+    }
+
+    /**
+     * Retrieve the status code for this instance.
+     * 
+     * @return the status code.
+     */
+    public int code() {
+        return code;
+    }
+
+    /**
+     * Retrieve the status line for this instance.
+     * 
+     * @return the status line.
+     */
+    public String line() {
+        return line + "\r\n";
+    }
+}

Added: incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpVerb.java
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpVerb.java?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpVerb.java (added)
+++ incubator/deft/trunk/awf-core/src/main/java/org/apache/awf/web/http/protocol/HttpVerb.java Mon Feb 13 23:07:46 2012
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.awf.web.http.protocol;
+
+/**
+ * An <code>Enumeration</code> of all available HTTP verbs, as defined by <a
+ * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">Hypertext
+ * Transfer Protocol -- HTTP/1.1 (RFC 2616)</a>.
+ */
+public enum HttpVerb {
+
+    /**
+     * &quot;The OPTIONS method represents a request for information about the
+     * communication options available on the request/response chain identified
+     * by the Request-URI.&quot; (RFC 2616, 9.2)
+     */
+    OPTIONS,
+    /**
+     * &quotThe GET method means retrieve whatever information (in the form of
+     * an entity) is identified by the Request-URI.&quot; (RFC 2616, 9.3)
+     */
+    GET,
+    /**
+     * &quot;The HEAD method is identical to GET except that the server MUST NOT
+     * return a message-body in the response.&quot; (RFC 2616, 9.4)
+     */
+    HEAD,
+    /**
+     * &quot;The POST method is used to request that the origin server accept
+     * the entity enclosed in the request as a new subordinate of the resource
+     * identified by the Request-URI in the Request-Line.&quot; (RFC 2616, 9.5)
+     */
+    POST,
+    /**
+     * &quot;The PUT method requests that the enclosed entity be stored under
+     * the supplied Request-URI.&quot; (RFC 2616, 9.6)
+     */
+    PUT,
+    /**
+     * &quot;The DELETE method requests that the origin server delete the
+     * resource identified by the Request-URI.&quot; (RFC 2616, 9.7)
+     */
+    DELETE,
+    /**
+     * &quot;The TRACE method is used to invoke a remote, application-layer
+     * loop- back of the request message.&quot; (RFC 2616, 9.8)
+     */
+    TRACE,
+    /**
+     * &quot;This specification reserves the method name CONNECT for use with a
+     * proxy that can dynamically switch to being a tunnel &quot; (RFC 2616,
+     * 9.9)
+     */
+    CONNECT;
+}

Added: incubator/deft/trunk/awf-core/src/main/resources/logback.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/resources/logback.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/resources/logback.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/resources/logback.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<configuration>
+	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+		<!--
+			encoders are assigned the type
+			ch.qos.logback.classic.encoder.PatternLayoutEncoder by default
+		-->
+		<encoder>
+			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+			</pattern>
+		</encoder>
+	</appender>
+
+	<root level="warn">
+		<appender-ref ref="STDOUT" />
+	</root>
+</configuration>

Added: incubator/deft/trunk/awf-core/src/main/site/resources/css/site.css
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/resources/css/site.css?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/resources/css/site.css (added)
+++ incubator/deft/trunk/awf-core/src/main/site/resources/css/site.css Mon Feb 13 23:07:46 2012
@@ -0,0 +1,29 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#banner {
+  height: 90px;
+  background: none;
+}
+
+#bannerLeft img {
+  margin-left: 30px;
+  margin-top: 4px;
+}
+
+#bannerRight img {
+  margin: 17px;
+}

Added: incubator/deft/trunk/awf-core/src/main/site/resources/images/apache-incubator-logo.png
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/resources/images/apache-incubator-logo.png?rev=1243729&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/deft/trunk/awf-core/src/main/site/resources/images/apache-incubator-logo.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/deft/trunk/awf-core/src/main/site/resources/images/awf-logo.png
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/resources/images/awf-logo.png?rev=1243729&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/deft/trunk/awf-core/src/main/site/resources/images/awf-logo.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/api-guide.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/api-guide.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/api-guide.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/api-guide.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - API Guide</title>
+	</properties>
+	<body>
+		<section name="API Guide">
+			<p>This page is currently under development.</p>
+			<p>
+				Deft provides an API for the management of request/response pairs.
+		</p>
+			<p>
+				There are a number of examples in the source, under the
+				"org.apache.deft.example"
+				package.
+		</p>
+		</section>
+	</body>
+</document>

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/configuration-guide.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/configuration-guide.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/configuration-guide.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/configuration-guide.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - Configuration Guide</title>
+	</properties>
+	<body>
+		<section name="Configuration Guide">
+			<p>This page is currently under development.</p>
+		</section>
+	</body>
+</document>

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/contributor-guide.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/contributor-guide.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/contributor-guide.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/contributor-guide.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to You under 
+	the Apache License, Version 2.0 (the "License"); you may not use this file except 
+	in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+	Unless required by applicable law or agreed to in writing, software distributed under 
+	the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific language 
+	governing permissions and limitations under the License. -->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - Contributor Guide</title>
+	</properties>
+	<body>
+		<section name="Contributor Guide">
+			<p>
+				Anybody wishing to contribute code, ideas or their time in any other way is always welcome. This page provides an overview on how to go about becoming part of the team.
+			</p>
+
+			<subsection name="Getting Started">
+				<p>
+					To manage the code we use <a class="externalLink" href="http://subversion.apache.org/">Subversion</a>, and you can find more information on how we do that <a href="source-repository.html">here</a>. To start quickly, pull down a copy of the main branch, "trunk", like so:
+				</p>
+				<div class="source">
+					svn checkout http://svn.apache.org/repos/asf/incubator/deft/trunk/
+				</div>
+				<p>
+					Once the source is down, you should be able to import it into your chosen environment as you would any other Maven project. Eclipse	users might	want to firstly	run the following to generate project and classpath files:
+				</p>
+				<div class="source">
+					mvn eclipse:eclipse -DdownloadSources -DdownloadJavadocs
+				</div>
+				<p>
+					More information on this plug-in can be found <a class="externalLink" href="http://maven.apache.org/plugins/maven-eclipse-plugin/">here</a>, and if	it fails first time around you might want to build (see	below) and try again.
+				</p>
+				<p>
+					The project can be built within your development environment, or through standard Maven process:
+				</p>
+				<div class="source">
+					mvn clean install
+				</div>
+			</subsection>
+
+			<subsection name="Development">
+				<p>
+					Before anything else, it would be a good idea to join the various <a href="mail-lists.html">mailing lists</a> we run, to get a feel for the people and the discussions. Whether	you would like to submit a new idea, a code improvement, a patch to an existing issue or anything else at all take some time to introduce yourself and let us all know what you're up to.
+				</p>
+				<p>
+					A great way to start development is to review the list of outstanding issues in <a class="externalLink" href="https://issues.apache.org/jira/browse/DEFT">JIRA</a>, for which you will need to create an account. When development is completed, the first thing to do is ensure that the build - including all tests - completes without error. Following this, you should attach a patch merged against the current branch to the JIRA itself. Note that prior to submission you must select the toggle to permit ASF inclusion of the code, as per the <a href="license.html">licence</a>. The code will be reviewed, and possibly discussed before a committer puts it into the branch.
+				</p>
+			</subsection>
+
+			<subsection name="Continuous Integration">
+				<p>
+					Following any commit, the application will build through the <a class="externalLink" href="https://builds.apache.org/job/Deft/">Jenkins</a> environment. When the build completes, the job is done! Time for the next ticket...
+				</p>
+			</subsection>
+
+			<subsection name="Apache Guide">
+				<p>
+					The general Apache guide to getting involved can be found <a class="externalLink" href="http://www.apache.org/foundation/getinvolved.html">here</a>.
+				</p>
+			</subsection>
+		</section>
+	</body>
+</document>

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/faq.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/faq.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/faq.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/faq.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - FAQ</title>
+	</properties>
+	<body>
+		<section name="Frequently Asked Questions">
+
+			<subsection name="Why is there nothing here?">
+				<p>Deft is too shiny and brand-spanking new for this section. Be the
+					first to cause
+					trouble and ask questions!</p>
+			</subsection>
+		</section>
+	</body>
+</document>

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/index.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/index.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/index.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/index.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft</title>
+	</properties>
+	<body>
+		<section name="Apache Deft">
+			<p>
+				Apache Deft is a non-blocking, asynchronous, event driven high
+				performance web framework running on the JVM. Deft
+				is currently in
+				the
+				<a class="externalLink" href="http://incubator.apache.org/">Apache Incubator</a>
+				.
+			</p>
+			<p>
+				Find out more about Deft on our
+				<a class="externalLink" href="https://cwiki.apache.org/confluence/display/DEFT">wiki</a>
+				.
+			</p>
+
+			<subsection name="Getting Started">
+				<p>
+					For the impatient, we have a
+					<a href="quick-start-guide.html">Quick Start Guide</a>
+					available.
+				</p>
+				<p>
+					There is also an
+					<a href="faq.html">FAQ</a>
+					which covers common questions, and a
+					<a href="configuration-guide.html">configuration guide</a>
+					for reference.
+				</p>
+			</subsection>
+
+			<subsection name="Getting Involved">
+				<p>
+					Would you like to contribute, and help to improve Deft? Getting
+					<a href="contributor-guide.html">involved is easy</a>
+					.
+				</p>
+			</subsection>
+
+			<subsection name="Download">
+				<p>
+					Download a release of Deft from a
+					<a class="externalLink" href="http://www.apache.org/dyn/closer.cgi/incubator/deft/">nearby
+						mirror</a>
+					.
+				</p>
+			</subsection>
+
+			<subsection name="Disclaimer">
+				<p>
+					Apache Deft is an effort undergoing incubation at
+					<a class="externalLink" href="http://apache.org/">The Apache
+						Software Foundation</a>
+					(ASF), sponsored by the
+					<a class="externalLink" href="http://incubator.apache.org/">Apache Incubator PMC</a>
+					Incubation is required of all newly accepted projects until a
+					further
+					review indicates that the infrastructure, communications, and
+					decision making process have stabilized in a manner consistent with
+					other successful ASF projects. While incubation status is not
+					necessarily a reflection of the completeness or stability of the
+					code, it does indicate that the project has yet to be fully
+					endorsed
+					by the ASF.
+				</p>
+			</subsection>
+		</section>
+	</body>
+</document>

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/irc.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/irc.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/irc.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/irc.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - IRC Channel</title>
+	</properties>
+	<body>
+		<section name="IRC Channel">
+			<p>
+				To discuss all things Deft, the channel
+				<b>#deft</b>
+				is available on
+				<b>irc.freenode.org</b>
+				. Please do remember to bring all issues to the mailing lists and
+				tracking system, though.
+			</p>
+		</section>
+	</body>
+</document>

Added: incubator/deft/trunk/awf-core/src/main/site/xdoc/quick-start-guide.xml
URL: http://svn.apache.org/viewvc/incubator/deft/trunk/awf-core/src/main/site/xdoc/quick-start-guide.xml?rev=1243729&view=auto
==============================================================================
--- incubator/deft/trunk/awf-core/src/main/site/xdoc/quick-start-guide.xml (added)
+++ incubator/deft/trunk/awf-core/src/main/site/xdoc/quick-start-guide.xml Mon Feb 13 23:07:46 2012
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+	<!--
+		Licensed to the Apache Software Foundation (ASF) under one or more
+		contributor license agreements. See the NOTICE file distributed with
+		this work for additional information regarding copyright ownership.
+		The ASF licenses this file to You under the Apache License, Version
+		2.0 (the "License"); you may not use this file except in compliance
+		with the License. You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+		applicable law or agreed to in writing, software distributed under the
+		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - Quick Start Guide</title>
+	</properties>
+	<body>
+		<section name="Getting Started with Deft">
+			<p>This page is currently under development.</p>
+			<p>
+				The easiest way to start is to download the source and dive right
+				in.
+				There are examples under "org.apache.deft.example" to get you
+				started, and you can view the
+				<a href="apidocs/index.html">javadoc</a>
+				here.
+			</p>
+
+			<h4>Pre-requisites</h4>
+
+			<ul>
+				<li>Java 6, or higher</li>
+			</ul>
+		</section>
+	</body>
+</document>



Mime
View raw message