Coverage Report - co.stateful.rest.BaseRs
 
Classes in this File Line Coverage Branch Coverage Complexity
BaseRs
75%
12/16
0%
0/2
1.583
BaseRs$1
80%
4/5
50%
1/2
1.583
BaseRs$2
100%
5/5
N/A
1.583
BaseRs$3
50%
3/6
50%
1/2
1.583
BaseRs$4
37%
3/8
50%
1/2
1.583
 
 1  
 /**
 2  
  * Copyright (c) 2014, stateful.co
 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 stateful.co 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 co.stateful.rest;
 31  
 
 32  
 import co.stateful.spi.Base;
 33  
 import co.stateful.spi.User;
 34  
 import com.jcabi.manifests.Manifests;
 35  
 import com.jcabi.urn.URN;
 36  
 import com.rexsl.page.BasePage;
 37  
 import com.rexsl.page.BaseResource;
 38  
 import com.rexsl.page.Inset;
 39  
 import com.rexsl.page.JaxbBundle;
 40  
 import com.rexsl.page.Link;
 41  
 import com.rexsl.page.Resource;
 42  
 import com.rexsl.page.auth.AuthInset;
 43  
 import com.rexsl.page.auth.Facebook;
 44  
 import com.rexsl.page.auth.Github;
 45  
 import com.rexsl.page.auth.Google;
 46  
 import com.rexsl.page.auth.Identity;
 47  
 import com.rexsl.page.auth.Provider;
 48  
 import com.rexsl.page.inset.FlashInset;
 49  
 import com.rexsl.page.inset.LinksInset;
 50  
 import com.rexsl.page.inset.VersionInset;
 51  
 import java.io.IOException;
 52  
 import java.net.URI;
 53  
 import java.util.logging.Level;
 54  
 import javax.ws.rs.core.HttpHeaders;
 55  
 import javax.ws.rs.core.MediaType;
 56  
 import javax.ws.rs.core.Response;
 57  
 import org.apache.commons.lang3.Validate;
 58  
 
 59  
 /**
 60  
  * Abstract RESTful resource.
 61  
  *
 62  
  * <p>The class is mutable and NOT thread-safe.
 63  
  *
 64  
  * @author Yegor Bugayenko (yegor@tpc2.com)
 65  
  * @version $Id$
 66  
  * @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
 67  
  */
 68  
 @Resource.Forwarded
 69  
 @Inset.Default(LinksInset.class)
 70  
 @SuppressWarnings("PMD.TooManyMethods")
 71  2
 public class BaseRs extends BaseResource {
 72  
 
 73  
     /**
 74  
      * Version of the system, to show in header.
 75  
      */
 76  1
     private static final String VERSION_LABEL = String.format(
 77  
         "%s/%s built on %s",
 78  
         // @checkstyle MultipleStringLiterals (3 lines)
 79  
         Manifests.read("Stateful-Version"),
 80  
         Manifests.read("Stateful-Revision"),
 81  
         Manifests.read("Stateful-Date")
 82  
     );
 83  
 
 84  
     /**
 85  
      * Test authentication provider.
 86  
      */
 87  1
     private static final Provider TESTER = new Provider() {
 88  
         @Override
 89  
         public Identity identity() {
 90  
             final Identity identity;
 91  1
             if ("1234567".equals(Manifests.read("Stateful-Revision"))) {
 92  0
                 identity = new Identity.Simple(
 93  
                     URN.create("urn:test:123456"),
 94  
                     "Localhost",
 95  
                     URI.create("http://img.stateful.com/unknown.png")
 96  
                 );
 97  
             } else {
 98  1
                 identity = Identity.ANONYMOUS;
 99  
             }
 100  1
             return identity;
 101  
         }
 102  
     };
 103  
 
 104  
     /**
 105  
      * Flash.
 106  
      * @return The inset with flash
 107  
      */
 108  
     @Inset.Runtime
 109  
     public final FlashInset flash() {
 110  1
         return new FlashInset(this);
 111  
     }
 112  
 
 113  
     /**
 114  
      * Supplementary inset.
 115  
      * @return The inset
 116  
      */
 117  
     @Inset.Runtime
 118  
     public final Inset supplementary() {
 119  1
         return new Inset() {
 120  
             @Override
 121  
             public void render(final BasePage<?, ?> page,
 122  
                 final Response.ResponseBuilder builder) {
 123  1
                 builder.header("X-Sttc-Version", BaseRs.VERSION_LABEL);
 124  1
                 builder.type(MediaType.TEXT_XML);
 125  1
                 builder.header(HttpHeaders.VARY, "Cookie");
 126  1
             }
 127  
         };
 128  
     }
 129  
 
 130  
     /**
 131  
      * Menu inset.
 132  
      * @return The inset
 133  
      */
 134  
     @Inset.Runtime
 135  
     public final Inset menu() {
 136  1
         return new Inset() {
 137  
             @Override
 138  
             public void render(final BasePage<?, ?> page,
 139  
                 final Response.ResponseBuilder builder) {
 140  1
                 if (!BaseRs.this.auth().identity().equals(Identity.ANONYMOUS)) {
 141  0
                     page.link(new Link("menu:home", "/"));
 142  0
                     page.link(new Link("menu:counters", "/counters"));
 143  0
                     page.link(new Link("menu:locks", "/k"));
 144  
                 }
 145  1
             }
 146  
         };
 147  
     }
 148  
 
 149  
     /**
 150  
      * Token inset.
 151  
      * @return The inset
 152  
      */
 153  
     @Inset.Runtime
 154  
     public final Inset token() {
 155  1
         return new Inset() {
 156  
             @Override
 157  
             public void render(final BasePage<?, ?> page,
 158  
                 final Response.ResponseBuilder builder) {
 159  1
                 if (!BaseRs.this.auth().identity().equals(Identity.ANONYMOUS)) {
 160  
                     try {
 161  0
                         page.append(
 162  
                             new JaxbBundle("token", BaseRs.this.user().token())
 163  
                         );
 164  0
                     } catch (final IOException ex) {
 165  0
                         throw new IllegalStateException(ex);
 166  0
                     }
 167  0
                     page.link(new Link("user:refresh", "/u/refresh"));
 168  
                 }
 169  1
             }
 170  
         };
 171  
     }
 172  
 
 173  
     /**
 174  
      * Version inset.
 175  
      * @return The inset
 176  
      */
 177  
     @Inset.Runtime
 178  
     public final Inset version() {
 179  1
         return new VersionInset(
 180  
             Manifests.read("Stateful-Version"),
 181  
             Manifests.read("Stateful-Revision"),
 182  
             Manifests.read("Stateful-Date")
 183  
         );
 184  
     }
 185  
 
 186  
     /**
 187  
      * Authentication inset.
 188  
      * @return The inset
 189  
      */
 190  
     @Inset.Runtime
 191  
     public final AuthInset auth() {
 192  3
         return new AuthInset(this, Manifests.read("Stateful-SecurityKey"))
 193  
             .with(new Auth(this, this.base()))
 194  
             // @checkstyle LineLength (3 lines)
 195  
             .with(new Facebook(this, Manifests.read("Stateful-FbId"), Manifests.read("Stateful-FbSecret")))
 196  
             .with(new Google(this, Manifests.read("Stateful-GoogleId"), Manifests.read("Stateful-GoogleSecret")))
 197  
             .with(new Github(this, Manifests.read("Stateful-GithubId"), Manifests.read("Stateful-GithubSecret")))
 198  
             .with(BaseRs.TESTER);
 199  
     }
 200  
 
 201  
     /**
 202  
      * Get current user.
 203  
      * @return User
 204  
      */
 205  
     protected final User user() {
 206  0
         final Identity identity = this.auth().identity();
 207  0
         if (identity.equals(Identity.ANONYMOUS)) {
 208  0
             throw FlashInset.forward(
 209  
                 this.uriInfo().getBaseUriBuilder().clone()
 210  
                     .path(IndexRs.class)
 211  
                     .build(),
 212  
                 "please login first",
 213  
                 Level.SEVERE
 214  
             );
 215  
         }
 216  0
         return this.base().user(identity.urn());
 217  
     }
 218  
 
 219  
     /**
 220  
      * Get spi.
 221  
      * @return The spi
 222  
      */
 223  
     protected final Base base() {
 224  3
         final Base base = Base.class.cast(
 225  
             this.servletContext().getAttribute(Base.class.getName())
 226  
         );
 227  3
         Validate.notNull(base, "spi is not initialized");
 228  3
         return base;
 229  
     }
 230  
 
 231  
 }