1 5 6 package com.hp.hpl.jena.n3; 7 8 import com.hp.hpl.jena.rdf.model.*; 10 import com.hp.hpl.jena.shared.JenaException; 11 import com.hp.hpl.jena.vocabulary.RDF ; 12 import com.hp.hpl.jena.vocabulary.RDFS ; 13 import com.hp.hpl.jena.util.iterator.*; 14 15 import java.util.* ; 16 17 23 24 25 26 public class N3JenaWriterPP extends N3JenaWriterCommon 27 28 { 29 33 final private boolean doObjectListsAsLists = getBooleanValue("objectLists", true) ; 34 35 37 Set rdfLists = null ; Set rdfListsAll = null ; Set rdfListsDone = null ; Set roots = null ; Set oneRefObjects = null ; Set oneRefDone = null ; 44 boolean allowDeep = true ; 46 47 static final String objectListSep = " , " ; 48 49 52 protected void prepare(Model model) 53 { 54 prepareLists(model) ; 55 prepareOneRefBNodes(model) ; 56 } 57 58 64 private void prepareLists(Model model) 65 { 66 Set thisListAll = new HashSet(); 67 68 StmtIterator listTailsIter = model.listStatements(null, RDF.rest, RDF.nil); 69 70 tailLoop: 72 for ( ; listTailsIter.hasNext() ; ) 73 { 74 Resource listElement = listTailsIter.nextStatement().getSubject() ; 76 Resource validListHead = null ; 78 79 for ( ; ; ) 81 { 82 boolean isOK = checkListElement(listElement) ; 83 if ( ! isOK ) 84 break ; 85 86 if ( N3JenaWriter.DEBUG ) out.println("# RDF list all: "+formatResource(listElement)) ; 88 validListHead = listElement ; 89 thisListAll.add(listElement) ; 90 91 StmtIterator sPrev = model.listStatements(null, RDF.rest, listElement) ; 93 94 if ( ! sPrev.hasNext() ) 95 break ; 97 98 listElement = sPrev.nextStatement().getSubject() ; 100 if ( sPrev.hasNext() ) 101 { 102 if ( N3JenaWriter.DEBUG ) out.println("# RDF shared tail from "+formatResource(listElement)) ; 103 break ; 104 } 105 } 106 if ( N3JenaWriter.DEBUG ) out.println("# DAML list head: "+formatResource(validListHead)) ; 108 rdfListsAll.addAll(thisListAll) ; 109 if ( validListHead != null ) 110 rdfLists.add(validListHead) ; 111 } 112 listTailsIter.close() ; 113 } 114 115 private boolean checkListElement(Resource listElement) 117 { 118 if (!listElement.hasProperty(RDF.rest) 119 || !listElement.hasProperty(RDF.first)) 120 { 121 if (N3JenaWriter.DEBUG) 122 out.println( 123 "# RDF list element does not have required properties: " 124 + formatResource(listElement)); 125 return false; 126 } 127 128 int numProp = countProperties(listElement); 131 132 if ( numProp == 2) 133 return true ; 135 136 137 if (numProp == 3) 138 { 139 if (listElement.hasProperty(RDF.type, RDF.List)) 140 return true; 141 if (N3JenaWriter.DEBUG) 142 out.println( 143 "# RDF list element: 3 properties but no rdf:type rdf:List" 144 + formatResource(listElement)); 145 return false; 146 } 147 148 if (N3JenaWriter.DEBUG) 149 out.println( 150 "# RDF list element does not right number of properties: " 151 + formatResource(listElement)); 152 return false; 153 } 154 155 159 private void prepareOneRefBNodes(Model model) 160 { 161 162 NodeIterator objIter = model.listObjects() ; 163 for ( ; objIter.hasNext() ; ) 164 { 165 RDFNode n = objIter.nextNode() ; 166 167 if ( testOneRefBNode(n) ) 168 oneRefObjects.add(n) ; 169 objIter.close() ; 170 171 if ( N3JenaWriter.DEBUG ) 173 { 174 out.println("# RDF Lists = "+rdfLists.size()) ; 175 out.println("# RDF ListsAll = "+rdfListsAll.size()) ; 176 out.println("# oneRefObjects = "+oneRefObjects.size()) ; 177 } 178 } 179 } 180 181 private boolean testOneRefBNode(RDFNode n) 182 { 183 if ( ! ( n instanceof Resource ) ) 184 return false ; 185 186 Resource obj = (Resource)n ; 187 188 if ( ! obj.isAnon() ) 189 return false ; 190 191 if ( rdfListsAll.contains(obj) ) 193 return false ; 195 196 StmtIterator pointsToIter = obj.getModel().listStatements(null, null, obj) ; 197 if ( ! pointsToIter.hasNext() ) 198 throw new JenaException("N3: found object with no arcs!") ; 200 201 Statement s = pointsToIter.nextStatement() ; 202 203 if ( pointsToIter.hasNext() ) 204 return false ; 205 206 if ( N3JenaWriter.DEBUG ) 207 out.println("# OneRef: "+formatResource(obj)) ; 208 return true ; 209 } 210 211 214 219 220 221 protected ClosableIterator preparePropertiesForSubject(Resource r) 222 { 223 Set seen = new HashSet() ; 224 boolean hasTypes = false ; 225 SortedMap tmp1 = new TreeMap() ; 226 SortedMap tmp2 = new TreeMap() ; 227 228 StmtIterator sIter = r.listProperties(); 229 for ( ; sIter.hasNext() ; ) 230 { 231 Property p = sIter.nextStatement().getPredicate() ; 232 if ( seen.contains(p) ) 233 continue ; 234 seen.add(p) ; 235 236 if ( p.equals(RDF.type) ) 237 { 238 hasTypes = true ; 239 continue ; 240 } 241 242 if ( p.getURI().startsWith(RDF.getURI()) || 243 p.getURI().startsWith(RDFS.getURI()) ) 244 { 245 tmp1.put(p.getURI(), p) ; 246 continue ; 247 } 248 249 tmp2.put(p.getURI(), p) ; 250 } 251 sIter.close() ; 252 253 ExtendedIterator eIter = null ; 254 255 if ( hasTypes ) 256 eIter = new SingletonIterator(RDF.type) ; 257 258 ExtendedIterator eIter2 = WrappedIterator.create(tmp1.values().iterator()) ; 259 260 eIter = (eIter == null) ? eIter2 : eIter.andThen(eIter2) ; 261 262 eIter2 = WrappedIterator.create(tmp2.values().iterator()) ; 263 264 eIter = (eIter == null) ? eIter2 : eIter.andThen(eIter2) ; 265 return eIter ; 266 } 267 268 protected boolean skipThisSubject(Resource subj) 269 { 270 return rdfListsAll.contains(subj) || 271 oneRefObjects.contains(subj) ; 272 } 273 274 280 282 protected void startWriting() 283 { 284 allocateDatastructures() ; 285 } 286 287 293 protected void finishWriting() 294 { 295 oneRefObjects.removeAll(oneRefDone); 296 297 for (Iterator leftOverIter = oneRefObjects.iterator(); leftOverIter.hasNext();) 298 { 299 out.println(); 300 if (N3JenaWriter.DEBUG) 301 out.println("# One ref"); 302 allowDeep = false; 304 writeOneGraphNode((Resource) leftOverIter.next()); 305 allowDeep = true; 306 } 307 308 for (Iterator leftOverIter = rdfLists.iterator(); leftOverIter.hasNext();) 311 { 312 Resource r = (Resource) leftOverIter.next(); 313 if (rdfListsDone.contains(r)) 314 continue; 315 out.println(); 316 if (N3JenaWriter.DEBUG) 317 out.println("# RDF List"); 318 319 if (!r.isAnon() || countArcsTo(r) > 0 ) 320 { 321 out.print(formatResource(r)); 323 out.print(" :- "); 324 } 325 writeList(r); 326 out.println(" ."); 327 } 328 329 out.flush(); 332 clearDatastructures() ; 333 } 334 335 336 337 340 protected void writeObjectList(Resource resource, Property property) 341 { 342 348 String propStr = formatProperty(property); 349 350 352 StmtIterator sIter = resource.listProperties(property); 353 Set simple = new HashSet() ; 354 Set complex = new HashSet() ; 355 356 for (; sIter.hasNext();) 357 { 358 Statement stmt = sIter.nextStatement(); 359 RDFNode obj = stmt.getObject() ; 360 if ( isSimpleObject(obj) ) 361 simple.add(obj) ; 362 else 363 complex.add(obj) ; 364 } 365 sIter.close() ; 366 int simpleSize = simple.size() ; 368 int complexSize = complex.size() ; 369 370 372 if ( simple.size() > 0 ) 373 { 374 String padSp = null ; 375 if ((propStr.length()+minGap) <= widePropertyLen) 377 padSp = pad(calcPropertyPadding(propStr)) ; 378 379 if ( doObjectListsAsLists ) 380 { 381 out.print(propStr); 383 out.incIndent(indentObject) ; 384 385 if ( padSp != null ) 386 out.print(padSp) ; 387 else 388 out.println() ; 389 390 for (Iterator iter = simple.iterator(); iter.hasNext();) 391 { 392 RDFNode n = (RDFNode) iter.next(); 393 writeObject(n); 394 395 if (iter.hasNext()) 397 out.print(objectListSep); 398 } 399 400 out.decIndent(indentObject) ; 401 } 402 else 403 { 404 for (Iterator iter = simple.iterator(); iter.hasNext();) 405 { 406 out.print(propStr); 409 out.incIndent(indentObject) ; 410 if ( padSp != null ) 411 out.print(padSp) ; 412 else 413 out.println() ; 414 415 RDFNode n = (RDFNode) iter.next(); 416 writeObject(n); 417 out.decIndent(indentObject) ; 418 419 if (iter.hasNext()) 421 out.println(" ;"); 422 } 423 424 } 425 } 426 430 if (complex.size() > 0) 431 { 432 if ( simple.size() > 0 ) 434 out.println(" ;"); 435 436 int padding = -1 ; 437 String padSp = null ; 438 439 441 int tmp = propStr.length() ; 443 if ((propStr.length()+minGap) <= propertyCol) 445 { 446 padding = calcPropertyPadding(propStr) ; 447 padSp = pad(padding) ; 448 } 449 450 for (Iterator iter = complex.iterator(); iter.hasNext();) 451 { 452 int thisIndent = indentObject ; 453 out.incIndent(thisIndent); 455 out.print(propStr); 456 if ( padSp != null ) 457 out.print(padSp) ; 458 else 459 out.println() ; 460 461 RDFNode n = (RDFNode) iter.next(); 462 writeObject(n); 463 out.decIndent(thisIndent); 464 if ( iter.hasNext() ) 465 out.println(" ;"); 466 } 467 } 468 return; 469 } 470 471 472 private boolean isSimpleObject(RDFNode node) 473 { 474 if (node instanceof Literal) 475 return true ; 476 Resource rObj = (Resource) node; 477 if ( allowDeep && oneRefObjects.contains(rObj) ) 478 return false ; 479 return true ; 480 } 481 482 protected void writeObject(RDFNode node) 483 { 484 if (node instanceof Literal) 485 { 486 writeLiteral((Literal) node); 487 return; 488 } 489 490 Resource rObj = (Resource) node; 491 if ( allowDeep && ! isSimpleObject(rObj)) 492 { 493 oneRefDone.add(rObj); 494 497 out.print("[ "); 500 out.incIndent(2); 501 writePropertiesForSubject(rObj); 502 out.decIndent(2); 503 out.println() ; 504 out.print("]"); 506 508 return ; 510 } 511 512 if (rdfLists.contains(rObj)) 513 if (countArcsTo(rObj) <= 1) 514 { 515 writeList(rObj); 516 return; 517 } 518 519 out.print(formatResource(rObj)); 520 } 521 522 523 524 private void writeList(Resource resource) 527 528 { 529 out.print( "("); 530 out.incIndent(2) ; 531 boolean listFirst = true; 532 for (Iterator iter = rdfListIterator(resource); iter.hasNext();) 533 { 534 if (!listFirst) 535 out.print( " "); 536 listFirst = false; 537 RDFNode n = (RDFNode) iter.next(); 538 writeObject(n) ; 539 } 540 out.print( ")"); 541 out.decIndent(2) ; 542 rdfListsDone.add(resource); 543 544 } 545 546 protected void allocateDatastructures() 548 { 549 rdfLists = new HashSet() ; 550 rdfListsAll = new HashSet() ; 551 rdfListsDone = new HashSet() ; 552 oneRefObjects = new HashSet() ; 553 oneRefDone = new HashSet() ; 554 } 555 556 protected void clearDatastructures() 558 { 559 rdfLists = null ; 560 rdfListsAll = null ; 561 rdfListsDone = null ; 562 oneRefObjects = null ; 563 oneRefDone = null ; 564 } 565 } 566 567 593 | Popular Tags |