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