View Javadoc
1   /**
2    * Copyright (c) 2012-2017, s3auth.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the s3auth.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.s3auth.hosts;
31  
32  import com.jcabi.aspects.Immutable;
33  import com.jcabi.aspects.Loggable;
34  import com.jcabi.immutable.Array;
35  import java.io.Closeable;
36  import java.io.IOException;
37  import java.io.OutputStream;
38  import java.net.HttpURLConnection;
39  import java.util.Collection;
40  import java.util.Date;
41  import javax.validation.constraints.NotNull;
42  import lombok.EqualsAndHashCode;
43  import lombok.ToString;
44  import org.apache.commons.codec.digest.DigestUtils;
45  import org.apache.commons.io.Charsets;
46  import org.apache.commons.io.IOUtils;
47  import org.apache.http.HttpHeaders;
48  
49  /**
50   * Found resource.
51   *
52   * @author Yegor Bugayenko (yegor@tpc2.com)
53   * @version $Id: c31d6b662e1c3a6afeb91768a36717e936101741 $
54   * @since 0.0.1
55   */
56  @Immutable
57  @SuppressWarnings("PMD.TooManyMethods")
58  public interface Resource extends Closeable {
59  
60      /**
61       * Get HTTP status.
62       * @return The status
63       */
64      int status();
65  
66      /**
67       * Write its content to the writer.
68       * @param stream The stream to write to
69       * @return How many bytes were written
70       * @throws IOException If some error with I/O inside
71       */
72      long writeTo(OutputStream stream) throws IOException;
73  
74      /**
75       * Get a collection of all necessary HTTP headers for this resource.
76       * @return Collection of HTTP headers
77       * @throws IOException If some error with I/O inside
78       */
79      Collection<String> headers() throws IOException;
80  
81      /**
82       * Get its ETag.
83       * @return The etag
84       * @link <a href="http://en.wikipedia.org/wiki/HTTP_ETag">ETag</a>
85       */
86      String etag();
87  
88      /**
89       * Get its last modified date.
90       * @return The last modified date.
91       */
92      Date lastModified();
93  
94      /**
95       * Get the resource's HTTP Content-Type.
96       * @return The HTTP Content-Type of the resource.
97       */
98      String contentType();
99  
100     /**
101      * Simple resource made out of plain text.
102      */
103     @Immutable
104     @ToString
105     @EqualsAndHashCode(of = "text")
106     @Loggable(Loggable.DEBUG)
107     final class PlainText implements Resource {
108         /**
109          * Plain text to show.
110          */
111         @Immutable.Array
112         private final transient byte[] text;
113         /**
114          * Last modified date to return. Equal to the time of object creation.
115          */
116         private final transient long modified = System.currentTimeMillis();
117         /**
118          * Headers associated with this resource.
119          */
120         private final Array<String> hdrs;
121         /**
122          * Public ctor.
123          * @param txt The text to show
124          */
125         public PlainText(@NotNull final String txt) {
126             this.text = txt.getBytes(Charsets.UTF_8);
127             this.hdrs = new Array<String>(
128                 String.format(
129                     "%s: %s",
130                     HttpHeaders.CONTENT_TYPE,
131                     this.contentType()
132                 ),
133                 String.format(
134                     "%s: %d",
135                     HttpHeaders.CONTENT_LENGTH,
136                     this.text.length
137                 )
138             );
139         }
140         @Override
141         public int status() {
142             return HttpURLConnection.HTTP_OK;
143         }
144         @Override
145         public long writeTo(@NotNull final OutputStream stream)
146             throws IOException {
147             IOUtils.write(this.text, stream);
148             return this.text.length;
149         }
150         @Override
151         public String etag() {
152             return DigestUtils.md5Hex(this.text);
153         }
154         @Override
155         public Date lastModified() {
156             return new Date(this.modified);
157         }
158         @Override
159         public String contentType() {
160             return "text/plain";
161         }
162         @Override
163         @NotNull
164         public Collection<String> headers() {
165             return this.hdrs;
166         }
167         @Override
168         public void close() {
169             // nothing to do
170         }
171     }
172 
173 }