Coverage Report - co.stateful.rest.LocksRs
 
Classes in this File Line Coverage Branch Coverage Complexity
LocksRs
0%
0/19
0%
0/12
3.6
LocksRs$1
0%
0/2
N/A
3.6
 
 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.Locks;
 33  
 import com.rexsl.page.JaxbBundle;
 34  
 import com.rexsl.page.Link;
 35  
 import com.rexsl.page.PageBuilder;
 36  
 import java.io.IOException;
 37  
 import java.net.HttpURLConnection;
 38  
 import java.util.Map;
 39  
 import java.util.logging.Level;
 40  
 import javax.ws.rs.Consumes;
 41  
 import javax.ws.rs.DefaultValue;
 42  
 import javax.ws.rs.FormParam;
 43  
 import javax.ws.rs.GET;
 44  
 import javax.ws.rs.POST;
 45  
 import javax.ws.rs.Path;
 46  
 import javax.ws.rs.QueryParam;
 47  
 import javax.ws.rs.WebApplicationException;
 48  
 import javax.ws.rs.core.MediaType;
 49  
 import javax.ws.rs.core.Response;
 50  
 import org.apache.commons.io.IOUtils;
 51  
 import org.apache.commons.lang3.StringUtils;
 52  
 
 53  
 /**
 54  
  * Locks of a user.
 55  
  *
 56  
  * @author Yegor Bugayenko (yegor@tpc2.com)
 57  
  * @version $Id$
 58  
  * @checkstyle MultipleStringLiteralsCheck (500 lines)
 59  
  * @since 1.1
 60  
  */
 61  
 @Path("/k")
 62  0
 public final class LocksRs extends BaseRs {
 63  
 
 64  
     /**
 65  
      * Query param.
 66  
      * @checkstyle ConstantUsageCheck (3 lines)
 67  
      */
 68  
     private static final String PARAM = "name";
 69  
 
 70  
     /**
 71  
      * Get entrance page JAX-RS response.
 72  
      * @return The JAX-RS response
 73  
      * @throws Exception If some problem inside
 74  
      */
 75  
     @GET
 76  
     @Path("/")
 77  
     public Response index() throws Exception {
 78  0
         return new PageBuilder()
 79  
             .stylesheet("/xsl/locks.xsl")
 80  
             .build(StPage.class)
 81  
             .init(this)
 82  
             .append(
 83  
                 new JaxbBundle(
 84  
                     "documentation",
 85  
                     IOUtils.toString(
 86  
                         this.getClass().getResourceAsStream(
 87  
                             "doc-locks.html"
 88  
                         )
 89  
                     )
 90  
                 )
 91  
             )
 92  
             .append(this.list())
 93  
             .append(new JaxbBundle("menu", "locks"))
 94  
             .link(new Link("lock", "./lock"))
 95  
             .link(new Link("unlock", "./unlock"))
 96  
             .render()
 97  
             .build();
 98  
     }
 99  
 
 100  
     /**
 101  
      * Lock.
 102  
      * @param name Name of the lock
 103  
      * @param label Label
 104  
      * @return Response
 105  
      * @throws IOException If fails due to IO problem
 106  
      */
 107  
     @POST
 108  
     @Path("/lock")
 109  
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
 110  
     public Response lock(@FormParam(LocksRs.PARAM) final String name,
 111  
         @FormParam("label") @DefaultValue("none") final String label)
 112  
         throws IOException {
 113  0
         if (!name.matches("[0-9a-zA-Z\\-\\._\\$]{1,256}")) {
 114  0
             throw this.flash().redirect(
 115  
                 this.uriInfo().getBaseUriBuilder()
 116  
                     .clone()
 117  
                     .path(LocksRs.class)
 118  
                     .build(),
 119  
                 "1-256 letters, numbers or dashes",
 120  
                 Level.WARNING
 121  
             );
 122  
         }
 123  0
         if (label.isEmpty()) {
 124  0
             throw this.flash().redirect(
 125  
                 this.uriInfo().getBaseUriBuilder()
 126  
                     .clone()
 127  
                     .path(LocksRs.class)
 128  
                     .build(),
 129  
                 "label can't be empty",
 130  
                 Level.WARNING
 131  
             );
 132  
         }
 133  0
         if (this.user().locks().names().size() > Locks.MAX) {
 134  0
             throw this.flash().redirect(
 135  
                 this.uriInfo().getBaseUriBuilder()
 136  
                     .clone()
 137  
                     .path(LocksRs.class)
 138  
                     .build(),
 139  
                 "too many locks in your account",
 140  
                 Level.SEVERE
 141  
             );
 142  
         }
 143  0
         final String msg = this.user().locks().lock(name, label);
 144  0
         if (msg.isEmpty()) {
 145  0
             throw this.flash().redirect(
 146  
                 this.uriInfo().getBaseUriBuilder()
 147  
                     .clone()
 148  
                     .path(LocksRs.class)
 149  
                     .build(),
 150  
                 String.format("lock %s added successfully", name),
 151  
                 Level.INFO
 152  
             );
 153  
         }
 154  0
         throw new WebApplicationException(
 155  
             Response.status(HttpURLConnection.HTTP_CONFLICT)
 156  
                 .entity(msg)
 157  
                 .build()
 158  
         );
 159  
     }
 160  
 
 161  
     /**
 162  
      * Unlock.
 163  
      * @param name Name of the lock
 164  
      * @param label Optional label
 165  
      * @throws IOException If fails
 166  
      */
 167  
     @GET
 168  
     @Path("/unlock")
 169  
     public void unlock(@QueryParam(LocksRs.PARAM) final String name,
 170  
         @QueryParam("label") final String label)
 171  
         throws IOException {
 172  0
         if (StringUtils.isEmpty(label)) {
 173  0
             this.user().locks().unlock(name);
 174  
         } else {
 175  0
             final String match = this.user().locks().unlock(name, label);
 176  0
             if (!match.isEmpty()) {
 177  0
                 throw new WebApplicationException(
 178  
                     Response.status(HttpURLConnection.HTTP_CONFLICT)
 179  
                         .entity(String.format("label doesn't match: %s", match))
 180  
                         .build()
 181  
                 );
 182  
             }
 183  
         }
 184  0
         throw this.flash().redirect(
 185  
             this.uriInfo().getBaseUriBuilder()
 186  
                 .clone()
 187  
                 .path(LocksRs.class)
 188  
                 .build(),
 189  
             String.format("%s lock removed", name),
 190  
             Level.INFO
 191  
         );
 192  
     }
 193  
 
 194  
     /**
 195  
      * Get all locks of a user.
 196  
      * @return Locks
 197  
      * @throws IOException If fails
 198  
      */
 199  
     private JaxbBundle list() throws IOException {
 200  0
         return new JaxbBundle("locks").add(
 201  
             new JaxbBundle.Group<Map.Entry<String, String>>(
 202  
                 this.user().locks().names().entrySet()
 203  0
             ) {
 204  
                 @Override
 205  
                 public JaxbBundle bundle(final Map.Entry<String, String> ent) {
 206  0
                     return new JaxbBundle("lock")
 207  
                         .add("name", ent.getKey()).up()
 208  
                         .add("label", ent.getValue()).up();
 209  
                 }
 210  
             }
 211  
         );
 212  
     }
 213  
 
 214  
 }