1 57 58 package com.sun.org.apache.xerces.internal.impl.xs.models; 59 60 import com.sun.org.apache.xerces.internal.xni.QName; 61 import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; 62 import com.sun.org.apache.xerces.internal.impl.dtd.models.CMStateSet; 63 import com.sun.org.apache.xerces.internal.impl.xs.SubstitutionGroupHandler; 64 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl; 65 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl; 66 import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl; 67 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl; 68 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException; 69 import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints; 70 71 import java.util.Vector ; 72 73 82 public class XSDFACM 83 implements XSCMValidator { 84 85 private static final boolean DEBUG = false; 89 90 92 94 95 private static final boolean DEBUG_VALIDATE_CONTENT = false; 96 97 101 108 private Object fElemMap[] = null; 109 110 114 private int fElemMapType[] = null; 115 116 119 private int fElemMapId[] = null; 120 121 122 private int fElemMapSize = 0; 123 124 129 private boolean fFinalStateFlags[] = null; 130 131 136 private CMStateSet fFollowList[] = null; 137 138 144 private CMNode fHeadNode = null; 145 146 150 private int fLeafCount = 0; 151 152 156 private XSCMLeaf fLeafList[] = null; 157 158 159 private int fLeafListType[] = null; 160 161 173 private int fTransTable[][] = null; 174 175 179 private int fTransTableSize = 0; 180 181 183 187 196 197 public XSDFACM(CMNode syntaxTree, int leafCount) { 198 199 fLeafCount = leafCount; 201 202 208 218 if(DEBUG_VALIDATE_CONTENT) { 219 XSDFACM.time -= System.currentTimeMillis(); 220 } 221 222 buildDFA(syntaxTree); 223 224 if(DEBUG_VALIDATE_CONTENT) { 225 XSDFACM.time += System.currentTimeMillis(); 226 System.out.println("DFA build: " + XSDFACM.time + "ms"); 227 } 228 } 229 230 private static long time = 0; 231 232 236 243 public boolean isFinalState (int state) { 244 return (state < 0)? false : 245 fFinalStateFlags[state]; 246 } 247 248 262 public Object oneTransition(QName curElem, int[] state, SubstitutionGroupHandler subGroupHandler) { 263 int curState = state[0]; 264 265 if(curState == XSCMValidator.FIRST_ERROR || curState == XSCMValidator.SUBSEQUENT_ERROR) { 266 if(curState == XSCMValidator.FIRST_ERROR) 269 state[0] = XSCMValidator.SUBSEQUENT_ERROR; 270 271 return findMatchingDecl(curElem, subGroupHandler); 272 } 273 274 int nextState = 0; 275 int elemIndex = 0; 276 Object matchingDecl = null; 277 278 for (; elemIndex < fElemMapSize; elemIndex++) { 279 nextState = fTransTable[curState][elemIndex]; 280 if (nextState == -1) 281 continue; 282 int type = fElemMapType[elemIndex] ; 283 if (type == XSParticleDecl.PARTICLE_ELEMENT) { 284 matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]); 285 if (matchingDecl != null) { 286 break; 287 } 288 } 289 else if (type == XSParticleDecl.PARTICLE_WILDCARD) { 290 if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) { 291 matchingDecl = fElemMap[elemIndex]; 292 break; 293 } 294 } 295 } 296 297 if (elemIndex == fElemMapSize) { 300 state[1] = state[0]; 301 state[0] = XSCMValidator.FIRST_ERROR; 302 return findMatchingDecl(curElem, subGroupHandler); 303 } 304 305 state[0] = nextState; 306 return matchingDecl; 307 } 309 Object findMatchingDecl(QName curElem, SubstitutionGroupHandler subGroupHandler) { 310 Object matchingDecl = null; 311 312 for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { 313 int type = fElemMapType[elemIndex] ; 314 if (type == XSParticleDecl.PARTICLE_ELEMENT) { 315 matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]); 316 if (matchingDecl != null) { 317 return matchingDecl; 318 } 319 } 320 else if (type == XSParticleDecl.PARTICLE_WILDCARD) { 321 if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) 322 return fElemMap[elemIndex]; 323 } 324 } 325 326 return null; 327 } 328 329 public int[] startContentModel() { 331 int[] val = new int[2]; 332 val[0] = 0; 333 return val; 334 } 336 public boolean endContentModel(int[] state) { 338 return fFinalStateFlags[state[0]]; 339 } 341 344 348 355 private void buildDFA(CMNode syntaxTree) { 356 385 396 397 int EOCPos = fLeafCount; 405 XSCMLeaf nodeEOC = new XSCMLeaf(XSParticleDecl.PARTICLE_ELEMENT, null, -1, fLeafCount++); 406 fHeadNode = new XSCMBinOp( 407 XSModelGroupImpl.MODELGROUP_SEQUENCE, 408 syntaxTree, 409 nodeEOC 410 ); 411 412 fLeafList = new XSCMLeaf[fLeafCount]; 427 fLeafListType = new int[fLeafCount]; 428 postTreeBuildInit(fHeadNode); 429 430 fFollowList = new CMStateSet[fLeafCount]; 436 for (int index = 0; index < fLeafCount; index++) 437 fFollowList[index] = new CMStateSet(fLeafCount); 438 calcFollowList(fHeadNode); 439 fElemMap = new Object [fLeafCount]; 451 fElemMapType = new int[fLeafCount]; 452 fElemMapId = new int[fLeafCount]; 453 fElemMapSize = 0; 454 for (int outIndex = 0; outIndex < fLeafCount; outIndex++) { 455 fElemMap[outIndex] = null; 458 459 int inIndex = 0; 460 final int id = fLeafList[outIndex].getParticleId(); 461 for (; inIndex < fElemMapSize; inIndex++) { 462 if (id == fElemMapId[inIndex]) 463 break; 464 } 465 466 if (inIndex == fElemMapSize) { 468 fElemMap[fElemMapSize] = fLeafList[outIndex].getLeaf(); 469 fElemMapType[fElemMapSize] = fLeafListType[outIndex]; 470 fElemMapId[fElemMapSize] = id; 471 fElemMapSize++; 472 } 473 } 474 475 if (DEBUG) { 478 if (fElemMapId[fElemMapSize-1] != -1) 479 System.err.println("interal error in DFA: last element is not EOC."); 480 } 481 fElemMapSize--; 482 483 488 489 int[] fLeafSorter = new int[fLeafCount + fElemMapSize]; 490 int fSortCount = 0; 491 492 for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { 493 final int id = fElemMapId[elemIndex]; 494 for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++) { 495 if (id == fLeafList[leafIndex].getParticleId()) 496 fLeafSorter[fSortCount++] = leafIndex; 497 } 498 fLeafSorter[fSortCount++] = -1; 499 } 500 501 502 503 int curArraySize = fLeafCount * 4; 517 CMStateSet[] statesToDo = new CMStateSet[curArraySize]; 518 fFinalStateFlags = new boolean[curArraySize]; 519 fTransTable = new int[curArraySize][]; 520 521 CMStateSet setT = fHeadNode.firstPos(); 527 528 int unmarkedState = 0; 537 int curState = 0; 538 539 fTransTable[curState] = makeDefStateList(); 544 statesToDo[curState] = setT; 545 curState++; 546 547 550 551 java.util.Hashtable stateTable = new java.util.Hashtable (); 552 553 554 555 while (unmarkedState < curState) { 561 setT = statesToDo[unmarkedState]; 566 int[] transEntry = fTransTable[unmarkedState]; 567 568 fFinalStateFlags[unmarkedState] = setT.getBit(EOCPos); 570 571 unmarkedState++; 573 574 CMStateSet newSet = null; 576 577 int sorterIndex = 0; 578 579 for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { 580 if (newSet == null) 587 newSet = new CMStateSet(fLeafCount); 588 else 589 newSet.zeroBits(); 590 591 592 int leafIndex = fLeafSorter[sorterIndex++]; 593 594 while (leafIndex != -1) { 595 if (setT.getBit(leafIndex)) { 597 newSet.union(fFollowList[leafIndex]); 603 } 604 605 leafIndex = fLeafSorter[sorterIndex++]; 606 } 607 608 609 if (!newSet.isEmpty()) { 614 619 620 Integer stateObj = (Integer )stateTable.get(newSet); 621 int stateIndex = (stateObj == null ? curState : stateObj.intValue()); 622 623 624 if (stateIndex == curState) { 626 statesToDo[curState] = newSet; 632 fTransTable[curState] = makeDefStateList(); 633 634 635 stateTable.put(newSet, new Integer (curState)); 636 637 638 curState++; 640 641 newSet = null; 647 } 648 649 transEntry[elemIndex] = stateIndex; 656 657 if (curState == curArraySize) { 659 final int newSize = (int)(curArraySize * 1.5); 665 CMStateSet[] newToDo = new CMStateSet[newSize]; 666 boolean[] newFinalFlags = new boolean[newSize]; 667 int[][] newTransTable = new int[newSize][]; 668 669 for (int expIndex = 0; expIndex < curArraySize; expIndex++) { 671 newToDo[expIndex] = statesToDo[expIndex]; 672 newFinalFlags[expIndex] = fFinalStateFlags[expIndex]; 673 newTransTable[expIndex] = fTransTable[expIndex]; 674 } 675 676 curArraySize = newSize; 678 statesToDo = newToDo; 679 fFinalStateFlags = newFinalFlags; 680 fTransTable = newTransTable; 681 } 682 } 683 } 684 } 685 686 if (DEBUG_VALIDATE_CONTENT) 691 dumpTree(fHeadNode, 0); 692 fHeadNode = null; 693 fLeafList = null; 694 fFollowList = null; 695 fLeafListType = null; 696 fElemMapId = null; 697 } 698 699 706 private void calcFollowList(CMNode nodeCur) { 707 if (nodeCur.type() == XSModelGroupImpl.MODELGROUP_CHOICE) { 709 calcFollowList(((XSCMBinOp)nodeCur).getLeft()); 711 calcFollowList(((XSCMBinOp)nodeCur).getRight()); 712 } 713 else if (nodeCur.type() == XSModelGroupImpl.MODELGROUP_SEQUENCE) { 714 calcFollowList(((XSCMBinOp)nodeCur).getLeft()); 716 calcFollowList(((XSCMBinOp)nodeCur).getRight()); 717 718 final CMStateSet last = ((XSCMBinOp)nodeCur).getLeft().lastPos(); 724 final CMStateSet first = ((XSCMBinOp)nodeCur).getRight().firstPos(); 725 726 for (int index = 0; index < fLeafCount; index++) { 732 if (last.getBit(index)) 733 fFollowList[index].union(first); 734 } 735 } 736 else if (nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_MORE 737 || nodeCur.type() == XSParticleDecl.PARTICLE_ONE_OR_MORE) { 738 calcFollowList(((XSCMUniOp)nodeCur).getChild()); 740 741 final CMStateSet first = nodeCur.firstPos(); 746 final CMStateSet last = nodeCur.lastPos(); 747 748 for (int index = 0; index < fLeafCount; index++) { 754 if (last.getBit(index)) 755 fFollowList[index].union(first); 756 } 757 } 758 759 else if (nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_ONE) { 760 calcFollowList(((XSCMUniOp)nodeCur).getChild()); 762 } 763 764 } 765 766 774 private void dumpTree(CMNode nodeCur, int level) { 775 for (int index = 0; index < level; index++) 776 System.out.print(" "); 777 778 int type = nodeCur.type(); 779 780 switch(type ) { 781 782 case XSModelGroupImpl.MODELGROUP_CHOICE: 783 case XSModelGroupImpl.MODELGROUP_SEQUENCE: { 784 if (type == XSModelGroupImpl.MODELGROUP_CHOICE) 785 System.out.print("Choice Node "); 786 else 787 System.out.print("Seq Node "); 788 789 if (nodeCur.isNullable()) 790 System.out.print("Nullable "); 791 792 System.out.print("firstPos="); 793 System.out.print(nodeCur.firstPos().toString()); 794 System.out.print(" lastPos="); 795 System.out.println(nodeCur.lastPos().toString()); 796 797 dumpTree(((XSCMBinOp)nodeCur).getLeft(), level+1); 798 dumpTree(((XSCMBinOp)nodeCur).getRight(), level+1); 799 break; 800 } 801 case XSParticleDecl.PARTICLE_ZERO_OR_MORE: 802 case XSParticleDecl.PARTICLE_ONE_OR_MORE: 803 case XSParticleDecl.PARTICLE_ZERO_OR_ONE: { 804 System.out.print("Rep Node "); 805 806 if (nodeCur.isNullable()) 807 System.out.print("Nullable "); 808 809 System.out.print("firstPos="); 810 System.out.print(nodeCur.firstPos().toString()); 811 System.out.print(" lastPos="); 812 System.out.println(nodeCur.lastPos().toString()); 813 814 dumpTree(((XSCMUniOp)nodeCur).getChild(), level+1); 815 break; 816 } 817 case XSParticleDecl.PARTICLE_ELEMENT: { 818 System.out.print 819 ( 820 "Leaf: (pos=" 821 + ((XSCMLeaf)nodeCur).getPosition() 822 + "), " 823 + "(elemIndex=" 824 + ((XSCMLeaf)nodeCur).getLeaf() 825 + ") " 826 ); 827 828 if (nodeCur.isNullable()) 829 System.out.print(" Nullable "); 830 831 System.out.print("firstPos="); 832 System.out.print(nodeCur.firstPos().toString()); 833 System.out.print(" lastPos="); 834 System.out.println(nodeCur.lastPos().toString()); 835 break; 836 } 837 case XSParticleDecl.PARTICLE_WILDCARD: 838 System.out.print("Any Node: "); 839 840 System.out.print("firstPos="); 841 System.out.print(nodeCur.firstPos().toString()); 842 System.out.print(" lastPos="); 843 System.out.println(nodeCur.lastPos().toString()); 844 break; 845 default: { 846 throw new RuntimeException ("ImplementationMessages.VAL_NIICM"); 847 } 848 } 849 850 } 851 852 853 858 private int[] makeDefStateList() 859 { 860 int[] retArray = new int[fElemMapSize]; 861 for (int index = 0; index < fElemMapSize; index++) 862 retArray[index] = -1; 863 return retArray; 864 } 865 866 867 private void postTreeBuildInit(CMNode nodeCur) throws RuntimeException { 868 nodeCur.setMaxStates(fLeafCount); 870 871 XSCMLeaf leaf = null; 872 int pos = 0; 873 if (nodeCur.type() == XSParticleDecl.PARTICLE_WILDCARD) { 875 leaf = (XSCMLeaf)nodeCur; 876 pos = leaf.getPosition(); 877 fLeafList[pos] = leaf; 878 fLeafListType[pos] = XSParticleDecl.PARTICLE_WILDCARD; 879 } 880 else if ((nodeCur.type() == XSModelGroupImpl.MODELGROUP_CHOICE) || 881 (nodeCur.type() == XSModelGroupImpl.MODELGROUP_SEQUENCE)) { 882 postTreeBuildInit(((XSCMBinOp)nodeCur).getLeft()); 883 postTreeBuildInit(((XSCMBinOp)nodeCur).getRight()); 884 } 885 else if (nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_MORE || 886 nodeCur.type() == XSParticleDecl.PARTICLE_ONE_OR_MORE || 887 nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_ONE) { 888 postTreeBuildInit(((XSCMUniOp)nodeCur).getChild()); 889 } 890 else if (nodeCur.type() == XSParticleDecl.PARTICLE_ELEMENT) { 891 leaf = (XSCMLeaf)nodeCur; 894 pos = leaf.getPosition(); 895 fLeafList[pos] = leaf; 896 fLeafListType[pos] = XSParticleDecl.PARTICLE_ELEMENT; 897 } 898 else { 899 throw new RuntimeException ("ImplementationMessages.VAL_NIICM"); 900 } 901 } 902 903 909 public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException { 910 byte conflictTable[][] = new byte[fElemMapSize][fElemMapSize]; 915 916 for (int i = 0; i < fTransTable.length && fTransTable[i] != null; i++) { 918 for (int j = 0; j < fElemMapSize; j++) { 919 for (int k = j+1; k < fElemMapSize; k++) { 920 if (fTransTable[i][j] != -1 && 921 fTransTable[i][k] != -1) { 922 if (conflictTable[j][k] == 0) { 923 conflictTable[j][k] = XSConstraints.overlapUPA 924 (fElemMap[j],fElemMap[k], 925 subGroupHandler) ? 926 (byte)1 : (byte)-1; 927 } 928 } 929 } 930 } 931 } 932 933 for (int i = 0; i < fElemMapSize; i++) { 935 for (int j = 0; j < fElemMapSize; j++) { 936 if (conflictTable[i][j] == 1) { 937 throw new XMLSchemaException("cos-nonambig", new Object []{fElemMap[i].toString(), 941 fElemMap[j].toString()}); 942 } 943 } 944 } 945 946 for (int i = 0; i < fElemMapSize; i++) { 949 if (fElemMapType[i] == XSParticleDecl.PARTICLE_WILDCARD) { 950 XSWildcardDecl wildcard = (XSWildcardDecl)fElemMap[i]; 951 if (wildcard.fType == XSWildcardDecl.NSCONSTRAINT_LIST || 952 wildcard.fType == XSWildcardDecl.NSCONSTRAINT_NOT) { 953 return true; 954 } 955 } 956 } 957 958 return false; 959 } 960 961 970 public Vector whatCanGoHere(int[] state) { 971 int curState = state[0]; 972 if (curState < 0) 973 curState = state[1]; 974 975 Vector ret = new Vector (); 976 for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { 977 if (fTransTable[curState][elemIndex] != -1) 978 ret.addElement(fElemMap[elemIndex]); 979 } 980 return ret; 981 } 982 983 } | Popular Tags |