1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.xerces.impl.xpath.regex; 19 20 import java.text.CharacterIterator; 21 22 /** 23 * An instance of this class has ranges captured in matching. 24 * 25 * @xerces.internal 26 * 27 * @see RegularExpression#matches(char[], int, int, Match) 28 * @see RegularExpression#matches(char[], Match) 29 * @see RegularExpression#matches(java.text.CharacterIterator, Match) 30 * @see RegularExpression#matches(java.lang.String, int, int, Match) 31 * @see RegularExpression#matches(java.lang.String, Match) 32 * @author TAMURA Kent <kent@trl.ibm.co.jp> 33 * @version $Id: Match.java 446721 2006-09-15 20:35:34Z mrglavas $ 34 */ 35 public class Match implements Cloneable { 36 int[] beginpos = null; 37 int[] endpos = null; 38 int nofgroups = 0; 39 40 CharacterIterator ciSource = null; 41 String strSource = null; 42 char[] charSource = null; 43 44 /** 45 * Creates an instance. 46 */ 47 public Match() { 48 } 49 50 /** 51 * 52 */ 53 public synchronized Object clone() { 54 Match ma = new Match(); 55 if (this.nofgroups > 0) { 56 ma.setNumberOfGroups(this.nofgroups); 57 if (this.ciSource != null) ma.setSource(this.ciSource); 58 if (this.strSource != null) ma.setSource(this.strSource); 59 for (int i = 0; i < this.nofgroups; i ++) { 60 ma.setBeginning(i, this.getBeginning(i)); 61 ma.setEnd(i, this.getEnd(i)); 62 } 63 } 64 return ma; 65 } 66 67 /** 68 * 69 */ 70 protected void setNumberOfGroups(int n) { 71 int oldn = this.nofgroups; 72 this.nofgroups = n; 73 if (oldn <= 0 74 || oldn < n || n*2 < oldn) { 75 this.beginpos = new int[n]; 76 this.endpos = new int[n]; 77 } 78 for (int i = 0; i < n; i ++) { 79 this.beginpos[i] = -1; 80 this.endpos[i] = -1; 81 } 82 } 83 84 /** 85 * 86 */ 87 protected void setSource(CharacterIterator ci) { 88 this.ciSource = ci; 89 this.strSource = null; 90 this.charSource = null; 91 } 92 /** 93 * 94 */ 95 protected void setSource(String str) { 96 this.ciSource = null; 97 this.strSource = str; 98 this.charSource = null; 99 } 100 /** 101 * 102 */ 103 protected void setSource(char[] chars) { 104 this.ciSource = null; 105 this.strSource = null; 106 this.charSource = chars; 107 } 108 109 /** 110 * 111 */ 112 protected void setBeginning(int index, int v) { 113 this.beginpos[index] = v; 114 } 115 116 /** 117 * 118 */ 119 protected void setEnd(int index, int v) { 120 this.endpos[index] = v; 121 } 122 123 /** 124 * Return the number of regular expression groups. 125 * This method returns 1 when the regular expression has no capturing-parenthesis. 126 */ 127 public int getNumberOfGroups() { 128 if (this.nofgroups <= 0) 129 throw new IllegalStateException("A result is not set."); 130 return this.nofgroups; 131 } 132 133 /** 134 * Return a start position in the target text matched to specified regular expression group. 135 * 136 * @param index Less than <code>getNumberOfGroups()</code>. 137 */ 138 public int getBeginning(int index) { 139 if (this.beginpos == null) 140 throw new IllegalStateException("A result is not set."); 141 if (index < 0 || this.nofgroups <= index) 142 throw new IllegalArgumentException("The parameter must be less than " 143 +this.nofgroups+": "+index); 144 return this.beginpos[index]; 145 } 146 147 /** 148 * Return an end position in the target text matched to specified regular expression group. 149 * 150 * @param index Less than <code>getNumberOfGroups()</code>. 151 */ 152 public int getEnd(int index) { 153 if (this.endpos == null) 154 throw new IllegalStateException("A result is not set."); 155 if (index < 0 || this.nofgroups <= index) 156 throw new IllegalArgumentException("The parameter must be less than " 157 +this.nofgroups+": "+index); 158 return this.endpos[index]; 159 } 160 161 /** 162 * Return an substring of the target text matched to specified regular expression group. 163 * 164 * @param index Less than <code>getNumberOfGroups()</code>. 165 */ 166 public String getCapturedText(int index) { 167 if (this.beginpos == null) 168 throw new IllegalStateException("match() has never been called."); 169 if (index < 0 || this.nofgroups <= index) 170 throw new IllegalArgumentException("The parameter must be less than " 171 +this.nofgroups+": "+index); 172 String ret; 173 int begin = this.beginpos[index], end = this.endpos[index]; 174 if (begin < 0 || end < 0) return null; 175 if (this.ciSource != null) { 176 ret = REUtil.substring(this.ciSource, begin, end); 177 } else if (this.strSource != null) { 178 ret = this.strSource.substring(begin, end); 179 } else { 180 ret = new String(this.charSource, begin, end-begin); 181 } 182 return ret; 183 } 184 }