1 28 29 package com.caucho.relaxng.program; 30 31 import com.caucho.relaxng.RelaxException; 32 import com.caucho.util.CharBuffer; 33 import com.caucho.util.L10N; 34 import com.caucho.xml.QName; 35 36 import java.util.ArrayList ; 37 import java.util.HashSet ; 38 import java.util.Iterator ; 39 40 43 public class InterleaveItem extends Item { 44 protected final static L10N L = new L10N(InterleaveItem.class); 45 46 private ArrayList <Item> _items = new ArrayList <Item>(); 47 48 public InterleaveItem() 49 { 50 } 51 52 public static Item create(Item left, Item right) 53 { 54 InterleaveItem item = new InterleaveItem(); 55 56 item.addItem(left); 57 item.addItem(right); 58 59 return item.getMin(); 60 } 61 62 public void addItem(Item item) 63 { 64 if (item == null) 65 return; 66 else if (item instanceof EmptyItem) { 67 return; 68 } 69 else if (item instanceof InterleaveItem) { 70 InterleaveItem interleave = (InterleaveItem) item; 71 72 for (int i = 0; i < interleave._items.size(); i++) 73 addItem(interleave._items.get(i)); 74 75 return; 76 } 77 78 113 114 _items.add(item); 115 } 116 117 public Item getMin() 118 { 119 if (_items.size() == 0) 120 return null; 121 else if (_items.size() == 1) 122 return _items.get(0); 123 else 124 return this; 125 } 126 127 130 public void firstSet(HashSet <QName> set) 131 { 132 for (int i = 0; i < _items.size(); i++) 133 _items.get(i).firstSet(set); 134 } 135 136 139 public void requiredFirstSet(HashSet <QName> set) 140 { 141 if (allowEmpty()) 142 return; 143 144 for (int i = 0; i < _items.size(); i++) 145 _items.get(i).requiredFirstSet(set); 146 } 147 148 151 public boolean allowEmpty() 152 { 153 for (int i = 0; i < _items.size(); i++) { 154 if (! _items.get(i).allowEmpty()) 155 return false; 156 } 157 158 return true; 159 } 160 161 164 public Item interleaveContinuation(Item cont) 165 { 166 InterleaveItem item = new InterleaveItem(); 167 168 for (int i = 0; i < _items.size(); i++) 169 item.addItem(_items.get(i).interleaveContinuation(cont)); 170 171 return item.getMin(); 172 } 173 174 177 public Item inElementContinuation(Item cont) 178 { 179 InterleaveItem item = new InterleaveItem(); 180 181 for (int i = 0; i < _items.size(); i++) 182 item.addItem(_items.get(i).inElementContinuation(cont)); 183 184 return item.getMin(); 185 } 186 187 190 public Item groupContinuation(Item cont) 191 { 192 InterleaveItem item = new InterleaveItem(); 193 194 for (int i = 0; i < _items.size(); i++) 195 item.addItem(_items.get(i).groupContinuation(cont)); 196 197 return item.getMin(); 198 } 199 200 203 public Iterator <Item> getItemsIterator() 204 { 205 if ( _items.size() == 0 ) 206 return emptyItemIterator(); 207 else 208 return _items.iterator(); 209 } 210 211 212 215 public Item startElement(QName name) 216 throws RelaxException 217 { 218 Item result = null; 219 ChoiceItem choice = null; 220 221 for (int i = 0; i < _items.size(); i++) { 222 Item item = _items.get(i); 223 224 Item nextItem = item.startElement(name); 225 226 if (nextItem == null) 227 continue; 228 229 Item resultItem; 230 231 if (nextItem == item) 232 resultItem = this; 233 else { 234 InterleaveItem rest = new InterleaveItem(); 235 for (int j = 0; j < _items.size(); j++) { 236 if (i != j) 237 rest.addItem(_items.get(j)); 238 } 239 240 resultItem = nextItem.interleaveContinuation(rest); 241 } 242 243 if (result == null) 244 result = resultItem; 245 else { 246 if (choice == null) { 247 choice = new ChoiceItem(); 248 choice.addItem(result); 249 } 250 choice.addItem(resultItem); 251 } 252 } 253 254 if (choice != null) 255 return choice.getMin(); 256 else 257 return result; 258 } 259 260 268 public boolean allowAttribute(QName name, String value) 269 throws RelaxException 270 { 271 for (int i = _items.size() - 1; i >= 0; i--) 272 if (_items.get(i).allowAttribute(name, value)) 273 return true; 274 275 return false; 276 } 277 278 281 public void attributeSet(HashSet <QName> set) 282 { 283 for (int i = 0; i < _items.size(); i++) 284 _items.get(i).attributeSet(set); 285 } 286 287 295 public Item setAttribute(QName name, String value) 296 throws RelaxException 297 { 298 if (! allowAttribute(name, value)) 299 return this; 300 301 InterleaveItem interleave = new InterleaveItem(); 302 303 for (int i = _items.size() - 1; i >= 0; i--) { 304 Item next = _items.get(i).setAttribute(name, value); 305 306 if (next != null) 307 interleave.addItem(next); 308 } 309 310 return interleave.getMin(); 311 } 312 313 316 public Item attributeEnd() 317 { 318 InterleaveItem interleave = new InterleaveItem(); 319 320 for (int i = _items.size() - 1; i >= 0; i--) { 321 Item next = _items.get(i).attributeEnd(); 322 323 if (next == null) 324 return null; 325 326 interleave.addItem(next); 327 } 328 329 if (interleave.equals(this)) 330 return this; 331 else 332 return interleave.getMin(); 333 } 334 335 338 public Item text(String string) 339 throws RelaxException 340 { 341 Item result = null; 342 ChoiceItem choice = null; 343 344 for (int i = 0; i < _items.size(); i++) { 345 Item item = _items.get(i); 346 347 Item nextItem = item.text(string); 348 349 if (nextItem == null) 350 continue; 351 352 Item resultItem; 353 354 if (nextItem == item) 355 resultItem = this; 356 else { 357 InterleaveItem rest = new InterleaveItem(); 358 for (int j = 0; j < _items.size(); j++) { 359 if (i != j) 360 rest.addItem(_items.get(j)); 361 } 362 363 resultItem = nextItem.interleaveContinuation(rest); 364 } 365 366 if (result == null) 367 result = resultItem; 368 else { 369 if (choice == null) { 370 choice = new ChoiceItem(); 371 choice.addItem(result); 372 } 373 choice.addItem(resultItem); 374 } 375 } 376 377 if (choice != null) 378 return choice.getMin(); 379 else 380 return result; 381 } 382 383 392 public boolean allowsElement(QName name) 393 { 394 for (int i = 0; i < _items.size(); i++) { 395 Item subItem = _items.get(i); 396 397 if (subItem.allowsElement(name)) 398 return true; 399 } 400 401 return false; 402 } 403 404 407 public String toSyntaxDescription(int depth) 408 { 409 if (_items.size() == 1) 410 return _items.get(0).toSyntaxDescription(depth); 411 412 CharBuffer cb = CharBuffer.allocate(); 413 414 cb.append("("); 415 416 boolean isSimple = true; 417 for (int i = 0; i < _items.size(); i++) { 418 Item item = _items.get(i); 419 420 if (! item.isSimpleSyntax()) 421 isSimple = false; 422 423 if (i == 0) { 424 if (! isSimple) 425 cb.append(" "); 426 } 427 else if (isSimple) { 428 cb.append(" & "); 429 } 430 else { 431 addSyntaxNewline(cb, depth); 432 cb.append("& "); 433 } 434 435 cb.append(item.toSyntaxDescription(depth + 2)); 436 } 437 438 cb.append(')'); 439 440 return cb.close(); 441 } 442 443 446 public int hashCode() 447 { 448 int hash = 37; 449 450 for (int i = 0; i < _items.size(); i++) 451 hash += _items.get(i).hashCode(); 452 453 return hash; 454 } 455 456 459 public boolean equals(Object o) 460 { 461 if (this == o) 462 return true; 463 464 if (! (o instanceof InterleaveItem)) 465 return false; 466 467 InterleaveItem interleave = (InterleaveItem) o; 468 469 return isSubset(interleave) && interleave.isSubset(this); 470 } 471 472 private boolean isSubset(InterleaveItem item) 473 { 474 if (_items.size() != item._items.size()) 475 return false; 476 477 for (int i = 0; i < _items.size(); i++) { 478 Item subItem = _items.get(i); 479 480 if (! item._items.contains(subItem)) 481 return false; 482 } 483 484 return true; 485 } 486 } 487 488 | Popular Tags |