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