Coverage Report - com.jcabi.log.PreFormatter
 
Classes in this File Line Coverage Branch Coverage Complexity
PreFormatter
0%
0/33
0%
0/22
2.5
 
 1  
 /**
 2  
  * Copyright (c) 2012-2015, jcabi.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 jcabi.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.jcabi.log;
 31  
 
 32  
 import java.util.Arrays;
 33  
 import java.util.List;
 34  
 import java.util.concurrent.CopyOnWriteArrayList;
 35  
 import java.util.regex.Matcher;
 36  
 import java.util.regex.Pattern;
 37  
 import lombok.EqualsAndHashCode;
 38  
 import lombok.ToString;
 39  
 
 40  
 /**
 41  
  * Processor of formatting string and arguments, before sending it to
 42  
  * {@link String#format(String,Object[])}.
 43  
  *
 44  
  * @author Marina Kosenko (marina.kosenko@gmail.com)
 45  
  * @author Yegor Bugayenko (yegor@teamed.io)
 46  
  * @version $Id: 9d4a914e3f543b9532b9eca46eada73c95b48ed0 $
 47  
  * @since 0.1
 48  
  */
 49  0
 @ToString
 50  0
 @EqualsAndHashCode(of = { "format", "arguments" })
 51  
 final class PreFormatter {
 52  
 
 53  
     /**
 54  
      * Pattern used for matching format string arguments.
 55  
      */
 56  0
     private static final Pattern PATTERN = Pattern.compile(
 57  
         // @checkstyle LineLength (1 line)
 58  
         "%(?:\\d+\\$)?(\\[([A-Za-z\\-\\.0-9]+)\\])?[\\+\\-]?(?:\\d*(?:\\.\\d+)?)?[a-zA-Z%]"
 59  
     );
 60  
 
 61  
     /**
 62  
      * List of no argument specifier.
 63  
      */
 64  0
     private static final List<String> NO_ARG_SPECIFIERS =
 65  
         Arrays.asList("%n", "%%");
 66  
 
 67  
     /**
 68  
      * The formatting string.
 69  
      */
 70  
     private transient String format;
 71  
 
 72  
     /**
 73  
      * List of arguments.
 74  
      */
 75  
     private transient List<Object> arguments;
 76  
 
 77  
     /**
 78  
      * Public ctor.
 79  
      * @param fmt The formatting string
 80  
      * @param args The list of arguments
 81  
      */
 82  0
     public PreFormatter(final String fmt, final Object... args) {
 83  0
         this.process(fmt, args);
 84  0
     }
 85  
 
 86  
     /**
 87  
      * Get new formatting string.
 88  
      * @return The formatting text
 89  
      */
 90  
     public String getFormat() {
 91  0
         return this.format;
 92  
     }
 93  
 
 94  
     /**
 95  
      * Get new list of arguments.
 96  
      * @return The list of arguments
 97  
      */
 98  
     public Object[] getArguments() {
 99  0
         return this.arguments.toArray(new Object[this.arguments.size()]);
 100  
     }
 101  
 
 102  
     /**
 103  
      * Process the data provided.
 104  
      * @param fmt The formatting string
 105  
      * @param args The list of arguments
 106  
      */
 107  
     private void process(final String fmt, final Object... args) {
 108  0
         this.arguments = new CopyOnWriteArrayList<Object>();
 109  0
         final StringBuffer buf = new StringBuffer();
 110  0
         final Matcher matcher = PATTERN.matcher(fmt);
 111  0
         int pos = 0;
 112  0
         while (matcher.find()) {
 113  0
             final String group = matcher.group();
 114  0
             if (NO_ARG_SPECIFIERS.contains(group)) {
 115  0
                 matcher.appendReplacement(
 116  
                     buf,
 117  
                     Matcher.quoteReplacement(group)
 118  
                 );
 119  
             } else {
 120  0
                 final String decor = matcher.group(2);
 121  0
                 if (decor == null) {
 122  0
                     matcher.appendReplacement(
 123  
                         buf,
 124  
                         Matcher.quoteReplacement(group)
 125  
                     );
 126  0
                     this.arguments.add(args[pos]);
 127  
                 } else {
 128  0
                     matcher.appendReplacement(
 129  
                         buf,
 130  
                         Matcher.quoteReplacement(
 131  
                             group.replace(matcher.group(1), "")
 132  
                         )
 133  
                     );
 134  
                     try {
 135  0
                         this.arguments.add(
 136  
                             DecorsManager.decor(decor, args[pos])
 137  
                         );
 138  0
                     } catch (final DecorException ex) {
 139  0
                         this.arguments.add(
 140  
                             String.format("[%s]", ex.getMessage())
 141  
                         );
 142  0
                     }
 143  
                 }
 144  0
                 pos += 1;
 145  
             }
 146  0
         }
 147  0
         if (pos < args.length) {
 148  0
             throw new IllegalArgumentException(
 149  
                 String.format(
 150  
                     // @checkstyle LineLength (1 line)
 151  
                     "There are %d parameter(s) but only %d format argument(s) were provided.",
 152  
                     args.length,
 153  
                     pos
 154  
                 )
 155  
             );
 156  
         }
 157  0
         matcher.appendTail(buf);
 158  0
         this.format = buf.toString();
 159  0
     }
 160  
 
 161  
 }