1 /* morla - Copyright (C) 2005-2007 bakunin - Andrea Marchesini
2 * <bakunin@morlardf.net>
3 *
4 * This source code is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * This source code is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Please refer to the GNU Public License for more details.
13 *
14 * You should have received a copy of the GNU Public License along with
15 * this source code; if not, write to:
16 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #else
22 # error Use configure; make; make install
23 #endif
24
25 #include "editor.h"
26
27 static gchar *namespace_check_prefix (gchar * ns);
28
29 /* Funzione per ordinare namespace */
30 static gint
namespace_compare(struct namespace_t * a,struct namespace_t * b)31 namespace_compare (struct namespace_t *a, struct namespace_t *b)
32 {
33 return strcmp (a->namespace, b->namespace);
34 }
35
36 /* Controlla l'esistenza di un namespace in elenco e lo comunica */
37 static gboolean
namespace_check(GList * list,gchar * ns)38 namespace_check (GList * list, gchar * ns)
39 {
40 while (list)
41 {
42 if (!strcmp (ns, ((struct namespace_t *) list->data)->namespace))
43 return TRUE;
44
45 list = list->next;
46 }
47
48 return FALSE;
49 }
50
51 /* Libera la memoria di un namespace: */
52 void
namespace_free(struct namespace_t * namespace)53 namespace_free (struct namespace_t *namespace)
54 {
55 if (!namespace)
56 return;
57
58 if (namespace->namespace)
59 g_free (namespace->namespace);
60
61 if (namespace->prefix)
62 g_free (namespace->prefix);
63
64 g_free (namespace);
65 }
66
67 /* Parsa una lista rdf generando una lista di namespace: */
68 gboolean
namespace_parse(GList * rdf,GList ** ret_list)69 namespace_parse (GList * rdf, GList ** ret_list)
70 {
71 GList *ret = NULL;
72 struct rdf_t *data;
73 gint i = 0;
74
75 /* Per ogni tripletta: */
76 while (rdf)
77 {
78 data = (struct rdf_t *) rdf->data;
79
80 /* Guardo solo il predicato: */
81 if (data && data->predicate)
82 {
83 gint len = strlen (data->predicate);
84 struct namespace_t *ns;
85 gchar *t;
86
87 /* Cerco caratteri particolari: */
88 while (len--)
89 if (data->predicate[len] == '/' || data->predicate[len] == '#' ||
90 data->predicate[len] == ':')
91 break;
92
93 /* Se ho trovato qualcosa... */
94 if (len)
95 {
96 t = g_strdup (data->predicate);
97 t[len + 1] = 0;
98
99 /* ... controllo se ce l'ho gia' ed inserisco: */
100 if (namespace_check (ret, t) == FALSE)
101 {
102 ns =
103 (struct namespace_t *)
104 g_malloc0 (sizeof (struct namespace_t));
105
106 ns->namespace = g_strdup (t);
107 if (!(ns->prefix = namespace_check_prefix (t)))
108 ns->prefix = g_strdup_printf ("_%d", ++i);
109 ns->visible = TRUE;
110
111 ret = g_list_append (ret, ns);
112 }
113
114 g_free (t);
115 }
116 }
117
118 rdf = rdf->next;
119 }
120
121 /* Ordino: */
122 *ret_list = g_list_sort (ret, (GCompareFunc) namespace_compare);
123 return TRUE;
124 }
125
126 /* Chiede se e' visibile un determinato rdf_t in base ad una lista
127 * di namespace: */
128 gboolean
namespace_visible(GList * list,struct rdf_t * rdf)129 namespace_visible (GList * list, struct rdf_t * rdf)
130 {
131 struct namespace_t *ns;
132 gint len;
133
134 while (list)
135 {
136 ns = (struct namespace_t *) list->data;
137
138 /* Se non e' visibile... */
139 if (!ns->visible)
140 {
141 len = strlen (ns->namespace);
142
143 /* Ed e' nel soggetto, predicato o coggetto */
144 if (!strncmp (ns->namespace, rdf->subject, len))
145 return FALSE;
146
147 if (!strncmp (ns->namespace, rdf->predicate, len))
148 return FALSE;
149
150 if (rdf->object_type == RDF_OBJECT_RESOURCE
151 && !strncmp (ns->namespace, rdf->object, len))
152 return FALSE;
153 }
154
155 list = list->next;
156 }
157
158 return TRUE;
159 }
160
161 /* Ritorna il prefisso associato ad una tripletta cercandolo nella lista dei
162 * namespace. Se non lo trova, inserisce: */
163 gchar *
namespace_prefix(GList ** namespace,gchar * t)164 namespace_prefix (GList ** namespace, gchar * t)
165 {
166 struct namespace_t *ns;
167 gint max, i;
168 GList *list = *namespace;
169
170 max = -1;
171
172 while (list)
173 {
174 ns = list->data;
175 if (!strcmp (ns->namespace, t))
176 return ns->prefix;
177
178 /* Anche se non l'ho trovato mi segno il max valore trovato
179 * nel sistema di autonumerazione: */
180 if (ns->prefix[0] == '_' && (i = atoi (ns->prefix + 1)) && max < i)
181 max = i;
182
183 list = list->next;
184 }
185
186 /* Non l'ho trovato, alloco: */
187 ns = (struct namespace_t *) g_malloc0 (sizeof (struct namespace_t));
188
189 ns->namespace = g_strdup (t);
190
191 if (!(ns->prefix = namespace_check_prefix (t)))
192 ns->prefix = g_strdup_printf ("_%d", ++max);
193
194 ns->visible = TRUE;
195
196 /* appendo alla lista e comunico: */
197 (*namespace) = g_list_append (*namespace, ns);
198
199 return ns->prefix;
200 }
201
202 /* Dato una stringa cerca un possibile namespace e ritorna una stringa
203 * da scrivere dentro ad un file rdf: */
204 gchar *
namespace_create(GList * l,gchar * t)205 namespace_create (GList * l, gchar * t)
206 {
207 struct namespace_t *r;
208 gint len;
209
210 while (l)
211 {
212 r = (struct namespace_t *) l->data;
213
214 /* Se l'hai trovato: */
215 len = strlen (r->namespace);
216 if (!strncmp (r->namespace, t, len) && !strstr (t + len, "/")
217 && !strstr (t + len, "#") && !strstr (t + len, ":"))
218 return g_strdup_printf ("%s:%s", r->prefix, t + len);
219
220 l = l->next;
221 }
222
223 /* errore: */
224 return g_strdup_printf ("_:%s", t);
225 }
226
227 /* Controlla se esiste un prefisso di un determinato namepsace nella lista
228 * degli RDFS importati */
229 static gchar *
namespace_check_prefix(gchar * ns)230 namespace_check_prefix (gchar * ns)
231 {
232 GList *list;
233 struct rdfs_t *r;
234
235 list = rdfs_list;
236 while (list)
237 {
238 r = (struct rdfs_t *) list->data;
239 if (r->prefix && !strcmp (ns, r->resource))
240 return g_strdup (r->prefix);
241
242 list = list->next;
243 }
244
245 return NULL;
246 }
247
248 /* EOF */
249