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