1
15
16
17 package gate.jape;
18
19 import java.util.*;
20
21 import gate.*;
22 import gate.annotation.AnnotationSetImpl;
23 import gate.util.Out;
24 import gate.util.Strings;
25
26
27
32 public class BasicPatternElement
33 extends PatternElement implements JapeConstants, java.io.Serializable
34 {
35
36 private static final boolean DEBUG = false;
37
38
39 private ArrayList constraints1;
40
41
42 private Constraint[] constraints2;
43
44
45 private HashMap constraintsMap;
46
47
48 private int lastFailurePoint = -1;
49
50
53
55
56 private AnnotationSet matchedAnnots;
57
58
59 public AnnotationSet getMatchedAnnots() { return matchedAnnots; }
60
61
62 public BasicPatternElement() {
63 constraintsMap = new HashMap();
64 constraints1 = new ArrayList();
65 lastFailurePoint = -1;
66 matchedAnnots = new AnnotationSetImpl((Document) null);
68 }
70
73 public Object clone() {
74 BasicPatternElement newPE = (BasicPatternElement) super.clone();
75 newPE.constraintsMap = (HashMap) constraintsMap.clone();
76 newPE.constraints1 = new ArrayList();
77 int consLen = constraints1.size();
78 for(int i = 0; i < consLen; i++)
79 newPE.constraints1.add(
80 ((Constraint) constraints1.get(i)).clone()
81 );
82 return newPE;
85 }
87
90 public void addConstraint(Constraint newConstraint) {
91
94 String annotType = newConstraint.getAnnotType();
95 Constraint existingConstraint = (Constraint) constraintsMap.get(annotType);
96 if(existingConstraint == null) {
97 constraintsMap.put(annotType, newConstraint);
98 constraints1.add(newConstraint);
99 }
100 else {
101 FeatureMap newAttrs = newConstraint.getAttributeSeq();
102 FeatureMap existingAttrs =
103 existingConstraint.getAttributeSeq();
104 existingAttrs.putAll(newAttrs);
105 if(newConstraint.isNegated())
106 existingConstraint.negate();
107 }
108 }
110
111
114 public void finish() {
115 int j=0;
116 constraints2 = new Constraint[constraints1.size()];
117 for(Iterator i=constraints1.iterator(); i.hasNext(); ) {
118 constraints2[j] = (Constraint) i.next();
119 constraints2[j++].finish();
120 }
121 constraints1 = null;
122 }
124
125 public void reset() {
126 super.reset();
127 lastFailurePoint = -1;
128 matchedAnnots = new AnnotationSetImpl((Document) null);
130 }
132
133 public void rollback(int arity) {
134
138 for(int i=0; i<arity; i++) {
139 matchedAnnots.removeAll((AnnotationSet) matchHistory.pop());
140 }
141 }
143
144 public boolean matches (
145 Document doc, int position, MutableInteger newPosition
146 ) {
147 final int startingCacheSize = matchedAnnots.size();
148 AnnotationSet addedAnnots = new AnnotationSetImpl((Document) null);
149
150 int rightmostEnd = -1;
153 int end = doc.getContent().size().intValue();
154 MutableInteger nextAvailable = new MutableInteger();
155 int nextAvailOfFirstConstraint = -1;
156
157 for(int len = constraints2.length, i = 0; i < len; i++) {
158 Constraint constraint = constraints2[i];
159 String annotType = constraint.getAnnotType();
160 JdmAttribute[] constraintAttrs = constraint.getAttributeArray();
161 MutableBoolean moreToTry = new MutableBoolean();
162
163 if(DEBUG) {
164 Out.println(
165 "BPE.matches: selectAnn on lFP = " + lastFailurePoint +
166 "; max(pos,lfp) = " + Math.max(position, lastFailurePoint) +
167 "; annotType = " + annotType + "; attrs = " +
168 constraintAttrs.toString() + Strings.getNl()
169 );
170 for(int j=0; j<constraintAttrs.length; j++)
171 Out.println(
172 "BPE.matches attr: " + constraintAttrs[j].toString()
173 );
174 }
175 FeatureMap features = Factory.newFeatureMap();
176 for(int j = constraintAttrs.length - 1; j >= 0; j--)
177 features.put(constraintAttrs[j].getName(), constraintAttrs[j].getValue());
178 AnnotationSet match = doc.getAnnotations().get(
179 annotType,
182 features,
183 new Long(Math.max(position, lastFailurePoint))
186 );
187 if(DEBUG) Out.println(
188 "BPE.matches: selectAnn returned " + match + ".... moreToTry = " +
189 moreToTry.value + " nextAvailable = " + nextAvailable.value
190 );
191
192 if(nextAvailOfFirstConstraint == -1)
194 nextAvailOfFirstConstraint = nextAvailable.value;
195
196 if(! moreToTry.value) {
199 if(match != null)
200 throw(new RuntimeException("BPE: no more annots but found one!"));
201 lastFailurePoint = end;
202 newPosition.value = end;
203 }
204
205 int matchEnd = -1;
212 if(match != null) {
213 matchEnd = match.lastNode().getOffset().intValue();
214 if(rightmostEnd == -1) { rightmostEnd = matchEnd;
216 }
217 else if(match.firstNode().getOffset().intValue() >= rightmostEnd) {
218 lastFailurePoint = matchEnd;
220 match = null;
221 }
222 else { if(rightmostEnd < matchEnd)
224 rightmostEnd = matchEnd;
225 }
226 }
228 if(constraint.isNegated()) {
230 if(match == null) {
231 continue;
235 }
236 else {
237 lastFailurePoint = matchEnd;
242 match = null;
243 }
244 }
246 if(match == null) {
250 newPosition.value = Math.max(position + 1, nextAvailOfFirstConstraint);
251 lastFailurePoint = nextAvailable.value;
252
253 matchedAnnots.removeAll(addedAnnots);
259
260 return false;
265 } else {
266
267 matchedAnnots.addAll(match);
269 addedAnnots.addAll(match);
270 newPosition.value = Math.max(newPosition.value, matchEnd);
271 }
272
273 }
275 matchHistory.push(addedAnnots);
277
278 if(newPosition.value == position)
281 newPosition.value++;
282
283 return true;
284 }
286
287 public String toString() {
288 StringBuffer result = new StringBuffer("{");
289 Constraint[] constraints = getConstraints();
290 for(int i = 0; i<constraints.length; i++){
291 result.append(constraints[i].shortDesc() + ",");
292 }
293 result.setCharAt(result.length() -1, '}');
294 return result.toString();
295 }
296
297
298 public String toString(String pad) {
299 String newline = Strings.getNl();
300 String newPad = Strings.addPadding(pad, INDENT_PADDING);
301
302 StringBuffer buf = new StringBuffer(pad +
303 "BPE: lastFailurePoint(" + lastFailurePoint + "); constraints("
304 );
305
306 if(constraints1 != null) {
308 for(int len = constraints1.size(), i = 0; i < len; i++)
309 buf.append(
310 newline + ((Constraint) constraints1.get(i)).toString(newPad)
311 );
312 } else {
313 for(int len = constraints2.length, i = 0; i < len; i++)
314 buf.append(newline + constraints2[i].toString(newPad));
315 }
316
317 buf.append(
319 newline + pad + "matchedAnnots: " + matchedAnnots +
320 newline + pad + ") BPE."
321 );
322
323 return buf.toString();
324 }
326
329 public String shortDesc() {
330 String res = "";
331 if(constraints1 != null) {
332 for(int len = constraints1.size(), i = 0; i < len; i++)
333 res += ((Constraint) constraints1.get(i)).toString();
334 } else {
335 for(int len = constraints2.length, i = 0; i < len; i++)
336 res += constraints2[i].shortDesc();
337 }
338 return res;
339 }
340
341 public Constraint[] getConstraints(){
342 return constraints2;
343 }
344 }
346