1 7 8 package com.hp.hpl.jena.xmloutput.impl; 9 10 92 import com.hp.hpl.jena.rdf.model.*; 93 import com.hp.hpl.jena.util.iterator.*; 94 import com.hp.hpl.jena.vocabulary.*; 95 import com.hp.hpl.jena.rdf.model.impl.*; 96 import com.hp.hpl.jena.rdf.arp.*; 97 import com.hp.hpl.jena.shared.*; 98 99 import java.util.*; 100 import java.io.*; 101 102 import org.apache.commons.logging.Log; 103 import org.apache.commons.logging.LogFactory; 104 import org.apache.xerces.util.XMLChar; 105 106 110 class Unparser { 111 static private Property LI = new PropertyImpl(RDF.getURI(), "li"); 112 static private Property DESCRIPTION = 113 new PropertyImpl(RDF.getURI(), "Description"); 114 115 static protected Log logger = LogFactory.getLog(Unparser.class); 116 117 126 Unparser(Abbreviated parent, String localName, Model m, PrintWriter w) { 127 setLocalName(localName); 128 prettyWriter = parent; 129 out = w; 130 model = m; 131 addTypeNameSpaces(); 132 objectTable = new HashMap(); 133 StmtIterator ss = m.listStatements(); 134 try { 135 while (ss.hasNext()) { 136 Statement s = ss.nextStatement(); 137 RDFNode rn = s.getObject(); 138 if (rn instanceof Resource) { 139 increaseObjectCount((Resource) rn); 140 } 141 } 142 } finally { 143 ss.close(); 144 } 145 try { 146 res2statement = new HashMap(); 147 statement2res = new HashMap(); 148 ClosableIterator reified = new MapFilterIterator(new MapFilter() { 149 public Object accept(Object o) { 150 Resource r = (Resource) o; 151 return ( 152 r.hasProperty(RDF.subject) 153 && r.hasProperty(RDF.object) 154 && r.hasProperty(RDF.predicate)) 155 ? r 156 : null; 157 158 } 159 }, model.listSubjectsWithProperty(RDF.type, RDF.Statement)); 160 while (reified.hasNext()) { 161 Resource r = (Resource) reified.next(); 162 try { 163 169 Statement subj = r.getRequiredProperty(RDF.subject); 170 Statement pred = r.getRequiredProperty(RDF.predicate); 171 Statement obj = r.getRequiredProperty(RDF.object); 172 RDFNode nobj = obj.getObject(); 173 Resource rsubj = (Resource) subj.getObject(); 174 Resource rpred = (Resource) pred.getObject(); 175 176 Property ppred = 177 model.createProperty(((Resource) rpred).getURI()); 178 179 Statement statement = 180 model.createStatement((Resource) rsubj, ppred, nobj); 181 res2statement.put(r, statement); 182 statement2res.put(statement, r); 183 } catch (Exception ignored) { 184 } 185 } 186 } finally { 187 ss.close(); 188 } 189 } 190 191 194 private void setLocalName(String uri) { 195 if (uri == null || uri.equals("")) 196 localName = ""; 197 else 198 try { 199 URI u = new URI(uri); 200 u.setFragment(null); 201 localName = u.getURIString(); 202 } catch (MalformedURIException e) { 203 throw new BadURIException( uri, e); 204 } 205 } 206 207 210 void write() { 211 prettyWriter.workOutNamespaces(); 212 wRDF(); 213 219 } 220 225 void setTopLevelTypes(Resource types[]) { 226 pleasingTypes = types; 227 pleasingTypeSet = new HashSet(Arrays.asList(types)); 228 } 229 230 private String xmlBase; 231 void setXMLBase(String b) { 232 xmlBase = b; 233 } 234 238 239 final private static String rdfns = RDF.type.getNameSpace(); 240 final private static Integer one = new Integer (1); 241 242 private String localName; 243 private Map objectTable; private Model model; 247 private PrintWriter out; 248 private Set doing = new HashSet(); private Set doneSet = new HashSet(); private Set haveReified = new HashSet(); 255 private Resource pleasingTypes[] = null; 256 private Set pleasingTypeSet = new HashSet(); 257 258 final private Abbreviated prettyWriter; 259 260 private boolean avoidExplicitReification = true; 261 263 265 Map res2statement; 266 Map statement2res; 267 268 278 281 private void wRDF() { 282 tab(); 283 print("<"); 284 print(prettyWriter.rdfEl("RDF")); 285 indentPlus(); 286 printNameSpaceDefn(); 287 if (xmlBase != null) { 288 setLocalName(xmlBase); 289 tab(); 290 print("xml:base=" + quote(xmlBase)); 291 } 292 print(">"); 293 wObjStar(); 294 indentMinus(); 295 tab(); 296 print("</"); 297 print(prettyWriter.rdfEl("RDF")); 298 print(">"); 299 tab(); 300 } 301 302 305 private void wObjStar() { 306 Iterator rs = listSubjects(); 307 while (rs.hasNext()) { 308 Resource r = (Resource) rs.next(); 309 increaseObjectCount(r); 310 wObj(r, true); 313 } 314 closeAllResIterators(); 315 } 316 317 337 private boolean wPropertyElt( 338 WType wt, 339 Property prop, 340 Statement s, 341 RDFNode val) { 342 return wPropertyEltCompact(wt, prop, s, val) || wPropertyEltDamlCollection(wt, prop, s, val) || wPropertyEltLiteral(wt, prop, s, val) || wPropertyEltResource(wt, prop, s, val) || wPropertyEltDatatype(wt, prop, s, val) 347 || wPropertyEltValue(wt, prop, s, val); 348 } 350 351 353 private boolean wPropertyEltCompact( 354 WType wt, 355 Property prop, 356 Statement s, 357 RDFNode val) { 358 if (!(val instanceof Resource)) 360 return false; 361 Resource r = (Resource) val; 362 if (!(allPropsAreAttr(r) || doing.contains(r))) 363 return false; 364 if ((!hasProperties(r)) && isGenuineAnon(r)) 369 return false; 370 done(s); 372 tab(); 373 print("<"); 374 wt.wTypeStart(prop); 375 indentPlus(); 376 wIdRefAttrOpt(s, r); 377 if (!doing.contains(r)) { 378 wPropAttrAll(r); 379 } else if (isGenuineAnon(r)) { 380 error("Genuine anon resource in cycle?"); 382 } 383 indentMinus(); 384 print("/>"); 385 return true; 386 } 387 388 392 private boolean wPropertyEltLiteral( 393 WType wt, 394 Property prop, 395 Statement s, 396 RDFNode r) { 397 if (prettyWriter.sParseTypeLiteralPropertyElt) 398 return false; 399 if (!((r instanceof Literal) && ((Literal) r).getWellFormed())) { 400 return false; 401 } 402 done(s); 404 tab(); 405 print("<"); 406 wt.wTypeStart(prop); 407 wIdAttrReified(s); 408 maybeNewline(); 409 wParseLiteral(); 410 maybeNewline(); 411 print(">"); 412 print(((Literal) r).getLexicalForm()); 413 print("</"); 414 wt.wTypeEnd(prop); 415 print(">"); 416 return true; 417 } 418 419 private boolean wPropertyEltDatatype( 420 WType wt, 421 Property prop, 422 Statement s, 423 RDFNode r) { 424 if (!((r instanceof Literal) 425 && ((Literal) r).getDatatypeURI() != null)) { 426 return false; 427 } 428 done(s); 430 tab(); 431 print("<"); 432 wt.wTypeStart(prop); 433 wIdAttrReified(s); 434 maybeNewline(); 435 wDatatype(((Literal) r).getDatatypeURI()); 436 maybeNewline(); 437 print(">"); 438 print( 439 Util.substituteEntitiesInElementContent( 440 ((Literal) r).getLexicalForm())); 441 print("</"); 442 wt.wTypeEnd(prop); 443 print(">"); 444 return true; 445 } 446 447 451 private boolean wPropertyEltResource( 452 WType wt, 453 Property prop, 454 Statement s, 455 RDFNode r) { 456 if (prettyWriter.sParseTypeResourcePropertyElt) 457 return false; 458 if (r instanceof Literal) 459 return false; 460 Resource res = (Resource) r; 461 if (!isGenuineAnon(res)) 462 return false; 463 if (getType(res) != null) 464 return false; done(s); 467 tab(); 468 print("<"); 469 wt.wTypeStart(prop); 470 indentPlus(); 471 wIdAttrReified(s); 472 wParseResource(); 473 print(">"); 474 wPropertyEltStar(res); 475 indentMinus(); 476 tab(); 477 print("</"); 478 wt.wTypeEnd(prop); 479 print(">"); 480 return true; 481 } 482 483 486 private boolean wPropertyEltValue( 487 WType wt, 488 Property prop, 489 Statement s, 490 RDFNode r) { 491 return wPropertyEltValueString(wt, prop, s, r) 492 || wPropertyEltValueObj(wt, prop, s, r); 493 } 494 495 498 private boolean wPropertyEltValueString( 499 WType wt, 500 Property prop, 501 Statement s, 502 RDFNode r) { 503 if (r instanceof Literal) { 504 done(s); 505 Literal lt = (Literal) r; 506 String lang = lt.getLanguage(); 507 tab(); 508 print("<"); 509 wt.wTypeStart(prop); 510 wIdAttrReified(s); 511 maybeNewline(); 512 if (lang != null && lang.length() > 0) 513 print(" xml:lang=" + q(lang)); 514 maybeNewline(); 515 print(">"); 516 wValueString(lt); 517 print("</"); 518 wt.wTypeEnd(prop); 519 print(">"); 520 return true; 521 } else { 522 return false; 523 } 524 } 525 526 529 private void wValueString(Literal lt) { 530 String val = lt.getString(); 531 print(Util.substituteEntitiesInElementContent(val)); 532 } 533 534 538 private boolean wPropertyEltValueObj( 539 WType wt, 540 Property prop, 541 Statement s, 542 RDFNode r) { 543 if (r instanceof Resource && !prettyWriter.sResourcePropertyElt) { 544 Resource res = (Resource) r; 545 done(s); 546 tab(); 547 print("<"); 548 wt.wTypeStart(prop); 549 wIdAttrReified(s); 550 print(">"); 551 tab(); 552 indentPlus(); 553 wObj(res, false); 554 indentMinus(); 555 tab(); 556 print("</"); 557 wt.wTypeEnd(prop); 558 print(">"); 559 return true; 560 } else { 561 return false; 562 } 563 } 564 565 570 private boolean wPropertyEltDamlCollection( 571 WType wt, 572 Property prop, 573 Statement s, 574 RDFNode r) { 575 boolean daml = true; 576 Statement list[][] = getDamlList(r); 577 if (list == null) { 578 daml = false; 579 list = getRDFList(r); 580 } 581 if (list == null) 582 return false; 583 done(s); 585 for (int i = 0; i < list.length; i++) { 588 done(list[i][0]); 589 done(list[i][1]); 590 if (daml) 591 done(list[i][2]); 592 } 593 tab(); 594 print("<"); 595 wt.wTypeStart(prop); 596 indentPlus(); 597 wIdAttrReified(s); 598 if (daml) 599 wParseDamlCollection(); 600 else 601 wParseCollection(); 602 603 print(">"); 604 for (int i = 0; i < list.length; i++) { 605 wObj((Resource) list[i][0].getObject(), false); 606 } 607 indentMinus(); 608 tab(); 609 print("</"); 610 wt.wTypeEnd(prop); 611 print(">"); 612 return true; 613 } 614 615 private void wPropAttrAll(Resource r) { 617 wPropAttrSome(r); 618 if (hasProperties(r)) 619 error("Bad call to wPropAttrAll"); 620 } 621 622 private void wPropAttrSome(Resource r) { 624 ClosableIterator ss = listProperties(r); 625 try { 626 Set seen = new HashSet(); 627 while (ss.hasNext()) { 628 Statement s = (Statement) ss.next(); 629 RDFNode val = s.getObject(); 630 if (canBeAttribute(s, seen)) { 631 done(s); 632 wPropAttr(s.getPredicate(), s.getObject()); 633 } 634 } 635 } finally { 636 ss.close(); 637 } 638 } 639 640 662 private boolean wObj(Resource r, boolean topLevel) { 663 try { 664 doing.add(r); 665 Statement typeStatement = getType(r); 666 if (typeStatement != null) { 667 Resource t = typeStatement.getResource(); 668 if (!topLevel) { 669 if (pleasingTypeSet.contains(t) && (!isGenuineAnon(r))) { 670 return wTypedNodeNoProperties(r); 671 } 672 } 673 return wTypedNode(r) || wDescription(r); 674 } else 675 return wDescription(r); 676 } finally { 677 doing.remove(r); 678 } 679 } 680 681 abstract private class WType { 682 abstract void wTypeStart(Resource uri); 683 abstract void wTypeEnd(Resource uri); 684 } 685 686 static private int RDF_HASH = RDF.getURI().length(); 687 688 private WType wdesc = new WType() { 689 void wTypeStart(Resource u) { 690 print(prettyWriter.rdfEl(u.getURI().substring(RDF_HASH))); 691 } 692 void wTypeEnd(Resource u) { 693 print(prettyWriter.rdfEl(u.getURI().substring(RDF_HASH))); 694 } 695 }; 696 697 private WType wtype = new WType() { 698 void wTypeStart(Resource u) { 699 print(prettyWriter.startElementTag(u.getURI())); 700 } 701 void wTypeEnd(Resource u) { 702 print(prettyWriter.endElementTag(u.getURI())); 703 } 704 }; 705 706 711 private boolean wDescription(Resource r) { 712 return wTypedNodeOrDescription(wdesc, DESCRIPTION, r); 713 } 714 719 private boolean wTypedNode(Resource r) { 720 Statement st = getType(r); 721 if (st == null) 722 return false; 723 Resource type = st.getResource(); 724 done(st); 725 return wTypedNodeOrDescription(wtype, type, r); 726 } 727 728 private boolean wTypedNodeOrDescription( 729 WType wt, 730 Resource ty, 731 Resource r) { 732 Vector found = new Vector(); 734 ClosableIterator ss = listProperties(r); 735 try { 736 int greatest = 0; 737 if (!prettyWriter.sListExpand) 738 while (ss.hasNext()) { 739 Statement s = (Statement) ss.next(); 740 int ix = s.getPredicate().getOrdinal(); 741 if (ix != 0) { 742 if (ix > greatest) { 743 found.setSize(ix); 744 greatest = ix; 745 } 746 found.set(ix - 1, s); 747 } 748 } 749 } finally { 750 ss.close(); 751 } 752 int last = found.indexOf(null); 753 List li = last == -1 ? found : found.subList(0, last); 754 755 return wTypedNodeOrDescriptionCompact(wt, ty, r, li) 756 || wTypedNodeOrDescriptionLong(wt, ty, r, li); 757 } 758 759 761 private boolean wTypedNodeOrDescriptionCompact( 762 WType wt, 763 Resource ty, 764 Resource r, 765 List li) { 766 if ((!li.isEmpty()) || !allPropsAreAttr(r)) 768 return false; 769 tab(); 771 print("<"); 772 wt.wTypeStart(ty); 773 indentPlus(); 774 wIdAboutAttrOpt(r); 775 wPropAttrAll(r); 776 print("/>"); 777 indentMinus(); 778 return true; 779 } 780 781 783 private boolean wTypedNodeNoProperties(Resource r) { 784 if (isGenuineAnon(r)) 786 return false; 787 Statement st = getType(r); 788 if (st == null) 789 return false; 790 Resource type = st.getResource(); 791 done(st); 792 tab(); 794 print("<"); 795 wtype.wTypeStart(type); 796 indentPlus(); 797 wIdAboutAttrOpt(r); 801 print("/>"); 802 indentMinus(); 803 return true; 804 } 805 806 810 private boolean wTypedNodeOrDescriptionLong( 811 WType wt, 812 Resource ty, 813 Resource r, 814 List li) { 815 Iterator it = li.iterator(); 816 while (it.hasNext()) { 817 done((Statement) it.next()); 818 } 819 820 tab(); 821 print("<"); 822 wt.wTypeStart(ty); 823 indentPlus(); 824 wIdAboutAttrOpt(r); 825 wPropAttrSome(r); 826 print(">"); 827 wLiEltStar(li.iterator()); 828 wPropertyEltStar(r); 829 indentMinus(); 830 tab(); 831 print("</"); 832 wt.wTypeEnd(ty); 833 print(">"); 834 return true; 835 } 836 837 private void wPropertyEltStar(Resource r) { 838 ClosableIterator ss = this.listProperties(r); 839 try { 840 while (ss.hasNext()) { 841 Statement s = (Statement) ss.next(); 842 wPropertyElt(wtype, s.getPredicate(), s, s.getObject()); 843 } 844 } finally { 845 ss.close(); 846 } 847 } 848 849 private void wLiEltStar(Iterator ss) { 850 while (ss.hasNext()) { 851 Statement s = (Statement) ss.next(); 852 wPropertyElt(wdesc, LI, s, s.getObject()); 853 } 854 } 855 856 861 private Set idDone = new HashSet(); 862 863 private boolean wIdAboutAttrOpt(Resource r) { 864 return wIdAttrOpt(r) || wNodeIDAttr(r) || wAboutAttr(r); 865 } 866 867 872 private boolean wIdAttrOpt(Resource r) { 873 874 if (isGenuineAnon(r)) 875 return true; if (prettyWriter.sIdAttr) 877 return false; 878 if (r.isAnon()) 879 return false; 880 if (isLocalReference(r)) { 881 if (wantReification(r)) 884 return false; 885 if (idDone.contains(r)) { 887 return false; } else { 889 idDone.add(r); 890 print(" "); 891 printRdfAt("ID"); 892 print("="); 893 print(quote(getLocalName(r))); 894 return true; 895 } 896 } else { 897 return false; 898 } 899 } 900 901 904 private boolean wAboutAttr(Resource r) { 905 print(" "); 906 printRdfAt("about"); 907 print("="); 908 wURIreference(r); 909 return true; 910 } 911 912 private void wURIreference(String s) { 913 print(quote(prettyWriter.relativize(s))); 914 } 915 916 private void wURIreference(Resource r) { 917 wURIreference(r.getURI()); 918 } 919 920 923 private void wIdRefAttrOpt(Statement s, Resource r) { 924 wIdAttrReified(s); 925 if (!isGenuineAnon(r)) { 926 wResourceNodeIDAttr(r); 927 } 928 } 929 930 933 private void wIdAttrReified(Statement s) { 934 if (wantReification(s)) { 935 941 Statement reify[] = reification(s); 942 Resource res = (Resource) statement2res.get(s); 943 idDone.add(res); 944 int i; 945 for (i = 0; i < reify.length; i++) 946 done(reify[i]); 947 print(" "); 948 printRdfAt("ID"); 949 print("="); 950 print(quote(getLocalName(res))); 951 haveReified.add(res); 952 } 953 } 954 955 958 private boolean wResourceNodeIDAttr(Resource r) { 959 return wNodeIDAttr(r) || wResourceAttr(r); 960 } 961 962 965 private boolean wNodeIDAttr(Resource r) { 966 if (!r.isAnon()) 967 return false; 968 print(" "); 969 printRdfAt("nodeID"); 970 print("="); 971 print(q(prettyWriter.anonId(r))); 972 973 return true; 974 } 975 976 979 private boolean wResourceAttr(Resource r) { 980 if (r.isAnon()) 981 return false; 982 print(" "); 983 printRdfAt("resource"); 984 print("="); 985 wURIreference(r); 986 return true; 987 } 988 989 int codeCoverage[] = new int[8]; 990 991 1002 private void wQNameAttr(Property p) { 1003 print(prettyWriter.attributeTag(p.getURI())); 1004 } 1005 1006 private void printRdfAt(String s) { 1007 print(prettyWriter.rdfAt(s)); 1008 } 1009 1010 1015 private void wPropAttr(Property p, RDFNode n) { 1016 tab(); 1017 if (p.equals(RDF.type)) 1018 wTypeAttr((Resource) n); 1019 else 1020 wPropAttrString(p, (Literal) n); 1021 } 1022 1023 private void wTypeAttr(Resource r) { 1024 print(" "); 1025 printRdfAt("type"); 1026 print("="); 1027 wURIreference(r); 1028 } 1030 1031 private void wPropAttrString(Property p, Literal l) { 1032 print(" "); 1033 wQNameAttr(p); 1034 print("=" + quote(l.getString())); 1035 } 1036 1037 1040 private void wParseDamlCollection() { 1041 print(" "); 1042 printRdfAt("parseType"); 1043 print("=" + q("daml:collection")); 1044 } 1045 1046 1049 private void wParseCollection() { 1050 print(" "); 1051 printRdfAt("parseType"); 1052 print("=" + q("Collection")); 1053 } 1054 1055 1058 private void wParseLiteral() { 1059 print(" "); 1060 printRdfAt("parseType"); 1061 print("=" + q("Literal")); 1062 } 1063 1064 private void wDatatype(String dtURI) { 1065 print(" "); 1066 printRdfAt("datatype"); 1067 print("="); 1068 maybeNewline(); 1069 wURIreference(dtURI); 1070 } 1071 1074 private void wParseResource() { 1075 print(" "); 1076 printRdfAt("parseType"); 1077 print("=" + q("Resource")); 1078 } 1079 1080 private void printNameSpaceDefn() { 1081 print(prettyWriter.xmlnsDecl()); 1082 } 1083 1084 1088 1089 1092 private int indentLevel = 0; 1093 1094 private int currentColumn = 0; 1095 1096 static private String filler(int lgth) { 1097 char rslt[] = new char[lgth]; 1098 Arrays.fill(rslt, ' '); 1099 return new String (rslt); 1100 } 1101 1102 private void tab() { 1103 int desiredColumn = prettyWriter.tab * indentLevel; 1104 if (desiredColumn > prettyWriter.width) { 1105 desiredColumn = 4 + (desiredColumn - 4) % prettyWriter.width; 1106 } 1107 if ((desiredColumn == 0 && currentColumn == 0) 1108 || desiredColumn > currentColumn) { 1109 String spaces = filler(desiredColumn - currentColumn); 1110 out.print(spaces); 1111 } else { 1112 out.println(); 1113 out.print(filler(desiredColumn)); 1114 } 1115 currentColumn = desiredColumn; 1116 } 1117 1118 private void maybeNewline() { 1119 if (currentColumn > prettyWriter.width) { 1120 tab(); 1121 } 1122 } 1123 1124 1129 private String quote(String str) { 1130 return prettyWriter.qq(str); 1131 } 1132 private String q(String str) { 1133 return prettyWriter.q(str); 1134 } 1135 1136 1140 private void print(String s) { 1141 out.print(s); 1142 int ix = s.lastIndexOf('\n'); 1143 if (ix == -1) 1144 currentColumn += s.length(); 1145 else 1146 currentColumn = s.length() - ix - 1; 1147 } 1148 1149 private void indentPlus() { 1150 indentLevel++; 1151 } 1152 1153 private void indentMinus() { 1154 indentLevel--; 1155 } 1156 1157 1159 private void error(String msg) { 1160 JenaException e = 1161 new BrokenException("Internal error in Unparser: " + msg); 1162 this.prettyWriter.fatalError(e); 1163 throw e; } 1165 1168 private void addTypeNameSpaces() { 1169 NodeIterator nn = model.listObjectsOfProperty(RDF.type); 1170 try { 1171 while (nn.hasNext()) { 1172 RDFNode obj = nn.nextNode(); 1173 int split = isOKType(obj); 1174 if (split != -1) 1175 prettyWriter.addNameSpace( 1176 ((Resource) obj).getURI().substring(0, split)); 1177 } 1178 } finally { 1179 nn.close(); 1180 } 1181 } 1182 1183 private String getNameSpace(Resource r) { 1184 if (r.isAnon()) { 1185 logger.error("Internal error - Unparser.getNameSpace; giving up"); 1186 throw new BrokenException("Internal error: getNameSpace(bNode)"); 1187 } 1188 String uri = r.getURI(); 1189 int split = Util.splitNamespace(uri); 1190 return uri.substring(0, split); 1191 1192 } 1193 1194 1197 private boolean isGenuineAnon(Resource r) { 1198 if (!r.isAnon()) 1199 return false; 1200 Integer v = (Integer ) objectTable.get(r); 1201 return v == null 1202 || ((!prettyWriter.sResourcePropertyElt) 1203 && v.intValue() <= 1 1204 && (!haveReified.contains(r))); 1205 } 1206 1207 private boolean isLocalReference(Resource r) { 1208 return (!r.isAnon()) 1209 && getNameSpace(r).equals(localName + "#") 1210 && XMLChar.isValidNCName(getLocalName(r)); 1211 } 1212 1227 1228 private String getLocalName(Resource r) { 1229 if (r.isAnon()) { 1230 logger.error("Internal error - giving up - Unparser.getLocalName"); 1231 throw new BrokenException("Internal error: getLocalName(bNode)"); 1232 } else { 1233 String uri = r.getURI(); 1234 int split = Util.splitNamespace(uri); 1235 return uri.substring(split); 1236 } 1237 } 1238 1241 1242 private void increaseObjectCount(Resource r) { 1243 if (!r.isAnon()) 1244 return; 1245 Integer cnt = (Integer ) objectTable.get(r); 1246 if (cnt == null) { 1247 cnt = one; 1248 } else { 1249 cnt = new Integer (cnt.intValue() + 1); 1250 } 1251 objectTable.put(r, cnt); 1252 } 1253 1254 1257 1260 private boolean wantReification(Statement s) { 1261 return wantReification(s, (Resource) statement2res.get(s)); 1262 } 1263 1264 private boolean wantReification(Resource res) { 1265 return wantReification((Statement) res2statement.get(res), res); 1266 } 1267 1268 private boolean wantReification(Statement s, Resource ref) { 1269 if (s == null 1270 || ref == null 1271 || ref.isAnon() 1272 || prettyWriter.sReification) 1273 return false; 1274 if (!(isLocalReference(ref))) 1275 return false; 1276 Statement reify[] = reification(s); 1277 int i; 1278 for (i = 0; i < reify.length; i++) 1279 if (doneSet.contains(reify[i]) || (!model.contains(reify[i]))) 1280 return false; return true; } 1283 1284 private Statement[] reification(Statement s) { 1285 Model m = s.getModel(); 1286 Resource r = (Resource) statement2res.get(s); 1287 return new Statement[] { 1288 m.createStatement(r, RDF.type, RDF.Statement), 1289 m.createStatement(r, RDF.subject, s.getSubject()), 1290 m.createStatement(r, RDF.predicate, s.getPredicate()), 1291 m.createStatement(r, RDF.object, s.getObject())}; 1292 } 1293 1294 private boolean hasProperties(Resource r) { 1295 ExtendedIterator ss = listProperties(r); 1296 if (avoidExplicitReification 1297 && (!r.isAnon()) 1299 && isLocalReference(r) 1300 && res2statement.containsKey(r)) { 1301 ss = new MapFilterIterator(new MapFilter() { 1302 public Object accept(Object o) { 1303 Statement s = (Statement) o; 1304 Property p = s.getPredicate(); 1305 String local = p.getLocalName(); 1306 return ( 1307 (!p.getNameSpace().equals(rdfns)) 1308 || !((RDF.type.equals(p) 1309 && s.getObject().equals(RDF.Statement)) 1310 || RDF.object.equals(p) 1311 || RDF.predicate.equals(p) 1312 || RDF.subject.equals(p))) 1313 ? o 1314 : null; 1315 } 1316 }, ss); 1317 } 1318 try { 1319 return ss.hasNext(); 1320 } finally { 1321 ss.close(); 1322 } 1323 } 1324 private ExtendedIterator listProperties(Resource r) { 1325 return new MapFilterIterator(new MapFilter() { 1326 public Object accept(Object o) { 1327 return doneSet.contains(o) ? null : o; 1328 } 1329 }, r.listProperties()); 1330 } 1331 private boolean canBeAttribute(Statement s, Set seen) { 1334 Property p = s.getPredicate(); 1335 if (prettyWriter.sPropertyAttr 1337 || seen.contains(p)) return false; 1340 seen.add(p); 1341 1342 if (p.equals(RDF.type)) { 1343 RDFNode n = s.getObject(); 1347 return (n instanceof Resource) && !((Resource) n).isAnon(); 1348 } 1349 1350 if (s.getObject() instanceof Literal) { 1351 Literal l = s.getLiteral(); 1352 if (l.getDatatypeURI() != null) 1353 return false; 1354 1355 if (l.getLanguage().equals("")) { 1356 if (prettyWriter.isDefaultNamespace(getNameSpace(p))) 1358 return false; 1359 1360 String str = l.getString(); 1361 if (str.length() < 40) { 1362 char buf[] = str.toCharArray(); 1363 for (int i = 0; i < buf.length; i++) { 1364 if (buf[i] <= ' ') 1366 return false; 1367 } 1368 return !wantReification(s); 1369 } 1370 } 1371 } 1372 return false; 1373 } 1374 1375 private boolean allPropsAreAttr(Resource r) { 1376 ClosableIterator ss = listProperties(r); 1377 Set seen = new HashSet(); 1378 try { 1379 while (ss.hasNext()) { 1380 Statement s = (Statement) ss.next(); 1381 if (!canBeAttribute(s, seen)) 1382 return false; 1383 } 1384 } finally { 1385 ss.close(); 1386 } 1387 return true; 1388 } 1389 private void done(Statement s) { 1390 doneSet.add(s); 1391 } 1393 1400 private Statement[][] getDamlList(RDFNode r) { 1401 return prettyWriter.sDamlCollection 1402 ? null 1403 : getList( 1404 r, 1405 DAML_OIL.List, 1406 DAML_OIL.first, 1407 DAML_OIL.rest, 1408 DAML_OIL.nil); 1409 } 1410 private Statement[][] getRDFList(RDFNode r) { 1411 return prettyWriter.sParseTypeCollectionPropertyElt 1412 ? null 1413 : getList(r, null, RDF.first, RDF.rest, RDF.nil); 1414 } 1415 1416 private Statement[][] getList( 1417 RDFNode r, 1418 Resource list, 1419 Property first, 1420 Property rest, 1421 Resource nil) { 1422 boolean lookingGood = false; 1423 1424 Vector rslt = new Vector(); 1425 Set seen = new HashSet(); 1426 RDFNode next = r; 1427 try { 1429 1430 while (!next.equals(nil)) { 1431 Statement elt[] = new Statement[list == null ? 2 : 3]; 1432 if (next instanceof Literal) 1433 return null; 1434 Resource res = (Resource) next; 1435 if (!isGenuineAnon(res)) 1437 return null; 1438 if (seen.contains(next)) 1440 return null; 1441 seen.add(next); 1442 1443 StmtIterator ss = res.listProperties(); 1445 try { 1446 while (ss.hasNext()) { 1447 Statement s = ss.nextStatement(); 1448 Property p = s.getPredicate(); 1449 int ix; 1450 RDFNode obj = s.getObject(); 1451 if (doneSet.contains(s)) 1452 return null; 1453 if (!(obj instanceof Resource)) { 1454 return null; 1455 } 1456 if (p.equals(RDF.type)) { 1457 ix = 2; 1458 if (!obj.equals(list)) 1459 return null; 1460 } else if (p.equals(first)) { 1461 ix = 0; 1462 lookingGood = true; 1463 } else if (p.equals(rest)) { 1464 ix = 1; 1465 next = obj; 1466 } else { 1467 return null; 1468 } 1469 if (elt[ix] != null) 1470 return null; 1471 elt[ix] = s; 1472 } 1473 } finally { 1474 ss.close(); 1475 } 1476 for (int i = 0; i < elt.length; i++) 1477 if (elt[i] == null) 1478 return null; 1480 rslt.add(elt); 1481 } 1482 if (rslt.size() == 0) 1483 return null; 1484 lookingGood = false; } finally { 1486 1495 } 1496 Statement array[][] = new Statement[rslt.size()][]; 1497 rslt.copyInto(array); 1498 return array; 1499 1500 } 1501 1504 private Statement getType(Resource r) { 1505 Statement rslt; 1506 try { 1507 if (r instanceof Statement) { 1508 rslt = ((Statement) r).getStatementProperty(RDF.type); 1509 if (rslt == null || (!rslt.getObject().equals(RDF.Statement))) 1510 error("Statement type problem"); 1511 } else { 1512 rslt = r.getRequiredProperty(RDF.type); 1513 } 1514 } catch (PropertyNotFoundException rdfe) { 1515 if (r instanceof Statement) 1516 error("Statement type problem"); 1517 rslt = null; 1518 } 1519 if (rslt == null || isOKType(rslt.getObject()) == -1) 1520 return null; 1521 1522 return rslt; 1523 } 1524 1525 1528 1529 private int isOKType(RDFNode n) { 1530 1531 if (!(n instanceof Resource)) 1532 return -1; 1533 if (((Resource) n).isAnon()) 1534 return -1; 1535 String uri = ((Resource) n).getURI(); 1537 1538 int split = Util.splitNamespace(uri); 1539 if (split == 0 || split == uri.length()) 1540 return -1; 1541 1542 return split; 1543 } 1544 1545 1549 private Set infinite; 1550 private void findInfiniteCycles() { 1551 StmtIterator ss = model.listStatements(); 1553 Relation relation = new Relation(); 1554 try { 1555 while (ss.hasNext()) { 1556 Statement s = ss.nextStatement(); 1557 if (!doneSet.contains(s)) { 1558 RDFNode rn = s.getObject(); 1559 if (rn instanceof Resource) { 1560 relation.set(s.getSubject(), rn); 1561 } 1562 } 1563 } 1564 } finally { 1565 ss.close(); 1566 } 1567 relation.transitiveClosure(); 1568 infinite = relation.getDiagonal(); 1569 } 1570 1575 private Iterator allInfiniteLeft() { 1576 return new LateBindingIterator() { 1577 public Iterator create() { 1578 return infinite.iterator(); 1579 } 1580 }; 1581 } 1582 1583 private Iterator pleasingTypeIterator() { 1584 if (pleasingTypes == null) 1585 return new NullIterator(); 1586 Map buckets = new HashMap(); 1587 Set bucketArray[] = new Set[pleasingTypes.length]; 1588 for (int i = 0; i < pleasingTypes.length; i++) { 1591 bucketArray[i] = new HashSet(); 1592 buckets.put(pleasingTypes[i], bucketArray[i]); 1593 } 1594 1595 ResIterator rs = model.listSubjects(); 1596 try { 1597 while (rs.hasNext()) { 1598 Resource r = rs.nextResource(); 1599 Statement s = getType(r); 1600 if (s != null) { 1601 Set bucket = (Set) buckets.get(s.getObject()); 1602 if (bucket != null) { 1603 if (isGenuineAnon(r)) { 1604 Integer v = (Integer ) objectTable.get(r); 1605 if (v != null && v.intValue() == 1) 1606 continue; 1607 } 1608 bucket.add(r); 1609 } 1610 } 1611 } 1612 } finally { 1613 rs.close(); 1614 } 1615 1616 1619 return new IteratorIterator(new Map1Iterator(new Map1() { 1620 public Object map1(Object bkt) { 1621 return ((Set) bkt).iterator(); 1622 } 1623 }, new ArrayIterator(bucketArray))); 1624 1625 } 1626 1648 private Iterator listSubjects() { 1649 Iterator currentFile = 1651 new SingletonIterator(model.createResource(this.localName)); 1654 Iterator pleasing = pleasingTypeIterator(); 1656 1657 Iterator fakeStopPleasing = new NullIterator() { 1658 public boolean hasNext() { 1659 pleasingTypeSet = new HashSet(); 1660 return false; 1661 } 1662 }; 1663 1664 Iterator nonObjects = new FilterIterator(new Filter() { 1666 public boolean accept(Object o) { 1667 return (!objectTable.containsKey(o)) 1668 && (!wantReification((Resource) o)); 1669 } 1670 }, modelListSubjects()); 1671 Iterator fakeLazyEvaluator = new NullIterator() { 1676 public boolean hasNext() { 1677 findInfiniteCycles(); 1679 return false; 1680 } 1681 }; 1682 Iterator firstChoiceCyclic = new FilterIterator(new Filter() { 1685 public boolean accept(Object o) { 1686 Resource r = (Resource) o; 1687 codeCoverage[4]++; 1688 if (r.isAnon()) 1689 return false; 1690 Integer cnt = (Integer ) objectTable.get(r); 1691 if (cnt == null || cnt.intValue() <= 1) 1692 return false; 1693 return true; 1694 } 1695 }, this.allInfiniteLeft()); 1696 Iterator nonAnonInfinite = new FilterIterator(new Filter() { 1698 public boolean accept(Object o) { 1699 codeCoverage[5]++; 1700 Resource r = (Resource) o; 1701 return !isGenuineAnon(r); 1702 } 1703 }, allInfiniteLeft()); 1704 Iterator infinite = allInfiniteLeft(); 1706 Iterator anotherFake = new NullIterator() { 1707 public boolean hasNext() { 1708 avoidExplicitReification = false; 1709 return false; 1710 } 1711 }; 1712 Iterator reifications = new FilterIterator(new Filter() { 1713 public boolean accept(Object o) { 1714 codeCoverage[6]++; 1715 return res2statement.containsKey(o); 1716 } 1717 }, allInfiniteLeft()); 1718 Iterator backStop = modelListSubjects(); 1720 1721 Iterator all[] = 1722 new Iterator[] { 1723 currentFile, 1724 pleasing, 1725 fakeStopPleasing, 1726 nonObjects, 1727 fakeLazyEvaluator, 1728 firstChoiceCyclic, 1729 nonAnonInfinite, 1730 infinite, 1731 anotherFake, 1732 reifications, 1733 new NullIterator() { 1734 public boolean hasNext() { if ( 1735 modelListSubjects() 1736 .hasNext()) 1737 codeCoverage[7]++; 1738 return false; 1739 } 1740 }, backStop }; 1741 Iterator allAsOne = new IteratorIterator(new ArrayIterator(all)); 1742 1743 return new FilterIterator(new Filter() { 1745 public boolean accept(Object o) { 1746 return hasProperties((Resource) o); 1747 } 1748 }, allAsOne); 1749 } 1750 1751 private Set openResIterators = new HashSet(); 1752 1753 private synchronized void close(ResIterator resIt) { 1754 resIt.close(); 1755 openResIterators.remove(resIt); 1756 } 1757 1758 private synchronized void closeAllResIterators() { 1759 Iterator members = openResIterators.iterator(); 1760 while (members.hasNext()) { 1761 ((ResIterator) members.next()).close(); 1762 } 1763 openResIterators = new HashSet(); 1764 } 1765 1766 private Iterator modelListSubjects() { 1767 ResIterator resIt = model.listSubjects(); 1768 openResIterators.add(resIt); 1769 return resIt; 1770 1771 } 1772 1773} 1774 1775 1804 | Popular Tags |