Coverage Report - com.thindeck.cockpit.deck.TkCommand
 
Classes in this File Line Coverage Branch Coverage Complexity
TkCommand
6%
4/60
0%
0/30
4.571
 
 1  
 /**
 2  
  * Copyright (c) 2014-2015, Thindeck.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 thindeck.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.thindeck.cockpit.deck;
 31  
 
 32  
 import com.jcabi.xml.XML;
 33  
 import com.thindeck.api.Base;
 34  
 import com.thindeck.api.Deck;
 35  
 import com.thindeck.api.Decks;
 36  
 import com.thindeck.cockpit.RqUser;
 37  
 import java.io.IOException;
 38  
 import java.security.SecureRandom;
 39  
 import java.util.Arrays;
 40  
 import java.util.Date;
 41  
 import java.util.Random;
 42  
 import org.apache.commons.lang3.time.DateFormatUtils;
 43  
 import org.takes.Request;
 44  
 import org.takes.Response;
 45  
 import org.takes.Take;
 46  
 import org.takes.facets.flash.RsFlash;
 47  
 import org.takes.facets.forward.RsForward;
 48  
 import org.takes.rq.RqHref;
 49  
 import org.xembly.Directive;
 50  
 import org.xembly.Directives;
 51  
 
 52  
 /**
 53  
  * Post a command.
 54  
  *
 55  
  * @author Yegor Bugayenko (yegor@teamed.io)
 56  
  * @version $Id$
 57  
  * @since 0.5
 58  
  * @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
 59  
  * @checkstyle MultipleStringLiteralsCheck (500 lines)
 60  
  */
 61  
 @SuppressWarnings("PMD.AvoidDuplicateLiterals")
 62  
 public final class TkCommand implements Take {
 63  
 
 64  
     /**
 65  
      * Random.
 66  
      */
 67  1
     private static final Random RND = new SecureRandom();
 68  
 
 69  
     /**
 70  
      * Base.
 71  
      */
 72  
     private final transient Base base;
 73  
 
 74  
     /**
 75  
      * Ctor.
 76  
      * @param bse Base
 77  
      */
 78  1
     TkCommand(final Base bse) {
 79  1
         this.base = bse;
 80  1
     }
 81  
 
 82  
     @Override
 83  
     public Response act(final Request req) throws IOException {
 84  0
         final Decks decks = new RqUser(req, this.base).get().decks();
 85  0
         final String deck = new RqDeck(this.base, req).deck().name();
 86  0
         final String cmd = new RqHref.Smart(new RqHref.Base(req))
 87  
             .single("command");
 88  0
         final Deck.Smart smart = new Deck.Smart(decks.get(deck));
 89  0
         smart.update(TkCommand.answer(smart.xml(), cmd));
 90  0
         throw new RsForward(new RsFlash("thanks!"));
 91  
     }
 92  
 
 93  
     /**
 94  
      * Process command.
 95  
      * @param deck XML deck
 96  
      * @param cmd Command
 97  
      * @return Directives
 98  
      * @throws IOException If fails
 99  
      */
 100  
     private static Iterable<Directive> answer(final XML deck, final String cmd)
 101  
         throws IOException {
 102  0
         final Directives dirs = new Directives().xpath("/deck");
 103  0
         final String[] parts = cmd.trim().split("\\s+");
 104  0
         if ("domain".equals(parts[0])) {
 105  0
             dirs.append(
 106  
                 TkCommand.domain(
 107  
                     Arrays.copyOfRange(parts, 1, parts.length)
 108  
                 )
 109  
             );
 110  0
         } else if ("repo".equals(parts[0])) {
 111  0
             dirs.append(
 112  
                 TkCommand.repo(
 113  
                     deck,
 114  
                     Arrays.copyOfRange(parts, 1, parts.length)
 115  
                 )
 116  
             );
 117  0
         } else if ("container".equals(parts[0])) {
 118  0
             dirs.append(
 119  
                 TkCommand.container(
 120  
                     Arrays.copyOfRange(parts, 1, parts.length)
 121  
                 )
 122  
             );
 123  0
         } else if ("image".equals(parts[0])) {
 124  0
             dirs.append(
 125  
                 TkCommand.image(
 126  
                     Arrays.copyOfRange(parts, 1, parts.length)
 127  
                 )
 128  
             );
 129  
         }
 130  0
         return dirs;
 131  
     }
 132  
 
 133  
     /**
 134  
      * Domain command.
 135  
      * @param args Arguments
 136  
      * @return Directives
 137  
      * @throws IOException If fails
 138  
      */
 139  
     private static Iterable<Directive> domain(final String... args)
 140  
         throws IOException {
 141  0
         if (args.length == 0) {
 142  0
             throw new RsForward(
 143  
                 new RsFlash(
 144  
                     "'domain' command supports 'add' and 'remove'"
 145  
                 )
 146  
             );
 147  
         }
 148  0
         final Directives dirs = new Directives();
 149  0
         if ("add".equals(args[0])) {
 150  0
             dirs.addIf("domains").add("domain").set(args[1]);
 151  0
         } else if ("remove".equals(args[0])) {
 152  0
             dirs.xpath(
 153  
                 String.format(
 154  
                     "/deck/domains/domain[.='%s']", args[1]
 155  
                 )
 156  
             ).remove();
 157  
         } else {
 158  0
             throw new RsForward(
 159  
                 new RsFlash(
 160  
                     String.format(
 161  
                         "should be either 'add' or 'remove': '%s' is wrong",
 162  
                         args[0]
 163  
                     )
 164  
                 )
 165  
             );
 166  
         }
 167  0
         return dirs;
 168  
     }
 169  
 
 170  
     /**
 171  
      * Repo command.
 172  
      * @param deck XML deck
 173  
      * @param args Arguments
 174  
      * @return Directives
 175  
      * @throws IOException If fails
 176  
      */
 177  
     private static Iterable<Directive> repo(final XML deck,
 178  
         final String... args) throws IOException {
 179  0
         if (args.length == 0) {
 180  0
             throw new RsForward(
 181  
                 new RsFlash(
 182  
                     "'repo' command supports 'put'"
 183  
                 )
 184  
             );
 185  
         }
 186  0
         final Directives dirs = new Directives();
 187  0
         if ("put".equals(args[0])) {
 188  0
             if (deck.nodes("/deck/images/image").size() > 2) {
 189  0
                 throw new IllegalArgumentException(
 190  
                     "there are too many images as is, waste a few first"
 191  
                 );
 192  
             }
 193  0
             final String today = DateFormatUtils.ISO_DATETIME_FORMAT.format(
 194  
                 new Date()
 195  
             );
 196  0
             dirs.xpath("/deck").add("repo")
 197  
                 .attr("added", today)
 198  
                 .add("name")
 199  
                 .set(String.format("%08x", TkCommand.RND.nextInt())).up()
 200  
                 .add("uri").set(args[1]);
 201  0
         } else if ("remove".equals(args[0])) {
 202  0
             dirs.xpath("/deck/repo").remove();
 203  
         } else {
 204  0
             throw new IllegalArgumentException(
 205  
                 String.format(
 206  
                     "should be only 'put': '%s' is wrong",
 207  
                     args[0]
 208  
                 )
 209  
             );
 210  
         }
 211  0
         return dirs;
 212  
     }
 213  
 
 214  
     /**
 215  
      * Container command.
 216  
      * @param args Arguments
 217  
      * @return Directives
 218  
      * @throws IOException If fails
 219  
      */
 220  
     private static Iterable<Directive> container(final String... args)
 221  
         throws IOException {
 222  0
         if (args.length == 0) {
 223  0
             throw new RsForward(
 224  
                 new RsFlash(
 225  
                     "'container' command supports 'waste'"
 226  
                 )
 227  
             );
 228  
         }
 229  0
         final Directives dirs = new Directives();
 230  0
         if ("waste".equals(args[0])) {
 231  0
             final String today = DateFormatUtils.ISO_DATETIME_FORMAT.format(
 232  
                 new Date()
 233  
             );
 234  0
             dirs.xpath(
 235  
                 String.format(
 236  
                     "/deck/containers/container[name='%s']",
 237  
                     args[1]
 238  
                 )
 239  
             ).attr("waste", today);
 240  0
         } else {
 241  0
             throw new IllegalArgumentException(
 242  
                 String.format(
 243  
                     "should be only 'waste': '%s' is wrong",
 244  
                     args[0]
 245  
                 )
 246  
             );
 247  
         }
 248  0
         return dirs;
 249  
     }
 250  
 
 251  
     /**
 252  
      * Image command.
 253  
      * @param args Arguments
 254  
      * @return Directives
 255  
      * @throws IOException If fails
 256  
      */
 257  
     private static Iterable<Directive> image(final String... args)
 258  
         throws IOException {
 259  0
         if (args.length == 0) {
 260  0
             throw new RsForward(
 261  
                 new RsFlash(
 262  
                     "'image' command supports 'waste'"
 263  
                 )
 264  
             );
 265  
         }
 266  0
         final Directives dirs = new Directives();
 267  0
         if ("waste".equals(args[0])) {
 268  0
             final String today = DateFormatUtils.ISO_DATETIME_FORMAT.format(
 269  
                 new Date()
 270  
             );
 271  0
             dirs.xpath(
 272  
                 String.format(
 273  
                     "/deck/images/image[name='%s']",
 274  
                     args[1]
 275  
                 )
 276  
             ).attr("waste", today);
 277  0
         } else {
 278  0
             throw new IllegalArgumentException(
 279  
                 String.format(
 280  
                     "should be only 'waste': '%s' is wrong argument",
 281  
                     args[0]
 282  
                 )
 283  
             );
 284  
         }
 285  0
         return dirs;
 286  
     }
 287  
 
 288  
 }