1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ 2 3 /* AbiWord 4 * Copyright (c) 2010 GPL. V2+ copyright to AbiSource B.V. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 * 02110-1301 USA. 20 */ 21 22 #ifndef PD_DOCUMENTRDF_H 23 #define PD_DOCUMENTRDF_H 24 25 #include <string> 26 #include <list> 27 #include <map> 28 #include <set> 29 #include "ut_types.h" 30 #include "pt_Types.h" 31 32 #include <boost/shared_ptr.hpp> 33 34 class PD_Document; 35 class pt_PieceTable; 36 class PP_AttrProp; 37 class RDFModel_SPARQLLimited; 38 class pf_Frag; 39 class pf_Frag_Object; 40 class PD_RDFSemanticItem; 41 class FV_View; 42 43 class PD_DocumentRDFMutation; 44 typedef boost::shared_ptr<PD_DocumentRDFMutation> PD_DocumentRDFMutationHandle; 45 class PD_RDFModel; 46 typedef boost::shared_ptr<PD_RDFModel> PD_RDFModelHandle; 47 class PD_DocumentRDF; 48 typedef boost::shared_ptr<PD_DocumentRDF> PD_DocumentRDFHandle; 49 50 51 /** 52 * An RDF URI. This can be thought of as a std::string 53 * like object, but explicit support for namespaces and 54 * other RDF functionality might be added over time. 55 * For example, foaf:name mapping to the foaf URI vocab. 56 * 57 */ 58 class ABI_EXPORT PD_URI 59 { 60 protected: 61 std::string m_value; 62 63 public: 64 PD_URI( const std::string& v = "" ); ~PD_URI()65 virtual ~PD_URI() {} 66 virtual std::string toString() const; 67 int length() const; 68 bool isValid() const; 69 bool operator==(const PD_URI& b) const; 70 bool operator==(const std::string& b) const; 71 bool operator<(const PD_URI& b) const; 72 73 virtual bool read( std::istream& ss ); 74 virtual bool write( std::ostream& ss ) const; 75 76 PD_URI prefixedToURI( PD_RDFModelHandle model ) const; 77 empty()78 bool empty() const { return m_value.empty(); } c_str()79 const char* c_str() const { return m_value.c_str(); } 80 81 }; 82 83 template <class ostream> 84 ostream& operator<<( ostream& ss, PD_URI& uri ) 85 { 86 ss << uri.toString(); 87 return ss; 88 } 89 90 91 92 /** 93 * An RDF Object is either a URI, a bnode, or a Literal value. While inheritance 94 * is not strictly correct for this relation, since the main features of 95 * a PD_URI are to get a string value, if the Object is a literal it can 96 * return it's literal value via toString(). 97 * 98 * The main additions for an Object are the type information of the 99 * literal and also the context if the Object forms part of a triple. 100 * 101 * There are two types for an Object, use getObjectType() to see if it 102 * is a URI, LITERAL, BNODE etc. Use getXSDType() to get the XSD 103 * schema type for the literal. While using getXSDType() for a URI or 104 * BNODE will result in "", the object type is still needed to 105 * differentiate properly between URI and BNodes and makes this 106 * explicit. 107 * 108 */ 109 class ABI_EXPORT PD_Object : public PD_URI 110 { 111 public: 112 enum 113 { 114 OBJECT_TYPE_URI = 1, 115 OBJECT_TYPE_LITERAL, 116 OBJECT_TYPE_BNODE 117 }; 118 119 PD_Object( const std::string& v = "" ); 120 PD_Object( const PD_URI& u ); 121 PD_Object( const std::string& v, int objectType, const std::string& xsdtype = "" ); 122 123 std::string getXSDType() const; 124 bool hasXSDType() const; 125 int getObjectType() const; 126 bool isLiteral() const; 127 bool isURI() const; 128 bool isBNode() const; 129 130 virtual bool read( std::istream& ss ); 131 virtual bool write( std::ostream& ss ) const; 132 133 protected: 134 std::string m_xsdType; 135 std::string m_context; 136 int m_objectType; 137 }; 138 /** 139 * Convenience class for creating Literal values. Note that object 140 * slicing is OK here because there are no local member variables in 141 * this class and the type is explicitly preserved in m_objectType in 142 * the parent class. 143 */ 144 class ABI_EXPORT PD_Literal : public PD_Object 145 { 146 public: 147 PD_Literal( const std::string& v = "", const std::string& xsdtype = "" ); 148 }; 149 150 typedef std::list< PD_URI > PD_URIList; 151 // REQUIRES: ordered, same key can -> many different values 152 typedef std::multimap< PD_URI, PD_Object > POCol; 153 typedef std::list< PD_Object > PD_ObjectList; 154 155 struct PD_URIListCompare : public std::binary_function<PD_URI, PD_URI, bool> { operatorPD_URIListCompare156 bool operator()(PD_URI x, PD_URI y) { return x.toString() < y.toString(); } 157 }; 158 159 160 /** 161 * When iterating over the RDF triples it is nice to have a single 162 * C++ object which represents the while triple. 163 */ 164 class ABI_EXPORT PD_RDFStatement 165 { 166 PD_URI m_subject; 167 PD_URI m_predicate; 168 PD_Object m_object; 169 bool m_isValid; 170 public: 171 PD_RDFStatement(); 172 PD_RDFStatement( PD_RDFModelHandle model, const PD_URI& s, const PD_URI& p, const PD_Object& o ); 173 PD_RDFStatement( const PD_URI& s, const PD_URI& p, const PD_Object& o ); 174 PD_RDFStatement( const std::string& s, const std::string& p, const PD_Object& o ); 175 PD_RDFStatement( const std::string& s, const std::string& p, const PD_Literal& o ); 176 const PD_URI& getSubject() const; 177 const PD_URI& getPredicate() const; 178 const PD_Object& getObject() const; 179 bool isValid() const; 180 std::string toString() const; 181 182 PD_RDFStatement uriToPrefixed( PD_RDFModelHandle model ) const; 183 PD_RDFStatement prefixedToURI( PD_RDFModelHandle model ) const; 184 185 bool operator==(const PD_RDFStatement& b) const; 186 187 }; 188 189 template <class ostream> 190 ostream& operator<<( ostream& ss, const PD_RDFStatement& st ) 191 { 192 ss << st.toString(); 193 return ss; 194 } 195 196 197 198 199 class ABI_EXPORT PD_RDFModelIterator 200 : 201 public std::iterator< std::forward_iterator_tag, PD_RDFStatement > 202 { 203 PD_RDFModelHandle m_model; 204 const PP_AttrProp* m_AP; 205 bool m_end; 206 size_t m_apPropertyNumber; 207 std::string m_subject; 208 POCol m_pocol; 209 POCol::iterator m_pocoliter; 210 PD_RDFStatement m_current; 211 212 void setup_pocol(); 213 214 public: 215 typedef const PD_RDFModelIterator& self_constref; 216 typedef PD_RDFModelIterator& self_reference; 217 typedef PD_RDFModelIterator self_type; 218 219 PD_RDFModelIterator(); 220 ~PD_RDFModelIterator(); 221 PD_RDFModelIterator( PD_RDFModelHandle model, const PP_AttrProp* AP ); 222 223 self_reference operator++(); 224 bool operator==( self_constref other ); 225 PD_RDFModelIterator& operator=( const PD_RDFModelIterator& other ); 226 227 self_type operator++(int) 228 { 229 self_type result( *this ); 230 ++( *this ); 231 return result; 232 } 233 bool operator!=( self_constref other ) 234 { 235 return !operator==(other); 236 } 237 reference operator*() 238 { 239 return m_current; 240 } 241 242 self_reference moveToNextSubject(); 243 void moveToNextSubjectReadPO(); 244 bool moveToNextSubjectHavePOCol(); 245 }; 246 247 248 /** 249 * An RDF Model is an abstract immutable collection of RDF triples. 250 * You can query if the model contains a statement, and navigate 251 * around by supplying one or more parts of a triple. 252 * 253 * Having the RDF Model abstract like this allows slices of the whole 254 * RDF to be returned in various places. For example, to get all the 255 * RDF that is explicitly "related" to a location in the document. 256 * 257 * To make implementing custom models simpler many methods have 258 * defaults which rely on other methods. For example, the getObject() 259 * method simply returns the first object from the getObjects() 260 * method. Many of the default implementations rely on begin() and 261 * end() and simply loop over all the RDF to find the result. Compare 262 * the linear performance of the default to the contant time 263 * performance which might be possible for contains(s,p,o) if the 264 * model uses more knowledge. 265 * 266 * The uriToPrefixed() and prefixedToURI() rely on getUriToPrefix() 267 * returning a suitable prefix map. 268 * 269 * Methods with default implementations remain virtual because a 270 * subclass might have a more efficient method of finding the result 271 * than the default implementation. 272 */ 273 class ABI_EXPORT PD_RDFModel 274 { 275 protected: 276 long m_version; 277 PD_URI front( const PD_URIList& l ) const; 278 PD_Object front( const PD_ObjectList& l ) const; 279 PD_RDFModel(); 280 void incremenetVersion(); 281 282 public: ~PD_RDFModel()283 virtual ~PD_RDFModel() {} 284 virtual PD_ObjectList getObjects( const PD_URI& s, const PD_URI& p ); 285 virtual PD_Object getObject( const PD_URI& s, const PD_URI& p ); 286 virtual PD_URIList getSubjects( const PD_URI& p, const PD_Object& o ); 287 virtual PD_URI getSubject( const PD_URI& p, const PD_Object& o ); 288 virtual PD_URIList getAllSubjects(); 289 virtual POCol getArcsOut( const PD_URI& s ); 290 virtual bool contains( const PD_URI& s, const PD_URI& p, const PD_Object& o ); 291 virtual bool contains( const PD_URI& s, const PD_URI& p ); 292 virtual bool contains( const PD_RDFStatement& st ); 293 virtual long getTripleCount(); 294 295 virtual PD_RDFModelIterator begin() = 0; 296 virtual PD_RDFModelIterator end() = 0; 297 298 typedef std::map< std::string, std::string > stringmap_t; 299 typedef stringmap_t uriToPrefix_t; 300 virtual uriToPrefix_t& getUriToPrefix(); 301 302 303 virtual void dumpModel( const std::string& headerMsg = "dumpModel()" ); 304 305 virtual PD_DocumentRDFMutationHandle createMutation() = 0; 306 virtual std::string uriToPrefixed( const std::string& uri ); 307 virtual std::string prefixedToURI( const std::string& prefixed ); 308 size()309 inline long size() { return getTripleCount(); } empty()310 inline bool empty() { return size() == 0; } 311 getVersion()312 long getVersion() const { return m_version; } 313 314 }; 315 316 class PD_RDFSemanticItem; 317 typedef boost::shared_ptr<PD_RDFSemanticItem> PD_RDFSemanticItemHandle; 318 typedef std::list< PD_RDFSemanticItemHandle > PD_RDFSemanticItems; 319 class PD_RDFContact; 320 typedef boost::shared_ptr<PD_RDFContact > PD_RDFContactHandle; 321 typedef std::list< PD_RDFContactHandle > PD_RDFContacts; 322 class PD_RDFEvent; 323 typedef boost::shared_ptr<PD_RDFEvent > PD_RDFEventHandle; 324 typedef std::list< PD_RDFEventHandle > PD_RDFEvents; 325 class PD_RDFLocation; 326 typedef boost::shared_ptr<PD_RDFLocation > PD_RDFLocationHandle; 327 typedef std::list< PD_RDFLocationHandle > PD_RDFLocations; 328 class PD_RDFSemanticStylesheet; 329 typedef boost::shared_ptr<PD_RDFSemanticStylesheet > PD_RDFSemanticStylesheetHandle; 330 typedef std::list< PD_RDFSemanticStylesheetHandle > PD_RDFSemanticStylesheets; 331 class PD_RDFSemanticItemViewSite; 332 typedef boost::shared_ptr<PD_RDFSemanticItemViewSite> PD_RDFSemanticItemViewSiteHandle; 333 typedef std::list< PD_RDFSemanticItemViewSiteHandle > PD_RDFSemanticItemViewSites; 334 335 // semantic stylesheets 336 #define RDF_SEMANTIC_STYLESHEET_NAME "name" 337 #define RDF_SEMANTIC_STYLESHEET_CONTACT_NAME RDF_SEMANTIC_STYLESHEET_NAME 338 #define RDF_SEMANTIC_STYLESHEET_CONTACT_NICK "nick" 339 #define RDF_SEMANTIC_STYLESHEET_CONTACT_NAME_PHONE "name, phone" 340 #define RDF_SEMANTIC_STYLESHEET_CONTACT_NICK_PHONE "nick, phone" 341 #define RDF_SEMANTIC_STYLESHEET_CONTACT_NAME_HOMEPAGE_PHONE "name, (homepage), phone" 342 #define RDF_SEMANTIC_STYLESHEET_EVENT_NAME RDF_SEMANTIC_STYLESHEET_NAME 343 #define RDF_SEMANTIC_STYLESHEET_EVENT_SUMMARY "summary" 344 #define RDF_SEMANTIC_STYLESHEET_EVENT_SUMMARY_LOCATION "summary, location" 345 #define RDF_SEMANTIC_STYLESHEET_EVENT_SUMMARY_LOCATION_TIMES "summary, location, start date/time" 346 #define RDF_SEMANTIC_STYLESHEET_EVENT_SUMMARY_TIMES "summary, start date/time" 347 #define RDF_SEMANTIC_STYLESHEET_LOCATION_NAME RDF_SEMANTIC_STYLESHEET_NAME 348 #define RDF_SEMANTIC_STYLESHEET_LOCATION_NAME_LATLONG "name, digital latitude, digital longitude" 349 350 /** 351 * @short Base class for C++ objects which represent RDF at a higher level. 352 * @author Ben Martin 353 * 354 */ 355 class ABI_EXPORT PD_RDFSemanticItem 356 { 357 PD_DocumentRDFHandle m_rdf; 358 PD_URI m_context; 359 protected: 360 std::string m_name; 361 PD_URI m_linkingSubject; 362 typedef std::list< std::map< std::string, std::string > > PD_ResultBindings_t; 363 364 virtual std::string getImportFromFileName( const std::string& filename_const, 365 std::list< std::pair< std::string, std::string> > types ) const; 366 virtual std::list< std::pair< std::string, std::string> > getImportTypes() const; 367 368 virtual std::string getExportToFileName( const std::string& filename_const, 369 std::string defaultExtension, 370 std::list< std::pair< std::string, std::string> > types ) const; 371 virtual std::list< std::pair< std::string, std::string> > getExportTypes() const; 372 virtual std::string getDefaultExtension() const; 373 std::string getProperty( std::string subj, std::string pred, std::string defVal ) const; 374 375 public: 376 PD_RDFSemanticItem( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator& it ); 377 virtual ~PD_RDFSemanticItem(); 378 379 PD_DocumentRDFHandle getRDF() const; 380 PD_DocumentRDFMutationHandle createMutation(); 381 382 std::string requestExportFileNameByDialog(); 383 384 385 /** 386 * For an item like a contact, event, location, if there is a 387 * subject, common#idref xml:id triple that can be used to link 388 * into the document content, return that subject node here for 389 * the common base class methods to use. 390 * 391 * For example, in the FOAF vocabulary the ?person node from the 392 * SPARQL query fragment below will be the linkingSubject() 393 * ?person rdf:type foaf:Person 394 */ 395 virtual PD_URI linkingSubject() const; 396 397 398 /** 399 * Given a linking subject, find all the xmlids that are referenced by it 400 * ie, return all ?xmlid from the form: 401 * 402 * ?linkingSubj pkg:idref ?xmlid 403 * 404 */ 405 static std::set< std::string > getXMLIDsForLinkingSubject( PD_DocumentRDFHandle rdf, const std::string& linkingSubj ); 406 407 408 /** 409 * A simple description of the semantic item that can be shown to the user 410 */ 411 virtual std::string name() const; 412 virtual void setName( const std::string& n ); 413 414 /** 415 * Something that can be used on a notebook tab to describe this semantic item 416 * eg, Contact, Event etc. 417 */ 418 virtual std::string getDisplayLabel() const; 419 420 421 /** 422 * A Semantic Item can appear multiple times in a document. For 423 * example, the person Frodo can be referenced 20 times in a short 424 * book review. This method gives all the xmlid values where the 425 * semantic item is referenced in the document. 426 * 427 * The list of xmlid values can in turn be used by 428 * PD_DocumentRDF::getIDRange() and PD_DocumentRDF::getRDFForID() 429 * to inspect or perform actions at the various places the 430 * semanitc item appears in the document. 431 */ 432 virtual std::set< std::string > getXMLIDs() const; 433 434 /** 435 * Create a Widget that can edit the SemanticItem. Note that the 436 * widget will show the data and allow editing of it for the 437 * SemanticItem, but to make changes permenant, the 438 * updateFromEditorData() method must be used. A typical senario 439 * is to add the widget from createEditor to a dialog and when the 440 * user affirms the dialog call updateFromEditorData() to update 441 * the document. 442 * 443 * @see updateFromEditorData() 444 */ 445 virtual void* createEditor() = 0; 446 447 /** 448 * Create a top level dialog allowing the user to edit this semitem 449 */ 450 virtual void showEditorWindow( const PD_RDFSemanticItemHandle & c ); 451 virtual void showEditorWindow( const PD_RDFSemanticItems & cl ); 452 453 /** 454 * Update the SemanticItem from the edited dialog that was created using 455 * createEditor. 456 * 457 * @see createEditor() 458 */ 459 void updateFromEditorData(); 460 virtual void updateFromEditorData( PD_DocumentRDFMutationHandle m ) = 0; 461 462 463 /** 464 * Import the data in iss to the semnatic item. This is used for 465 * D&D Drop events to create a new semnatic item. Subclasses 466 * should set their internal state based on the data in 'iss' and 467 * then call importFromDataComplete() at the end of the method to 468 * update the RDF and insert the semantic item into the document. 469 * 470 * ??? maybe not ??? importFromDataComplete() calls also insert() which links the 471 * ??? semanticItem with the document object m_rdf. 472 */ 473 virtual void importFromData( std::istream& iss, PD_DocumentRDFHandle rdf, PD_DocumentRange * pDocRange = 0 ) = 0; 474 475 /** 476 * Export to a file in whatever format is the most useful for the 477 * semantic item. Prompt for a filename if none is given. 478 */ 479 virtual void exportToFile( const std::string& filename = "" ) const = 0; 480 481 /** 482 * Import from a file in whatever format is the most useful for the 483 * semantic item. The default implemenation uses importFromData() to perform this import, 484 * so all a subclass needs to do is override the getImportTypes() method to 485 * let an import dialog know what types are OK. 486 */ 487 virtual void importFromFile( const std::string& filename = "" ); 488 489 490 /** 491 * Create a SemanticItem subclass using its name from 492 * getClassNames(). Useful for menus and other places that want to 493 * allow the user to create new SemanticItem Objects. 494 */ 495 static PD_RDFSemanticItemHandle createSemanticItem( PD_DocumentRDFHandle rdf, const std::string& semanticClass ); 496 static PD_RDFSemanticItemHandle createSemanticItem( PD_DocumentRDFHandle rdf, 497 PD_ResultBindings_t::iterator it, 498 const std::string& semanticClass ); 499 500 /** 501 * Gets a list of SemanticItem subclasses that can be created. 502 * Any of the strings in the return value can be created using 503 * createSemanticItem(). 504 * 505 * @see createSemanticItem() 506 */ 507 static std::list< std::string > getClassNames(); 508 509 510 /** 511 * Insert a reference to this semantic item at the cursor location of pView 512 * 513 * This should only be called after creating a new sem item with 514 * createSemanticItem(). 515 */ 516 std::pair< PT_DocPosition, PT_DocPosition > insert( PD_DocumentRDFMutationHandle m, FV_View* pView ); 517 std::pair< PT_DocPosition, PT_DocPosition > insert( FV_View* pView ); 518 519 520 virtual void setupStylesheetReplacementMapping( std::map< std::string, std::string >& m ); 521 522 523 /** 524 * Unambiguiously find a stylesheet by its UUID. The sheet can 525 * be either user or system as long as it has the uuid you want. 526 */ 527 PD_RDFSemanticStylesheetHandle findStylesheetByUuid(const std::string &uuid) const; 528 529 /** 530 * Find a user/system stylesheet by name. 531 * sheetType is one of TYPE_SYSTEM/TYPE_USER. 532 * n is the name of the stylesheet you want. 533 */ 534 PD_RDFSemanticStylesheetHandle findStylesheetByName(const std::string &sheetType, const std::string &n) const; 535 /** 536 * Find a user/system stylesheet by name. 537 * ssl is either stylesheets() or userStylesheets() 538 * n is the name of the stylesheet you want. 539 */ 540 PD_RDFSemanticStylesheetHandle findStylesheetByName(const PD_RDFSemanticStylesheets& ssl, const std::string &n) const; 541 542 /** 543 * Get the default stylesheet for this subclass of Semantic Item. 544 * 545 * If you want to know which stylesheet is in use by a particular 546 * reference to a semantic item, use KoRdfSemanticItemViewSite::stylesheet() 547 * 548 * @see KoRdfSemanticItemViewSite 549 * @see KoRdfSemanticItemViewSite::stylesheet() 550 */ 551 PD_RDFSemanticStylesheetHandle defaultStylesheet() const; 552 553 /** 554 * Get the system semantic stylesheets that are supported for this 555 * particular semantic item subclass. 556 */ 557 virtual PD_RDFSemanticStylesheets stylesheets() const = 0; 558 virtual std::string className() const = 0; 559 560 enum RelationType 561 { 562 RELATION_FOAF_KNOWS = 1 563 }; 564 void relationAdd( PD_RDFSemanticItemHandle si, RelationType rt ); 565 PD_RDFSemanticItems relationFind( RelationType rt ); 566 567 protected: 568 569 std::pair< PT_DocPosition, PT_DocPosition > insertTextWithXMLID( const std::string& textconst, 570 const std::string& xmlid ); 571 572 /** 573 * The importFromData() method can use this method to finish an 574 * import. Text is also inserted into the document to show the 575 * user the new semantic object. The semanticObjectAdded signal is 576 * emitted so that UI elements have a chance to update themselves to 577 * reflect the newly added SemanticItem in the document. 578 * 579 * This method uses createEditor() followed by 580 * updateFromEditorData() to actually put the RDF triples into the 581 * store. So a subclass does not have to explicitly handle the 582 * import if it can present a GUI to edit itself. The GUI is not 583 * shown to the user. 584 * 585 * Basically a subclass reads the data in importFromData and sets 586 * local member variables from it. Then calls 587 * importFromDataComplete() which makes an editor using the member 588 * variables and commits the editor which in turn updates the RDF 589 * for the document. 590 */ 591 virtual void importFromDataComplete( std::istream& iss, 592 PD_DocumentRDFHandle rdf, 593 PD_DocumentRDFMutationHandle m, 594 PD_DocumentRange * pDocRange = 0 ); 595 596 std::string bindingAsString( PD_ResultBindings_t::iterator& it, const std::string k ); 597 std::string optionalBindingAsString( PD_ResultBindings_t::iterator& it, const std::string k ); 598 599 PD_URI& handleSubjectDefaultArgument( PD_URI& subj ); 600 601 /** 602 * Return the graph context that contains this SematicItem's Rdf 603 * statements. Used by the updateTriple()s to remove and add 604 * updated information. The default is the manifest.rdf file. 605 */ 606 virtual PD_URI context() const; 607 608 /** 609 * Ensure the Rdf Type of the subject or linkingSubject() by 610 * default is what you want After this method, the Rdf will have 611 * the following: linkingSubject() rdf:type type 612 */ 613 void setRDFType(PD_DocumentRDFMutationHandle m, const std::string& type, PD_URI subj = PD_URI()); 614 void setRDFType(const std::string& type, PD_URI subj = PD_URI()); 615 616 617 /** 618 * When a subclass wants to update a triple in the RDF store 619 * to reflect a change, for example, the phone number of a 620 * contact, it should call here to set toModify = newValue. 621 * 622 * This is done both in the C++ objects and the Rdf model. 623 * The RDF will be changed from 624 * linkingSubject() predString toModify 625 * to 626 * linkingSubject() predString newValue 627 * 628 * Note that rounding errors and other serialization issues that 629 * crop up are handled by these methods, so you should try very 630 * hard not to directly update the PD_RDFModelHandle outside these 631 * methods. 632 * 633 * Note that if you do not supply a mutationhandle the method to 634 * create/commit a mutation for you. 635 */ 636 void updateTriple( PD_DocumentRDFMutationHandle m, std::string& toModify, const std::string& newValue, const PD_URI& predString ); 637 void updateTriple( PD_DocumentRDFMutationHandle m, time_t& toModify, time_t newValue, const PD_URI& predString ); 638 void updateTriple( PD_DocumentRDFMutationHandle m, double& toModify, double newValue, const PD_URI& predString ); 639 void updateTriple( PD_DocumentRDFMutationHandle m, double& toModify, double newValue, const PD_URI& predString, PD_URI linkingSubject ); 640 641 void updateTriple( std::string& toModify, const std::string& newValue, const PD_URI& predString ); 642 void updateTriple( time_t& toModify, time_t newValue, const PD_URI& predString ); 643 void updateTriple( double& toModify, double newValue, const PD_URI& predString ); 644 645 /** 646 * Create a bnode with a uuid 647 */ 648 PD_URI createUUIDNode(); 649 650 651 protected: 652 /** 653 * The updateTriple() methods all call remove() then add() to 654 * perform their work. These lower level functions accept PD_URI 655 * to remove/add. Note that corner cases like "double" values are 656 * explicitly handled by these methods. For example, at times a 657 * double will undergo some rounding during serialization, so you 658 * can not just call mutation->remove() because you have to take 659 * rounding errors into account for the value you are intending to 660 * remove. 661 */ 662 void updateTriple_remove( PD_DocumentRDFMutationHandle m, 663 const PD_URI& toModify, 664 const PD_URI& predString, 665 const PD_URI& explicitLinkingSubject ); 666 667 /** 668 * After updateTriple() calls remove() it can set toModify to the 669 * new value and call this method to add the new value to the RDF 670 * store. 671 */ 672 void updateTriple_add( PD_DocumentRDFMutationHandle m, 673 const PD_URI& toModify, 674 const PD_URI& predString, 675 const PD_URI& explicitLinkingSubject ); 676 677 }; 678 679 680 681 class ABI_EXPORT PD_RDFContact : public PD_RDFSemanticItem 682 { 683 protected: 684 std::string m_nick; 685 std::string m_email; 686 std::string m_homePage; 687 std::string m_imageUrl; 688 std::string m_phone; 689 std::string m_jabberID; 690 691 virtual std::list< std::pair< std::string, std::string> > getImportTypes() const; 692 virtual std::list< std::pair< std::string, std::string> > getExportTypes() const; 693 virtual std::string getDefaultExtension() const; 694 695 public: 696 PD_RDFContact( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator& it ); 697 virtual ~PD_RDFContact(); 698 699 virtual void importFromData( std::istream& iss, PD_DocumentRDFHandle rdf, PD_DocumentRange * pDocRange = 0 ); 700 virtual void exportToFile( const std::string& filename = "" ) const; 701 virtual std::string getDisplayLabel() const; 702 virtual void setupStylesheetReplacementMapping( std::map< std::string, std::string >& m ); 703 virtual PD_RDFSemanticStylesheets stylesheets() const; 704 virtual std::string className() const; 705 }; 706 707 708 class ABI_EXPORT PD_RDFEvent : public PD_RDFSemanticItem 709 { 710 protected: 711 std::string m_uid; 712 std::string m_summary; 713 std::string m_location; 714 std::string m_desc; 715 time_t m_dtstart; 716 time_t m_dtend; 717 718 virtual std::list< std::pair< std::string, std::string> > getImportTypes() const; 719 virtual std::list< std::pair< std::string, std::string> > getExportTypes() const; 720 virtual std::string getDefaultExtension() const; 721 722 public: 723 PD_RDFEvent( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator& it ); 724 virtual ~PD_RDFEvent(); 725 726 virtual void importFromData( std::istream& iss, PD_DocumentRDFHandle rdf, PD_DocumentRange * pDocRange = 0 ); 727 virtual void exportToFile( const std::string& filename = "" ) const; 728 virtual std::string getDisplayLabel() const; 729 virtual void setupStylesheetReplacementMapping( std::map< std::string, std::string >& m ); 730 virtual PD_RDFSemanticStylesheets stylesheets() const; 731 virtual std::string className() const; 732 }; 733 734 735 class ABI_EXPORT PD_RDFLocation : public PD_RDFSemanticItem 736 { 737 protected: 738 std::string m_uid; 739 std::string m_desc; 740 double m_dlat; 741 double m_dlong; 742 PD_Object m_joiner; 743 bool m_isGeo84; 744 745 virtual std::list< std::pair< std::string, std::string> > getImportTypes() const; 746 virtual std::list< std::pair< std::string, std::string> > getExportTypes() const; 747 virtual std::string getDefaultExtension() const; 748 749 public: 750 PD_RDFLocation( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator& it, bool isGeo84 = false ); 751 virtual ~PD_RDFLocation(); 752 753 virtual void importFromData( std::istream& iss, PD_DocumentRDFHandle rdf, PD_DocumentRange * pDocRange = 0 ); 754 virtual void exportToFile( const std::string& filename = "" ) const; 755 virtual std::string getDisplayLabel() const; 756 virtual std::set< std::string > getXMLIDs() const; 757 virtual void setupStylesheetReplacementMapping( std::map< std::string, std::string >& m ); 758 virtual PD_RDFSemanticStylesheets stylesheets() const; 759 virtual std::string className() const; 760 }; 761 762 763 /** 764 * @short A stylesheet that knows how to format a given PD_RDFSemanticItem 765 * 766 * If you are looking to apply a stylesheet you should use the PD_RDFSemanticItemViewSite 767 * class. For example: 768 * 769 * PD_RDFSemanticItemViewSite vs( h_semitem, xmlid ); 770 * vs.applyStylesheet( pView, h_stylesheet ); 771 * 772 * @author Ben Martin 773 * @see PD_DocumentRDF 774 * @see PD_RDFSemanticItem 775 */ 776 class ABI_EXPORT PD_RDFSemanticStylesheet 777 { 778 std::string m_uuid; 779 std::string m_name; 780 std::string m_templateString; 781 std::string m_type; 782 bool m_isMutable; 783 protected: 784 785 // Restrict who can make us 786 friend class PD_RDFSemanticItem; 787 friend class PD_RDFLocation; 788 friend class PD_RDFContact; 789 friend class PD_RDFEvent; 790 friend class PD_RDFSemanticItemViewSite; 791 792 PD_RDFSemanticStylesheet( const std::string &uuid, 793 const std::string &name, 794 const std::string &templateString, 795 const std::string &type = "System", 796 bool isMutable = false); 797 798 /** 799 * Only called from PD_RDFSemanticItemViewSite, this method 800 * actually applies the stylesheet to a specific reference to a 801 * semantic item in the document. 802 */ 803 void format( PD_RDFSemanticItemHandle sob, FV_View* pView, const std::string& xmlid = "" ); 804 805 public: 806 807 virtual ~PD_RDFSemanticStylesheet(); 808 static std::string stylesheetTypeSystem(); 809 static std::string stylesheetTypeUser(); 810 811 std::string uuid() const; 812 std::string name() const; 813 std::string templateString() const; 814 std::string type() const; 815 bool isMutable() const; 816 }; 817 818 819 /** 820 * @short Handling a specific reference to a semantic item in the document text. 821 * @author Ben Martin 822 * 823 * There can be many references to a single PD_RDFSemanticItem in a 824 * document. One can consider PD_RDFSemanticItem to be the model and 825 * this class the view/controller (delegate). 826 * 827 * For example: 828 * foaf pkg:idref frodo1 829 * foaf pkg:idref frodo2 830 * 831 * the foaf/contact data is the PD_RDFSemanticItem (model) and each 832 * xml:id, the frodo1 and frodo2 above, are PD_RDFSemanticItemViewSite instances. 833 * This class allows different stylesheets to offer different 834 * formatting for each presentation of the same PD_RDFSemanticItem 835 * (model). 836 */ 837 class ABI_EXPORT PD_RDFSemanticItemViewSite 838 { 839 std::string m_xmlid; 840 PD_RDFSemanticItemHandle m_semItem; 841 842 public: 843 /** 844 * Performing actions on a specific reference to a semantic item in the document. 845 */ 846 PD_RDFSemanticItemViewSite( PD_RDFSemanticItemHandle si, const std::string &xmlid ); 847 PD_RDFSemanticItemViewSite( PD_RDFSemanticItemHandle si, PT_DocPosition pos ); 848 ~PD_RDFSemanticItemViewSite(); 849 850 /** 851 * The stylesheet that has been set for this view site 852 */ 853 PD_RDFSemanticStylesheetHandle stylesheet() const; 854 855 /** 856 * If there is a stylesheet set for this view site it is forgotten 857 * and the reference can be freely edited by the user 858 */ 859 void disassociateStylesheet(); 860 861 /** 862 * Apply a stylesheet for the semantic item. 863 * Note that the setting is rememebered for this site too. 864 * 865 * The application can be done separately using the setStylesheetWithoutReflow() 866 * and reflowUsingCurrentStylesheet() methods. Performing the stylesheet 867 * application in two parts is convenient if you are applying a stylesheet to many 868 * semantic items at once, or to all the locations in the document which reference 869 * a single semanti item. 870 * 871 * @see setStylesheetWithoutReflow() 872 * @see reflowUsingCurrentStylesheet() 873 */ 874 void applyStylesheet( FV_View* pView, PD_RDFSemanticStylesheetHandle ss ); 875 876 /** 877 * Remember that a specific stylesheet should be applied for this 878 * semantic item. No reflow of the document is performed and thus 879 * no layout or user visible changes occur. 880 * 881 * @see applyStylesheet() 882 */ 883 void setStylesheetWithoutReflow( PD_RDFSemanticStylesheetHandle ss ); 884 885 /** 886 * Reflow the text that shows the user this semantic item in the 887 * document. 888 * 889 * @see applyStylesheet() 890 */ 891 void reflowUsingCurrentStylesheet( FV_View* pView ); 892 893 /** 894 * Select this view of the semantic item in the document. 895 */ 896 void select( FV_View* pView ); 897 898 private: 899 900 /** 901 * This is similar to the linkingSubject() used by 902 * PD_RDFSemanticItem in that you have: 903 * 904 * linkingSubject() common#idref xml:id 905 * 906 * but metadata about the site at xml:id is stored as properties 907 * off the PD_RDFSemanticItemViewSite::linkingSubject() subject. 908 * 909 * The difference between this linkingSubject() and 910 * PD_RDFSemanticItem is that this is for RDF describing a single 911 * xml:id site in the document, the 912 * PD_RDFSemanticItem::linkingSubject() is the model for the 913 * semanitc item itself which can be referenced by many xml:id 914 * sites. 915 */ 916 PD_URI linkingSubject() const; 917 918 /** 919 * Convenience method to get a specific property from the Rdf 920 * model. There should be either zero or only one value for X in 921 * the triple: 922 * 923 * linkingSubject(), prop, X 924 * 925 * if the property does not exist defval is returned. 926 */ 927 std::string getProperty(const std::string &prop, const std::string &defval) const; 928 /** 929 * Set the single value for the Rdf predicate prop. 930 * @see getProperty() 931 */ 932 void setProperty(const std::string &prop, const std::string &v); 933 934 /** 935 * Convenience method to select a range in the document view 936 */ 937 void selectRange( FV_View* pView, std::pair< PT_DocPosition, PT_DocPosition > range ); 938 939 }; 940 941 942 943 /** 944 * Insert a reference to a semenatic item 945 */ 946 ABI_EXPORT std::pair< PT_DocPosition, PT_DocPosition > runInsertReferenceDialog( FV_View* pView ); 947 ABI_EXPORT void runSemanticStylesheetsDialog( FV_View* pView ); 948 949 950 class ABI_EXPORT PD_SemanticItemFactory 951 { 952 public: 953 typedef std::list< std::map< std::string, std::string > > PD_ResultBindings_t; ~PD_SemanticItemFactory()954 virtual ~PD_SemanticItemFactory() {} 955 virtual PD_RDFContact* createContact( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator it ) = 0; 956 virtual PD_RDFEvent* createEvent( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator it ) = 0; 957 virtual PD_RDFLocation* createLocation( PD_DocumentRDFHandle rdf, PD_ResultBindings_t::iterator it, 958 bool isGeo84 = false ) = 0; 959 }; 960 961 class ABI_EXPORT PD_RDFDialogs 962 { 963 public: ~PD_RDFDialogs()964 virtual ~PD_RDFDialogs() {} 965 virtual void runSemanticStylesheetsDialog( FV_View* pView ) = 0; 966 virtual std::pair< PT_DocPosition, PT_DocPosition > runInsertReferenceDialog( FV_View* pView ) = 0; 967 }; 968 969 970 971 /** 972 * The RDF associated with a document. 973 * 974 * The RDFModel interface can be used to query all the RDF for this 975 * document. Use createMutation() to create an object which allows 976 * you to update the RDF in batch. 977 * 978 * To find the RDF which is associated with an element use 979 * getRDFAtPosition() and getRDFForID() which return a submodel. 980 * 981 */ 982 class ABI_EXPORT PD_DocumentRDF : public PD_RDFModel 983 { 984 friend class PD_DocumentRDFMutation; 985 friend class RDFModel_SPARQLLimited; 986 friend class PD_RDFMutation_XMLIDLimited; 987 friend class PD_RDFSemanticItem; 988 989 public: 990 explicit PD_DocumentRDF( PD_Document* doc ); 991 virtual ~PD_DocumentRDF(); 992 993 UT_Error setupWithPieceTable(); 994 995 /** 996 * Does this document have any semantic items like contacts, events etc. 997 */ 998 bool haveSemItems() const; 999 1000 // PD_RDFModel methods... 1001 virtual PD_ObjectList getObjects( const PD_URI& s, const PD_URI& p ); 1002 virtual PD_URIList getSubjects( const PD_URI& p, const PD_Object& o ); 1003 virtual PD_URIList getAllSubjects(); 1004 virtual POCol getArcsOut( const PD_URI& s ); 1005 virtual bool contains( const PD_URI& s, const PD_URI& p, const PD_Object& o ); 1006 virtual bool contains( const PD_RDFStatement& st ); 1007 virtual long getTripleCount(); 1008 virtual PD_RDFModelIterator begin(); 1009 virtual PD_RDFModelIterator end(); 1010 virtual void dumpModel( const std::string& headerMsg = "dumpModel()" ); 1011 virtual PD_DocumentRDFMutationHandle createMutation(); 1012 1013 1014 void handleCollabEvent( gchar** szAtts, gchar** szProps ); 1015 1016 PD_RDFModelHandle getRDFAtPosition( PT_DocPosition pos ); 1017 PD_RDFModelHandle getRDFForID( const std::string& xmlid ); 1018 1019 std::list< pf_Frag_Object* > getObjectsInScopeOfTypesForRange( 1020 std::set< PTObjectType > objectTypes, 1021 std::pair< PT_DocPosition, PT_DocPosition > range ); 1022 std::set< std::string >& addXMLIDsForObjects( std::set< std::string >& ret, std::list< pf_Frag_Object* > objectList ); 1023 PT_DocPosition addXMLIDsForBlockAndTableCellForPosition( std::set< std::string >& col, PT_DocPosition pos ); 1024 1025 1026 void addRDFForID( const std::string& xmlid, PD_DocumentRDFMutationHandle& m ); 1027 std::set< std::string >& addRelevantIDsForPosition( std::set< std::string >& ret, 1028 PT_DocPosition pos ); 1029 std::set< std::string >& addRelevantIDsForRange( std::set< std::string >& ret, 1030 PD_DocumentRange* range ); 1031 std::set< std::string >& addRelevantIDsForRange( std::set< std::string >& ret, 1032 std::pair< PT_DocPosition, PT_DocPosition > range ); 1033 1034 std::set< std::string >& getAllIDs( std::set< std::string >& ret ); 1035 std::pair< PT_DocPosition, PT_DocPosition > getIDRange( const std::string& xmlid ) const; 1036 1037 1038 PD_RDFModelHandle createRestrictedModelForXMLIDs( const std::string& writeID, 1039 const std::set< std::string >& xmlids ); 1040 PD_RDFModelHandle createRestrictedModelForXMLIDs( const std::set< std::string >& xmlids ); 1041 1042 virtual void maybeSetDocumentDirty(); 1043 1044 // testing methods... 1045 void runMilestone2Test(); 1046 void runMilestone2Test2(); 1047 void dumpObjectMarkersFromDocument(); 1048 void runPlay(); 1049 1050 static std::string getSPARQL_LimitedToXMLIDList( const std::set< std::string >& xmlids, 1051 const std::string& extraPreds = "" ); 1052 1053 std::string makeLegalXMLID( const std::string& s ); 1054 void relinkRDFToNewXMLID( const std::string& oldxmlid, const std::string& newxmlid, bool deepCopyRDF = false ); 1055 1056 PD_RDFModelHandle createScratchModel(); 1057 1058 static PD_URI getManifestURI(); 1059 1060 PD_RDFSemanticItems getAllSemanticObjects( const std::string& classRestriction = "" ); 1061 PD_RDFSemanticItems getSemanticObjects( const std::set< std::string >& xmlids ); 1062 PD_RDFContacts getContacts( PD_RDFModelHandle alternateModel = PD_RDFModelHandle((PD_RDFModel*)0) ); 1063 PD_RDFEvents getEvents( PD_RDFModelHandle alternateModel = PD_RDFModelHandle((PD_RDFModel*)0) ); 1064 PD_RDFLocations getLocations( PD_RDFModelHandle alternateModel = PD_RDFModelHandle((PD_RDFModel*)0) ); 1065 void selectXMLIDs( const std::set< std::string >& xmlids, FV_View* pView = 0 ) const; 1066 1067 1068 void showEditorWindow( const PD_RDFSemanticItems& cl ); 1069 1070 1071 // GTK, win32, osx, whatever backends can call this method to allow the correct 1072 // subclasses to be made for the runtime environment. 1073 static void setSemanticItemFactory( PD_SemanticItemFactory* f ); 1074 static void setRDFDialogs( PD_RDFDialogs* d ); 1075 1076 static PD_SemanticItemFactory *getSemanticItemFactory(); 1077 static PD_RDFDialogs *getRDFDialogs(); 1078 1079 protected: 1080 PD_Document* m_doc; 1081 private: 1082 static PD_SemanticItemFactory *s_SemanticItemFactory; 1083 static PD_RDFDialogs *s_RDFDialogs; 1084 PT_AttrPropIndex m_indexAP; 1085 bool m_haveSemItems; 1086 1087 PD_Document* getDocument(void) const; 1088 pt_PieceTable* getPieceTable(void) const; 1089 void setIndexAP( PT_AttrPropIndex idx ); 1090 PT_AttrPropIndex getIndexAP(void) const; 1091 virtual const PP_AttrProp* getAP(void); 1092 virtual UT_Error setAP( PP_AttrProp* newAP ); 1093 virtual bool isStandAlone() const; 1094 1095 std::set< std::string >& priv_addRelevantIDsForPosition( std::set< std::string >& ret, 1096 PT_DocPosition pos, 1097 PT_DocPosition searchBackThisFar = 0 ); 1098 1099 protected: 1100 PD_ObjectList& apGetObjects( const PP_AttrProp* AP, PD_ObjectList& ret, const PD_URI& s, const PD_URI& p ); 1101 PD_URIList& apGetSubjects( const PP_AttrProp* AP, PD_URIList& ret, const PD_URI& p, const PD_Object& o ); 1102 PD_URIList& apGetAllSubjects( const PP_AttrProp* AP, PD_URIList& ret ); 1103 POCol& apGetArcsOut( const PP_AttrProp* AP, POCol& ret, const PD_URI& s ); 1104 bool apContains( const PP_AttrProp* AP, const PD_URI& s, const PD_URI& p, const PD_Object& o ); 1105 void apDumpModel( const PP_AttrProp* AP, const std::string& headerMsg ); 1106 1107 void updateHaveSemItemsCache(); 1108 1109 private: 1110 PD_RDFLocations& addLocations( PD_RDFLocations& ret, 1111 bool isGeo84, 1112 const std::string sparql, 1113 PD_RDFModelHandle alternateModel ); 1114 }; 1115 1116 1117 /** 1118 * Changes to the document RDF are handled with this class. Changes 1119 * made to the mutation are not reflected in the document RDF right 1120 * away but must be committed first. You can only have a single commit 1121 * or rollback for any instance of PD_DocumentRDFMutation. If you 1122 * commit and want to make another change to the document RDF, create 1123 * another PD_DocumentRDFMutation object. 1124 * 1125 * Because changing the document RDF uses the piece table and AttrProp 1126 * values, it is (relatively) expensive to mutate RDF. Using this 1127 * class a collection of changes can be built up and performed in a 1128 * single operation. 1129 * 1130 * By default the object will commit() when it is destroyed. Thus the 1131 * normal usage pattern is to get a PD_DocumentRDFMutationHandle smart 1132 * pointer from the DocumentRDF, call add() and/or remove() and then 1133 * let the PD_DocumentRDFMutationHandle run out of scope to commit 1134 * your changes. Of course, use rollback() if you want to abandon your 1135 * mutations. 1136 * 1137 * This class also handles notifying the local AbiCollab of updates 1138 * and any RDF change requests that come in from other abiword 1139 * instances. 1140 * 1141 * On an implementation note: the public API add() and remove() 1142 * maintain two internal AttrProp tables; the add and remove 1143 * collections. These internal AttrProp tables are modified using 1144 * apAdd() and apRemove(). A single add() will use apAdd() to add the 1145 * change to the add collection and apRemove() to remove it from the 1146 * remove collection. Thus having the ap prefixed methods is very 1147 * useful for implementing the public API. 1148 * 1149 * When commit() is called, the add/remove changes are made permanent 1150 * using handleAddAndRemove(). The add/remove are then combined into a 1151 * single AttrProp and sent via a Change Record CR. AbiCollab will 1152 * propergate the CR to other abiword instances and the collab code 1153 * knows to send that AttrProp back to the RDF code through 1154 * handleCollabEvent(). Inside of handleCollabEvent() a speical flag 1155 * is set so that we commit the changes but do not propergate them 1156 * again via a CR (thus avoiding a never ending loop). 1157 */ 1158 class ABI_EXPORT PD_DocumentRDFMutation 1159 { 1160 friend class PD_DocumentRDF; 1161 friend class RDFModel_XMLIDLimited; 1162 1163 protected: 1164 PD_DocumentRDF* m_rdf; ///< DocumentRDF we are changing 1165 bool m_rolledback; ///< Should we rollback 1166 bool m_committed; ///< Only commit() once. 1167 bool m_handlingAbiCollabNotification; ///< If we are handling a remote CR 1168 PP_AttrProp* m_pAP; ///< AP that is changed incrementally (deprecated) 1169 PP_AttrProp* m_crRemoveAP; ///< Triples to remove during commit() 1170 PP_AttrProp* m_crAddAP; ///< Triples to add during commit() 1171 1172 1173 1174 bool apAdd( PP_AttrProp* AP, const PD_URI& s, const PD_URI& p, const PD_Object& o ); 1175 void apRemove( PP_AttrProp*& AP, const PD_URI& s, const PD_URI& p, const PD_Object& o ); 1176 UT_Error handleAddAndRemove( PP_AttrProp* add, PP_AttrProp* remove ); 1177 1178 PD_DocumentRDFMutation( PD_DocumentRDF* rdf ); 1179 1180 public: 1181 1182 virtual ~PD_DocumentRDFMutation(); 1183 virtual void handleCollabEvent( gchar** szAtts, gchar** szProps ); 1184 1185 /** 1186 * @return false of the triple could not be added. 1187 */ 1188 virtual bool add( const PD_URI& s, const PD_URI& p, const PD_Object& o ); 1189 virtual bool add( const PD_URI& s, const PD_URI& p, const PD_Object& o, const PD_URI& context ); 1190 virtual void remove( const PD_URI& s, const PD_URI& p, const PD_Object& o ); 1191 void remove( const PD_URI& s, const PD_URI& p, const PD_URI& o ); 1192 bool add( const PD_RDFStatement& st ); 1193 void remove( const PD_RDFStatement& st ); 1194 int add( PD_RDFModelHandle model ); 1195 void remove( const std::list< PD_RDFStatement >& sl ); 1196 void remove( const PD_URI& s, const PD_URI& p ); 1197 1198 PD_URI createBNode(); 1199 1200 virtual UT_Error commit(); 1201 virtual void rollback(); 1202 }; 1203 1204 1205 1206 class ABI_EXPORT RDFAnchor 1207 { 1208 bool m_isEnd; 1209 std::string m_xmlid; 1210 1211 void setup( const PP_AttrProp* pAP ); 1212 1213 public: 1214 RDFAnchor( const PP_AttrProp* pAP ); 1215 RDFAnchor( PD_Document* pDoc, PT_AttrPropIndex api ); 1216 RDFAnchor( PD_Document* doc, pf_Frag* pf ); 1217 bool isEnd(); 1218 std::string getID(); 1219 }; 1220 1221 1222 #endif 1223