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
115 public boolean isMultiType() {
116 return constraints2 != null ? constraints2.length > 1 :
117 constraints1 != null ? constraints1.size() > 1 :
118 false;
119 }
120
121
124 public void finish() {
125 int j=0;
126 constraints2 = new Constraint[constraints1.size()];
127 for(Iterator i=constraints1.iterator(); i.hasNext(); ) {
128 constraints2[j] = (Constraint) i.next();
129 constraints2[j++].finish();
130 }
131 constraints1 = null;
132 }
134
135 public void reset() {
136 super.reset();
137 lastFailurePoint = -1;
138 matchedAnnots = new AnnotationSetImpl((Document) null);
140 }
142
143 public void rollback(int arity) {
144
148 for(int i=0; i<arity; i++) {
149 matchedAnnots.removeAll((AnnotationSet) matchHistory.pop());
150 }
151 }
153
154 public boolean matches (
155 Document doc, int position, MutableInteger newPosition
156 ) {
157 final int startingCacheSize = matchedAnnots.size();
158 AnnotationSet addedAnnots = new AnnotationSetImpl((Document) null);
159
160 int rightmostEnd = -1;
163 int end = doc.getContent().size().intValue();
164 MutableInteger nextAvailable = new MutableInteger();
165 int nextAvailOfFirstConstraint = -1;
166
167 for(int len = constraints2.length, i = 0; i < len; i++) {
168 Constraint constraint = constraints2[i];
169 String annotType = constraint.getAnnotType();
170 JdmAttribute[] constraintAttrs = constraint.getAttributeArray();
171 MutableBoolean moreToTry = new MutableBoolean();
172
173 if(DEBUG) {
174 Out.println(
175 "BPE.matches: selectAnn on lFP = " + lastFailurePoint +
176 "; max(pos,lfp) = " + Math.max(position, lastFailurePoint) +
177 "; annotType = " + annotType + "; attrs = " +
178 constraintAttrs.toString() + Strings.getNl()
179 );
180 for(int j=0; j<constraintAttrs.length; j++)
181 Out.println(
182 "BPE.matches attr: " + constraintAttrs[j].toString()
183 );
184 }
185 FeatureMap features = Factory.newFeatureMap();
186 for(int j = constraintAttrs.length - 1; j >= 0; j--)
187 features.put(constraintAttrs[j].getName(), constraintAttrs[j].getValue());
188 AnnotationSet match = doc.getAnnotations().get(
189 annotType,
192 features,
193 new Long(Math.max(position, lastFailurePoint))
196 );
197 if(DEBUG) Out.println(
198 "BPE.matches: selectAnn returned " + match + ".... moreToTry = " +
199 moreToTry.value + " nextAvailable = " + nextAvailable.value
200 );
201
202 if(nextAvailOfFirstConstraint == -1)
204 nextAvailOfFirstConstraint = nextAvailable.value;
205
206 if(! moreToTry.value) {
209 if(match != null)
210 throw(new RuntimeException("BPE: no more annots but found one!"));
211 lastFailurePoint = end;
212 newPosition.value = end;
213 }
214
215 int matchEnd = -1;
222 if(match != null) {
223 matchEnd = match.lastNode().getOffset().intValue();
224 if(rightmostEnd == -1) { rightmostEnd = matchEnd;
226 }
227 else if(match.firstNode().getOffset().intValue() >= rightmostEnd) {
228 lastFailurePoint = matchEnd;
230 match = null;
231 }
232 else { if(rightmostEnd < matchEnd)
234 rightmostEnd = matchEnd;
235 }
236 }
238 if(constraint.isNegated()) {
240 if(match == null) {
241 continue;
245 }
246 else {
247 lastFailurePoint = matchEnd;
252 match = null;
253 }
254 }
256 if(match == null) {
260 newPosition.value = Math.max(position + 1, nextAvailOfFirstConstraint);
261 lastFailurePoint = nextAvailable.value;
262
263 matchedAnnots.removeAll(addedAnnots);
269
270 return false;
275 } else {
276
277 matchedAnnots.addAll(match);
279 addedAnnots.addAll(match);
280 newPosition.value = Math.max(newPosition.value, matchEnd);
281 }
282
283 }
285 matchHistory.push(addedAnnots);
287
288 if(newPosition.value == position)
291 newPosition.value++;
292
293 return true;
294 }
296
297 public String toString() {
298 StringBuffer result = new StringBuffer("{");
299 Constraint[] constraints = getConstraints();
300 for(int i = 0; i<constraints.length; i++){
301 result.append(constraints[i].shortDesc() + ",");
302 }
303 result.setCharAt(result.length() -1, '}');
304 return result.toString();
305 }
306
307
308 public String toString(String pad) {
309 String newline = Strings.getNl();
310 String newPad = Strings.addPadding(pad, INDENT_PADDING);
311
312 StringBuffer buf = new StringBuffer(pad +
313 "BPE: lastFailurePoint(" + lastFailurePoint + "); constraints("
314 );
315
316 if(constraints1 != null) {
318 for(int len = constraints1.size(), i = 0; i < len; i++)
319 buf.append(
320 newline + ((Constraint) constraints1.get(i)).toString(newPad)
321 );
322 } else {
323 for(int len = constraints2.length, i = 0; i < len; i++)
324 buf.append(newline + constraints2[i].toString(newPad));
325 }
326
327 buf.append(
329 newline + pad + "matchedAnnots: " + matchedAnnots +
330 newline + pad + ") BPE."
331 );
332
333 return buf.toString();
334 }
336
339 public String shortDesc() {
340 String res = "";
341 if(constraints1 != null) {
342 for(int len = constraints1.size(), i = 0; i < len; i++)
343 res += ((Constraint) constraints1.get(i)).toString();
344 } else {
345 for(int len = constraints2.length, i = 0; i < len; i++)
346 res += constraints2[i].shortDesc();
347 }
348 return res;
349 }
350
351 public Constraint[] getConstraints(){
352 return constraints2;
353 }
354 }
356