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