1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rdf_concepts.c - Nodes representing concepts from the RDF Model
4  *
5  * Copyright (C) 2000-2008, David Beckett http://www.dajobe.org/
6  * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/
7  *
8  * This package is Free Software and part of Redland http://librdf.org/
9  *
10  * It is licensed under the following three licenses as alternatives:
11  *   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12  *   2. GNU General Public License (GPL) V2 or any newer version
13  *   3. Apache License, V2.0 or any newer version
14  *
15  * You may not use this file except in compliance with at least one of
16  * the above three licenses.
17  *
18  * See LICENSE.html or LICENSE.txt at the top of this package for the
19  * complete terms and further detail along with the license texts for
20  * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21  *
22  *
23  */
24 
25 
26 
27 #ifdef HAVE_CONFIG_H
28 #include <rdf_config.h>
29 #endif
30 
31 #ifdef WIN32
32 #include <win32_rdf_config.h>
33 #endif
34 
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdarg.h>
38 
39 #ifdef HAVE_STDLIB_H
40 #include <stdlib.h>
41 #endif
42 
43 #include <redland.h>
44 #include <rdf_node.h>
45 
46 #ifndef STANDALONE
47 
48 /* FIXME: All the stuff here and in rdf_concepts.h should be machine
49  * generated from the schemas but there is a catch-22 here - can't do
50  * it without representing it
51  */
52 
53 
54 /* TAKE CARE: Tokens != Labels */
55 
56 /* Tokens used by the RDF world */
57 static const char* const librdf_concept_tokens[LIBRDF_CONCEPT_LAST+1]={
58   /* RDF M&S */
59   "Alt", "Bag", "Property", "Seq", "Statement", "object", "predicate", "subject", "type", "value", "li",
60   "RDF", "Description",
61   "aboutEach", "aboutEachPrefix",
62   /* all new in RDF/XML revised */
63   "nodeID",
64   "List", "first", "rest", "nil",
65   "XMLLiteral",
66 
67   /* RDF S */
68   "Class", "ConstraintProperty", "ConstraintResource", "Container", "ContainerMembershipProperty", "Literal", "Resource", "comment", "domain", "isDefinedBy", "label", "range", "seeAlso", "subClassOf", "subPropertyOf",
69 
70   /* RDF 1.1 */
71   "HTML", "langString"
72 };
73 
74 
75 static const unsigned char * const librdf_concept_ms_namespace=(const unsigned char *)"http://www.w3.org/1999/02/22-rdf-syntax-ns#";
76 static const unsigned char * const librdf_concept_schema_namespace=(const unsigned char *)"http://www.w3.org/2000/01/rdf-schema#";
77 
78 /**
79  * librdf_init_concepts:
80  * @world: redland world object
81  *
82  * INTERNAL - Initialise the concepts module.
83  *
84  **/
85 void
librdf_init_concepts(librdf_world * world)86 librdf_init_concepts(librdf_world *world)
87 {
88   int i;
89 
90   /* Create the Unique URI objects */
91   world->concept_ms_namespace_uri = librdf_new_uri(world, librdf_concept_ms_namespace);
92   world->concept_schema_namespace_uri = librdf_new_uri(world, librdf_concept_schema_namespace);
93   world->xsd_namespace_uri = librdf_new_uri(world, raptor_xmlschema_datatypes_namespace_uri);
94   if(!world->concept_ms_namespace_uri ||
95      !world->concept_schema_namespace_uri ||
96      !world->xsd_namespace_uri)
97     LIBRDF_FATAL1(world, LIBRDF_FROM_CONCEPTS, "Out of memory creating namespace URIs");
98 
99   /* Create arrays for the M&S and Schema resource nodes and uris */
100   world->concept_uris = LIBRDF_CALLOC(librdf_uri**, LIBRDF_CONCEPT_LAST + 1,
101                                       sizeof(librdf_uri*));
102   world->concept_resources = LIBRDF_CALLOC(librdf_node**, LIBRDF_CONCEPT_LAST + 1,
103                                            sizeof(librdf_node*));
104   if(!world->concept_uris || !world->concept_resources)
105     LIBRDF_FATAL1(world, LIBRDF_FROM_CONCEPTS, "Out of memory creating node/uri arrays");
106 
107   /* Create the M&S and Schema resource nodes */
108   for (i = 0; i <= LIBRDF_CONCEPT_LAST; i++) {
109     librdf_uri* ns_uri = (LIBRDF_CONCEPT_FIRST_S_ID <= i &&
110                           i <= LIBRDF_CONCEPT_LAST_S_ID) ?
111       world->concept_schema_namespace_uri : world->concept_ms_namespace_uri;
112     const unsigned char * token = (const unsigned char *)librdf_concept_tokens[i];
113 
114     world->concept_resources[i] = librdf_new_node_from_uri_local_name(world, ns_uri, token);
115     if(!world->concept_resources[i])
116       LIBRDF_FATAL1(world, LIBRDF_FROM_CONCEPTS, "Failed to create Node from URI\n");
117 
118     /* keep shared copy of URI from node */
119     world->concept_uris[i] = librdf_node_get_uri(world->concept_resources[i]);
120   }
121 }
122 
123 
124 /**
125  * librdf_get_concept_ms_namespace:
126  * @world: librdf world object
127  *
128  * Get a shared #librdf_uri for the RDF Syntax namespace.
129  *
130  * Return value: #librdf_uri pointer or NULL on failure.
131  */
132 librdf_uri *
librdf_get_concept_ms_namespace(librdf_world * world)133 librdf_get_concept_ms_namespace(librdf_world *world)
134 {
135   librdf_world_open(world);
136   return world->concept_ms_namespace_uri;
137 }
138 
139 
140 /**
141  * librdf_get_concept_schema_namespace:
142  * @world: librdf world object
143  *
144  * Get a shared #librdf_uri for the RDF Schema namespace.
145  *
146  * Return value: #librdf_uri pointer or NULL on failure.
147  */
148 librdf_uri *
librdf_get_concept_schema_namespace(librdf_world * world)149 librdf_get_concept_schema_namespace(librdf_world *world)
150 {
151   librdf_world_open(world);
152   return world->concept_schema_namespace_uri;
153 }
154 
155 
156 /**
157  * librdf_get_concept_by_name:
158  * @world: redland world object
159  * @is_ms: non zero if name is a RDF namespace concept (else is RDF schema)
160  * @name: the name to look up
161  * @uri_p: pointer to variable to hold #librdf_uri of concept or NULL if not required
162  * @node_p: pointer to variable to hold #librdf_node of concept or NULL if not required
163  *
164  * Get Redland uri and/or node objects for RDF concepts.
165  *
166  * Allows the dynamic look-up of an RDF concept by the local_name of
167  * the concept in either the RDF or RDF Schema namespace.  Returns
168  * the #librdf_uri and/or #librdf_node found as required.
169  **/
170 void
librdf_get_concept_by_name(librdf_world * world,int is_ms,const char * name,librdf_uri ** uri_p,librdf_node ** node_p)171 librdf_get_concept_by_name(librdf_world *world, int is_ms,
172                            const char *name,
173                            librdf_uri **uri_p, librdf_node **node_p)
174 {
175   int i;
176 
177   librdf_world_open(world);
178 
179   for (i=0; i < LIBRDF_CONCEPT_LAST; i++) {
180     int this_is_ms = !(LIBRDF_CONCEPT_FIRST_S_ID <= i &&
181                        i <= LIBRDF_CONCEPT_LAST_S_ID);
182     if(this_is_ms != is_ms)
183       continue;
184 
185     if(!strcmp(librdf_concept_tokens[i], name)) {
186       if(uri_p)
187         *uri_p=world->concept_uris[i];
188       if(node_p)
189         *node_p=world->concept_resources[i];
190     }
191   }
192 }
193 
194 
195 /**
196  * librdf_get_concept_resource_by_index:
197  * @world: redland world object
198  * @idx: #librdf_concepts_index
199  *
200  * Get Redland node object for RDF concepts.
201  *
202  * Return value: #librdf_node pointer or NULL on failure.
203  **/
204 librdf_node*
librdf_get_concept_resource_by_index(librdf_world * world,librdf_concepts_index idx)205 librdf_get_concept_resource_by_index(librdf_world *world,
206                                      librdf_concepts_index idx)
207 {
208   librdf_world_open(world);
209 
210   if ((int)idx < 0 || idx > LIBRDF_CONCEPT_LAST)
211     return NULL;
212 
213   return world->concept_resources[idx];
214 }
215 
216 
217 /**
218  * librdf_get_concept_uri_by_index:
219  * @world: redland world object
220  * @idx: #librdf_concepts_index
221  *
222  * Get Redland uri object for RDF concepts.
223  *
224  * Return value: #librdf_uri pointer or NULL on failure.
225  **/
226 librdf_uri*
librdf_get_concept_uri_by_index(librdf_world * world,librdf_concepts_index idx)227 librdf_get_concept_uri_by_index(librdf_world *world,
228                                 librdf_concepts_index idx)
229 {
230   librdf_world_open(world);
231 
232   if ((int)idx < 0 || idx > LIBRDF_CONCEPT_LAST)
233     return NULL;
234 
235   return world->concept_uris[idx];
236 }
237 
238 
239 /**
240  * librdf_finish_concepts:
241  * @world: redland world object
242  *
243  * INTERNAL - Terminate the concepts module.
244  *
245  **/
246 void
librdf_finish_concepts(librdf_world * world)247 librdf_finish_concepts(librdf_world *world)
248 {
249   int i;
250 
251   /* Free resources and set pointers to NULL so that they are cleared
252    * in case the concepts module is initialised again in the same process. */
253 
254   if(world->xsd_namespace_uri) {
255     librdf_free_uri(world->xsd_namespace_uri);
256     world->xsd_namespace_uri = NULL;
257   }
258 
259   if(world->concept_ms_namespace_uri) {
260     librdf_free_uri(world->concept_ms_namespace_uri);
261     world->concept_ms_namespace_uri = NULL;
262   }
263 
264   if(world->concept_schema_namespace_uri) {
265     librdf_free_uri(world->concept_schema_namespace_uri);
266     world->concept_schema_namespace_uri = NULL;
267   }
268 
269   if(world->concept_resources) {
270     for (i=0; i<= LIBRDF_CONCEPT_LAST; i++) {
271       /* deletes associated URI too */
272       if(world->concept_resources[i])
273         librdf_free_node(world->concept_resources[i]);
274     }
275     LIBRDF_FREE(librdf_node**, world->concept_resources);
276     world->concept_resources=NULL;
277   }
278 
279   if(world->concept_uris) {
280     /* uris were freed above, now just free the array */
281     LIBRDF_FREE(librdf_uri**, world->concept_uris);
282     world->concept_uris=NULL;
283   }
284 }
285 
286 #endif
287 
288 
289 /* TEST CODE */
290 
291 
292 #ifdef STANDALONE
293 
294 /* one more prototype */
295 int main(int argc, char *argv[]);
296 
297 
298 #define EXPECTED_STRING "http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq"
299 int
main(int argc,char * argv[])300 main(int argc, char *argv[])
301 {
302   const char *program=librdf_basename((const char*)argv[0]);
303   librdf_world *world;
304   librdf_uri* uri;
305   librdf_node* node;
306   unsigned char* actual;
307 
308   world=librdf_new_world();
309   librdf_world_open(world);
310 
311   uri=LIBRDF_MS_Seq_URI(world);
312   if(!uri) {
313     fprintf(stderr, "%s: Got no concept URI for rdf:Seq\n", program);
314     exit(1);
315   }
316 
317   actual=librdf_uri_as_string(uri);
318   if(strcmp(EXPECTED_STRING, (const char*)actual)) {
319     fprintf(stderr, "%s: Expected URI: <%s> Got: <%s>\n", program,
320             EXPECTED_STRING, actual);
321     exit(1);
322   }
323 
324   node=librdf_get_concept_resource_by_index(world, LIBRDF_CONCEPT_LAST);
325   if(!node) {
326     fprintf(stderr, "%s: Got no concept node for the last concept\n", program);
327     exit(1);
328   }
329 
330   librdf_free_world(world);
331 
332   /* keep gcc -Wall happy */
333   return(0);
334 }
335 
336 #endif
337