1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.logging.internal.helpers

File MessageParser.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

38
68
11
4
227
149
33
0.49
6.18
2.75
3

Classes

Class Line # Actions
MessageParser 22 62 0% 28 13
0.877358587.7%
MessageParser.MessageElement 44 2 0% 2 0
1.0100%
MessageParser.MessageIndex 59 3 0% 2 0
1.0100%
MessageParser.MessageString 76 1 0% 1 0
1.0100%
 

Contributing tests

This file is covered by 13 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.logging.internal.helpers;
21   
 
22    public class MessageParser
23    {
24    /**
25    * Argument syntax in message pattern.
26    */
27    public static final String ARGUMENT_STR = "{}";
28   
29    /**
30    * Argument start syntax in message pattern.
31    */
32    static final char ARGUMENT_START = '{';
33   
34    /**
35    * Argument end syntax in message pattern.
36    */
37    static final char ARGUMENT_STOP = '}';
38   
39    /**
40    * Character used to escape syntax in message pattern.
41    */
42    private static final char ESCAPE_CHAR = '\\';
43   
 
44    public static class MessageElement
45    {
46    private String string;
47   
 
48  10616 toggle protected MessageElement(String string)
49    {
50  10616 this.string = string;
51    }
52   
 
53  6327 toggle public String getString()
54    {
55  6327 return this.string;
56    }
57    }
58   
 
59    public static class MessageIndex extends MessageElement
60    {
61    private int index;
62   
 
63  4301 toggle public MessageIndex(String string, int index)
64    {
65  4301 super(string);
66   
67  4301 this.index = index;
68    }
69   
 
70  20 toggle public int getIndex()
71    {
72  20 return this.index;
73    }
74    }
75   
 
76    public static class MessageString extends MessageElement
77    {
 
78  6315 toggle public MessageString(String string)
79    {
80  6315 super(string);
81    }
82    }
83   
84    private char[] buffer;
85   
86    private boolean translations;
87   
88    private int bufferIndex;
89   
90    private int currentMessageIndex;
91   
92    private boolean previousWasDoubleEscaped;
93   
94    private MessageElement currentMessageElement;
95   
 
96  2213 toggle public MessageParser(String buffer, boolean translations)
97    {
98  2213 this(buffer.toCharArray(), translations);
99    }
100   
 
101  2213 toggle public MessageParser(char[] buffer, boolean translations)
102    {
103  2213 this.buffer = buffer;
104  2213 this.translations = translations;
105    }
106   
 
107  2212 toggle public MessageElement getCurrentMessageElement()
108    {
109  2212 return this.currentMessageElement;
110    }
111   
 
112  12829 toggle public MessageElement next()
113    {
114  12829 StringBuilder str = new StringBuilder();
115   
116  12829 int i = this.bufferIndex;
117  80125 for (; i < this.buffer.length; ++i) {
118  75776 if (this.buffer[i] == ESCAPE_CHAR) {
119  6 int nb = countEscaping(i);
120   
121  6 int iNext = i + nb;
122   
123  6 if (iNext == this.buffer.length) {
124  0 i = iNext;
125  0 break;
126    } else {
127  6 if (isMessageIndex(iNext) > iNext) {
128  6 str.append(this.buffer, this.bufferIndex, iNext - 1 - this.bufferIndex);
129  6 i = iNext;
130  6 this.bufferIndex = i;
131   
132    // Only the last two escaping characters are taken into account, all the previous are plain text
133  6 if (nb > 1) {
134  4 this.previousWasDoubleEscaped = true;
135  4 this.currentMessageElement = new MessageString(str.toString());
136   
137  4 return this.currentMessageElement;
138    }
139    } else {
140  0 i = iNext;
141    }
142    }
143  75770 } else if (this.buffer[i] == ARGUMENT_START) {
144  8478 int iNext = isMessageIndex(i);
145  8478 if (iNext != i) {
146  8476 if (this.bufferIndex == i) {
147    // Create and return new MessageIndex
148  4301 String messageIndexString = String.valueOf(this.buffer, i, iNext - i);
149   
150  4301 int messageIndex;
151  4301 if (this.translations && messageIndexString.length() > 2) {
152  8 messageIndex =
153    Integer.parseInt(messageIndexString.substring(1, messageIndexString.length() - 1));
154    } else {
155  4293 messageIndex = this.currentMessageIndex;
156    }
157  4301 ++this.currentMessageIndex;
158   
159  4301 if (this.previousWasDoubleEscaped) {
160  4 this.currentMessageElement = new MessageIndex("\\" + messageIndexString, messageIndex);
161    } else {
162  4297 this.currentMessageElement = new MessageIndex(messageIndexString, messageIndex);
163    }
164  4301 this.bufferIndex = iNext;
165   
166  4301 return this.currentMessageElement;
167    } else {
168    // Return previous plain text, the actual MessageIndex will be the next element
169  4175 this.currentMessageElement =
170    new MessageString(String.valueOf(this.buffer, this.bufferIndex, i - this.bufferIndex));
171  4175 this.bufferIndex = i;
172   
173  4175 return this.currentMessageElement;
174    }
175    }
176    }
177    }
178   
179  4349 if (i == this.bufferIndex) {
180  2213 return null;
181    }
182   
183  2136 this.currentMessageElement = new MessageString(String.valueOf(this.buffer, this.bufferIndex, i - this.bufferIndex));
184   
185  2136 this.bufferIndex = i;
186   
187  2136 return this.currentMessageElement;
188    }
189   
 
190  6 toggle private int countEscaping(int current)
191    {
192  6 int nb = 1;
193   
194  12 for (int i = current + 1; i < this.buffer.length && this.buffer[i] == ESCAPE_CHAR; ++i) {
195  6 ++nb;
196    }
197   
198  6 return nb;
199    }
200   
 
201  8484 toggle private int isMessageIndex(int current)
202    {
203  8484 int i = current;
204   
205  8484 if (this.buffer[current] != ARGUMENT_START) {
206  0 return current;
207    }
208   
209  8484 ++i;
210   
211  8484 if (i == this.buffer.length) {
212  0 return current;
213    }
214   
215  8484 if (this.translations) {
216  47 for (; this.buffer[i] != ARGUMENT_STOP; ++i) {
217  16 if (i == this.buffer.length) {
218  0 return current;
219  16 } else if (this.buffer[i] < '0' || this.buffer[i] > '9') {
220  0 return current;
221    }
222    }
223    }
224   
225  8484 return this.buffer[i] == ARGUMENT_STOP ? i + 1 : current;
226    }
227    }