Coverage Report - net.sf.jmatchparser.template.engine.parameter.Parameter
 
Classes in this File Line Coverage Branch Coverage Complexity
Parameter
100%
115/115
100%
86/86
5,545
 
 1  
 /*
 2  
  * Copyright (c) 2006 - 2011 Michael Schierl
 3  
  * All rights reserved.
 4  
  * 
 5  
  * This program is free software: you can redistribute it and/or modify
 6  
  * it under the terms of the GNU General Public License as published by
 7  
  * the Free Software Foundation, either version 2 of the License, or
 8  
  * (at your option) any later version.
 9  
  * 
 10  
  * This program 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
 13  
  * GNU General Public License for more details.
 14  
  * 
 15  
  * You should have received a copy of the GNU General Public License
 16  
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 17  
  */
 18  
 package net.sf.jmatchparser.template.engine.parameter;
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.List;
 22  
 import java.util.regex.Matcher;
 23  
 
 24  
 import net.sf.jmatchparser.template.engine.ParserState;
 25  
 
 26  
 public class Parameter {
 27  
 
 28  
         public static Parameter parseParameter(String text, String[] specialtags) {
 29  614
                 return parseParameters(text, 1, 1, 0, specialtags)[0];
 30  
         }
 31  
 
 32  
         public static Parameter parseRawParameter(String rawText) {
 33  162
                 return parseRawParameters(rawText, 1, 1, 0)[0];
 34  
         }
 35  
 
 36  
         public static Parameter[] parseParameters(String text, int minparamcount, int maxparamcount, int noCommaCount, String[] specialtags) {
 37  728
                 if (text.indexOf('\1') != -1 || text.indexOf('\2') != -1)
 38  2
                         throw new RuntimeException("Invalid control characters found");
 39  726
                 String start = specialtags[0], end = specialtags[1];
 40  726
                 String startentity = specialtags[2], endentity = specialtags[3];
 41  726
                 if (startentity == null)
 42  724
                         startentity = "\1[\2";
 43  726
                 if (endentity == null)
 44  724
                         endentity = "\1]\2";
 45  726
                 text = text.replace(start, "\1").replace(end, "\2");
 46  726
                 text = text.replace(startentity, start).replace(endentity, end);
 47  726
                 return parseRawParameters(text, minparamcount, maxparamcount, noCommaCount);
 48  
         }
 49  
 
 50  
         public static Parameter[] parseRawParameters(String rawText, int minparamcount, int maxparamcount, int noCommaCount) {
 51  906
                 if (rawText.indexOf('\0') != -1)
 52  1
                         throw new RuntimeException("Invalid control characters found");
 53  905
                 Parameter[] result = new Parameter[maxparamcount];
 54  905
                 int current = 0;
 55  905
                 StringBuilder literalBuffer = new StringBuilder();
 56  905
                 List<Tag> elems = new ArrayList<Tag>();
 57  
                 while (true) {
 58  
                         int pos;
 59  2776
                         if (noCommaCount > 0) {
 60  199
                                 pos = literalBuffer.indexOf(" ");
 61  199
                                 int pos2 = literalBuffer.indexOf("\t");
 62  199
                                 if (pos2 != -1 && (pos == -1 || pos > pos2))
 63  6
                                         pos = pos2;
 64  199
                                 if (pos != -1) {
 65  73
                                         literalBuffer.setCharAt(pos, '\0');
 66  
                                 }
 67  
                         }
 68  2776
                         pos = literalBuffer.indexOf("\0");
 69  2776
                         if (pos != -1 && current < maxparamcount - 1) {
 70  355
                                 if (pos != 0)
 71  328
                                         elems.add(new LiteralTag(literalBuffer.substring(0, pos)));
 72  355
                                 literalBuffer.delete(0, pos + 1);
 73  355
                                 result[current++] = new Parameter(elems);
 74  355
                                 elems.clear();
 75  355
                                 if (noCommaCount > 0)
 76  73
                                         noCommaCount--;
 77  
                                 continue; // check for another parameter
 78  
                         }
 79  2421
                         if (rawText.length() == 0)
 80  901
                                 break;
 81  1520
                         pos = rawText.indexOf("\1");
 82  1520
                         if (pos == -1) {
 83  693
                                 literalBuffer.append(rawText);
 84  693
                                 rawText = "";
 85  693
                                 continue;
 86  827
                         } else if (pos > 0) {
 87  339
                                 literalBuffer.append(rawText.substring(0, pos));
 88  339
                                 rawText = rawText.substring(pos);
 89  339
                                 continue;
 90  
                         } else {
 91  488
                                 rawText = rawText.substring(1);
 92  
                         }
 93  488
                         int depth = 1;
 94  3303
                         for (int i = 0; i < rawText.length(); i++) {
 95  3302
                                 if (rawText.charAt(i) == '\1')
 96  303
                                         depth++;
 97  3302
                                 if (rawText.charAt(i) == '\2')
 98  790
                                         depth--;
 99  3302
                                 if (depth == 0) {
 100  487
                                         Tag pe = Tag.parseTag(rawText.substring(0, i));
 101  484
                                         if (pe instanceof LiteralTag) {
 102  306
                                                 literalBuffer.append(((LiteralTag) pe).getString());
 103  
                                         } else {
 104  178
                                                 if (literalBuffer.length() > 0) {
 105  58
                                                         elems.add(new LiteralTag(literalBuffer.substring(0)));
 106  58
                                                         literalBuffer.delete(0, literalBuffer.length());
 107  
                                                 }
 108  178
                                                 elems.add(pe);
 109  
                                         }
 110  484
                                         rawText = rawText.substring(i + 1);
 111  484
                                         break;
 112  
                                 }
 113  
                         }
 114  485
                         if (depth != 0)
 115  1
                                 throw new RuntimeException("Unterminated tag.");
 116  484
                 }
 117  901
                 if (literalBuffer.length() > 0)
 118  694
                         elems.add(new LiteralTag(literalBuffer.toString()));
 119  901
                 if (elems.size() > 0 || current != 0 || minparamcount == 1)
 120  889
                         result[current++] = new Parameter(elems);
 121  901
                 if (current < minparamcount)
 122  1
                         throw new RuntimeException("Invalid number of parameters!");
 123  900
                 return result;
 124  
         }
 125  
 
 126  
         private final Tag[] tags;
 127  
         private final String cachedString;
 128  
         private final String cachedRegex;
 129  
 
 130  
         private Parameter(List<Tag> elems) {
 131  1244
                 this(elems.toArray(new Tag[elems.size()]));
 132  1244
         }
 133  
 
 134  1256
         private Parameter(Tag[] elements) {
 135  1256
                 this.tags = elements;
 136  1256
                 StringBuilder sbRegex = new StringBuilder();
 137  1256
                 StringBuilder sbString = new StringBuilder();
 138  2457
                 for (Tag e : elements) {
 139  1246
                         if (e.isStatic()) {
 140  1201
                                 sbRegex.append(e.getRegex(null));
 141  1201
                                 if (e.isParsingOnly() || sbString == null)
 142  163
                                         sbString = null;
 143  
                                 else
 144  1038
                                         sbString.append(e.getString(null));
 145  
                         } else {
 146  45
                                 sbString = sbRegex = null;
 147  45
                                 break;
 148  
                         }
 149  
                 }
 150  1256
                 cachedRegex = (sbRegex == null) ? null : sbRegex.toString();
 151  1256
                 cachedString = (sbString == null) ? null : sbString.toString();
 152  1256
         }
 153  
 
 154  
         public String getString(ParserState state) {
 155  1612
                 if (cachedString != null)
 156  1452
                         return cachedString;
 157  160
                 StringBuilder sb = new StringBuilder();
 158  452
                 for (Tag e : tags) {
 159  297
                         sb.append(e.getString(state));
 160  
                 }
 161  155
                 return sb.toString();
 162  
         }
 163  
 
 164  
         public String getRegex(ParserState state) {
 165  1262
                 if (cachedRegex != null)
 166  1097
                         return cachedRegex;
 167  165
                 StringBuilder sb = new StringBuilder();
 168  342
                 for (Tag e : tags) {
 169  177
                         sb.append(e.getRegex(state));
 170  
                 }
 171  165
                 return sb.toString();
 172  
         }
 173  
 
 174  
         public boolean isStringStatic() {
 175  121
                 return cachedString != null;
 176  
         }
 177  
 
 178  
         public void applyMatch(ParserState state, Matcher matcher) {
 179  754
                 int idx = 0;
 180  1539
                 for (Tag e : tags) {
 181  785
                         int cnt = e.getUsedGroupCount();
 182  785
                         String[] params = new String[cnt];
 183  1030
                         for (int i = 0; i < params.length; i++) {
 184  245
                                 params[i] = matcher.group(i + idx + 1);
 185  
                         }
 186  785
                         e.applyMatch(state, params);
 187  785
                         idx += cnt;
 188  
                 }
 189  754
                 if (idx != matcher.groupCount())
 190  1
                         throw new RuntimeException("Wrong number of regex groups");
 191  753
         }
 192  
 
 193  
         public static Parameter getLiteralParameter(String literal) {
 194  12
                 return new Parameter(new Tag[] { new LiteralTag(literal) });
 195  
         }
 196  
 }