Coverage Report - org.seasar.cubby.routing.impl.PathTemplateParserImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
PathTemplateParserImpl
96%
51/53
93%
29/31
23
PathTemplateParserImpl$1
100%
1/1
N/A
23
PathTemplateParserImpl$State
100%
2/2
N/A
23
 
 1  
 /*
 2  
  * Copyright 2004-2010 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 
 17  
 package org.seasar.cubby.routing.impl;
 18  
 
 19  
 import static org.seasar.cubby.internal.util.LogMessages.format;
 20  
 
 21  
 import org.seasar.cubby.routing.PathTemplateException;
 22  
 import org.seasar.cubby.routing.PathTemplateParser;
 23  
 
 24  
 /**
 25  
  * パステンプレートのパーサーの実装です。
 26  
  * 
 27  
  * @author baba
 28  
  */
 29  66
 public class PathTemplateParserImpl implements PathTemplateParser {
 30  
 
 31  
         /** プレースホルダの開始文字。 */
 32  
         private static final char OPEN_PLACE_HOLDER = '{';
 33  
 
 34  
         /** プレースホルダの終了文字。 */
 35  
         private static final char CLOSE_PLACE_HOLDER = '}';
 36  
 
 37  
         /** プレースホルダ中のパラメータ名と正規表現の区切り文字。 */
 38  
         private static final char PLACE_HOLDER_SEPARATOR = ',';
 39  
 
 40  
         /** 正規表現のエスケープ文字。 */
 41  
         private static final char REGEXP_ESCAPE = '\\';
 42  
 
 43  
         /**
 44  
          * パース中の状態。
 45  
          * 
 46  
          * @author baba
 47  
          */
 48  66
         private enum State {
 49  1
                 NORMAL, PARAM_NAME, PARAM_REGEX, PARAM_REGEX_ESCAPE;
 50  
         }
 51  
 
 52  
         /**
 53  
          * {@inheritDoc}
 54  
          */
 55  
         public String parse(final String template, final Handler handler) {
 56  723
                 final StringBuilder pathRegex = new StringBuilder(100);
 57  723
                 final StringBuilder paramName = new StringBuilder(10);
 58  723
                 final StringBuilder paramRegex = new StringBuilder(10);
 59  
 
 60  723
                 State state = State.NORMAL;
 61  723
                 int braceDepth = 0;
 62  
 
 63  11617
                 for (int i = 0; i < template.length(); i++) {
 64  10898
                         final char c = template.charAt(i);
 65  10898
                         switch (state) {
 66  
                         case NORMAL: {
 67  7579
                                 if (c == OPEN_PLACE_HOLDER) {
 68  487
                                         state = State.PARAM_NAME;
 69  
                                 } else {
 70  7092
                                         pathRegex.append(c);
 71  
                                 }
 72  7092
                                 break;
 73  
                         }
 74  
                         case PARAM_NAME: {
 75  2335
                                 if (c == CLOSE_PLACE_HOLDER) {
 76  338
                                         if (paramName.length() == 0) {
 77  1
                                                 throw new PathTemplateException(format("ECUB0108",
 78  
                                                                 template, i));
 79  
                                         }
 80  337
                                         final String replacement = handler.handle(paramName
 81  
                                                         .toString(), DEFAULT_URI_PARAMETER_REGEX);
 82  337
                                         pathRegex.append(replacement);
 83  
 
 84  337
                                         paramName.setLength(0);
 85  337
                                         state = State.NORMAL;
 86  337
                                 } else if (c == PLACE_HOLDER_SEPARATOR) {
 87  147
                                         state = State.PARAM_REGEX;
 88  
                                 } else {
 89  1850
                                         paramName.append(c);
 90  
                                 }
 91  1850
                                 break;
 92  
                         }
 93  
                         case PARAM_REGEX: {
 94  980
                                 if (c == REGEXP_ESCAPE) {
 95  4
                                         paramRegex.append(c);
 96  4
                                         state = State.PARAM_REGEX_ESCAPE;
 97  976
                                 } else if (c == CLOSE_PLACE_HOLDER && braceDepth == 0) {
 98  145
                                         if (paramName.length() == 0) {
 99  0
                                                 throw new PathTemplateException(format("ECUB0108",
 100  
                                                                 template, i));
 101  
                                         }
 102  145
                                         if (paramRegex.length() == 0) {
 103  1
                                                 throw new PathTemplateException(format("ECUB0109",
 104  
                                                                 template, i));
 105  
                                         }
 106  144
                                         final String replacement = handler.handle(paramName
 107  
                                                         .toString(), paramRegex.toString());
 108  142
                                         pathRegex.append(replacement);
 109  
 
 110  142
                                         paramName.setLength(0);
 111  142
                                         paramRegex.setLength(0);
 112  142
                                         braceDepth = 0;
 113  142
                                         state = State.NORMAL;
 114  142
                                 } else {
 115  831
                                         if (c == OPEN_PLACE_HOLDER) {
 116  1
                                                 braceDepth++;
 117  830
                                         } else if (c == CLOSE_PLACE_HOLDER) {
 118  1
                                                 braceDepth--;
 119  
                                         }
 120  831
                                         paramRegex.append(c);
 121  
                                 }
 122  831
                                 break;
 123  
                         }
 124  
                         case PARAM_REGEX_ESCAPE: {
 125  4
                                 paramRegex.append(c);
 126  4
                                 state = State.PARAM_REGEX;
 127  4
                                 break;
 128  
                         }
 129  
                         default:
 130  0
                                 throw new IllegalStateException();
 131  
                         }
 132  
                 }
 133  719
                 if (state != State.NORMAL) {
 134  4
                         throw new PathTemplateException(format("ECUB0107", template));
 135  
                 }
 136  715
                 return pathRegex.toString();
 137  
         }
 138  
 
 139  
 }