001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.util.parse.metapattern.parsers; 018 019import java.util.regex.Matcher; 020 021import org.apache.wicket.util.parse.metapattern.MetaPattern; 022 023 024/** 025 * Base class for various MetaPattern based parsers. 026 * 027 * @author Jonathan Locke 028 */ 029public abstract class MetaPatternParser 030{ 031 /** The input to parse */ 032 private final CharSequence input; 033 034 /** The length of the input; no. of characters */ 035 private final int length; 036 037 /** 038 * The position (index) behind the last pattern group matched while advancing from one pattern 039 * group to the next one. 040 */ 041 private int pos; 042 043 /** The object maintaining all the regex match details */ 044 private Matcher matcher; 045 046 /** 047 * Construct the parser. You must call 048 * 049 * @see #advance(MetaPattern) to initialize the matcher with the pattern. 050 * @param input 051 * to parse 052 */ 053 public MetaPatternParser(final CharSequence input) 054 { 055 this.input = input; 056 length = input.length(); 057 } 058 059 /** 060 * Construct the parser and initialize the matcher with the pattern given. 061 * 062 * @param pattern 063 * Meta pattern 064 * @param input 065 * Input to parse 066 */ 067 public MetaPatternParser(final MetaPattern pattern, final CharSequence input) 068 { 069 this(input); 070 setPattern(pattern); 071 } 072 073 /** 074 * @param pattern 075 * Pattern 076 */ 077 public void setPattern(final MetaPattern pattern) 078 { 079 matcher = pattern.matcher(input); 080 } 081 082 /** 083 * Advance parsing to the next element. The internal cursor will be moved to end of the string 084 * matched. 085 * 086 * @param pattern 087 * Meta pattern 088 * @return True if found, false otherwise 089 */ 090 protected final boolean advance(final MetaPattern pattern) 091 { 092 // get the remaining part of the input 093 final CharSequence s = input.subSequence(pos, length); 094 095 // does the pattern match? 096 matcher = pattern.matcher(s); 097 if (matcher.lookingAt()) 098 { 099 // Yes, it does. Move the cursor to the end of the 100 // char sequence matched. 101 pos += matcher.end(); 102 103 // Found the pattern 104 return true; 105 } 106 107 // Did not find the pattern. 108 return false; 109 } 110 111 /** 112 * Whether the matcher matches the pattern. 113 * 114 * @return whether the matcher matches 115 */ 116 public boolean matches() 117 { 118 return matcher.matches(); 119 } 120 121 /** 122 * Gets the matcher. 123 * 124 * @return the matcher 125 */ 126 public final Matcher matcher() 127 { 128 return matcher; 129 } 130 131 /** 132 * Whether the internal cursor has advanced to the end of the input. 133 * 134 * @return whether the input is parsed 135 */ 136 public final boolean atEnd() 137 { 138 return pos == length; 139 } 140}