]> matita.cs.unibo.it Git - helm.git/blob - helm/gTopLevel/xmlDiff.ml
Debugging stuff changed.
[helm.git] / helm / gTopLevel / xmlDiff.ml
1 (* Copyright (C) 2000-2002, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 let myprerr_endline = prerr_endline;;
27 let prerr_endline _ = ();;
28
29 let update_dom ~(from : Gdome.document) (d : Gdome.document) =
30  let rec aux (p: Gdome.node) (f: Gdome.node) (t: Gdome.node) =
31 (* Perche' non andava?
32   if f#get_localName = t#get_localName &&
33      f#get_namespaceURI = t#get_namespaceURI
34 *)
35   match
36    f#get_nodeType,t#get_nodeType,
37    f#get_namespaceURI,t#get_namespaceURI,
38    f#get_localName,t#get_localName
39   with
40      GdomeNodeTypeT.TEXT_NODE,GdomeNodeTypeT.TEXT_NODE,_,_,_,_ when
41       match f#get_nodeValue, t#get_nodeValue with
42          Some v, Some v' -> v#to_string = v'#to_string
43        | _,_ -> assert false
44       ->
45 prerr_endline ("XML_DIFF: preservo il nodo testo " ^ match f#get_nodeValue with Some v -> v#to_string | None -> assert false);
46        ()
47    | GdomeNodeTypeT.ELEMENT_NODE,GdomeNodeTypeT.ELEMENT_NODE,
48       Some nu, Some nu', Some ln, Some ln' when
49        ln#to_string = ln'#to_string && nu#to_string = nu'#to_string ->
50 prerr_endline ("XML_DIFF: preservo il nodo "^ nu#to_string ^ ":" ^ln#to_string);
51         begin
52          match f#get_attributes, t#get_attributes with
53             Some fattrs, Some tattrs ->
54              let flen = fattrs#get_length in
55              let tlen = tattrs#get_length in
56               let processed = ref [] in
57               for i = 0 to flen -1 do
58                match fattrs#item i with
59                   None -> assert false
60                 | Some attr ->
61                     match attr#get_namespaceURI with
62                        None ->
63                         (* Back to DOM Level 1 ;-( *)
64                         begin
65                          let name = attr#get_nodeName in
66                           match tattrs#getNamedItem ~name with
67                              None ->
68 myprerr_endline ("XML_DIFF: rimuovo l'attributo " ^ name#to_string);
69                               ignore (f#removeChild attr)
70                            | Some attr' ->
71                               processed :=
72                                (None,Some name)::!processed ;
73                               match attr#get_nodeValue, attr'#get_nodeValue with
74                                  Some v1, Some v2 when
75                                      v1#to_string = v2#to_string
76                                   || (name#to_string = "selection" &&
77                                       nu#to_string =
78                                        "http://www.w3.org/1998/Math/MathML" &&
79                                       ln#to_string = "maction")
80                                   ->
81 prerr_endline ("XML_DIFF: DOM 1; preservo l'attributo " ^ name#to_string);
82                                    ()
83                                | Some v1, Some v2 ->
84 myprerr_endline ("XML_DIFF: DOM 1; rimpiazzo l'attributo " ^ name#to_string ^ ": old value=" ^ v1#to_string ^ ", new value=" ^ v2#to_string);
85                                   let attr'' = from#importNode attr' true in
86                                    ignore (fattrs#setNamedItem attr'')
87                                | _,_ -> assert false
88                         end
89                      | Some namespaceURI ->
90                         let localName = 
91                          match attr#get_localName with
92                            Some v -> v
93                           | None -> assert false
94                         in
95                          match
96                           tattrs#getNamedItemNS ~namespaceURI ~localName
97                          with
98                             None ->
99 myprerr_endline ("XML_DIFF: rimuovo l'attributo " ^ localName#to_string);
100                              ignore (f#removeChild attr)
101                           | Some attr' ->
102                              processed :=
103                               (Some namespaceURI,Some localName)::!processed ;
104                              (*CSC: questo mi dice read-only ;-( 
105                                attr#set_nodeValue attr'#get_nodeValue *)
106                              (*CSC: questo mi abortisce con una assert
107                              let attr'' = from#importNode attr' true in
108                               ignore(f#replaceChild ~newChild:attr'' ~oldChild:attr)*)
109                               match attr#get_nodeValue, attr'#get_nodeValue with
110                                  Some v1, Some v2 when
111                                   v1#to_string = v2#to_string ->
112 prerr_endline ("XML_DIFF: DOM 2; preservo l'attributo " ^ namespaceURI#to_string ^ ":" ^ localName#to_string);
113                                    ()
114                                | Some _, Some _ ->
115 myprerr_endline ("XML_DIFF: DOM 2; rimpiazzo l'attributo " ^ namespaceURI#to_string ^ ":" ^ localName#to_string);
116                                   let attr'' = from#importNode attr' true in
117                                    ignore (fattrs#setNamedItem attr'')
118                                | _,_ -> assert false
119               done ;
120               for i = 0 to tlen -1 do
121                match tattrs#item i with
122                   None -> assert false
123                 | Some attr ->
124 let debugs = ref "" in
125                    let namespaceURI,localName =
126                     match attr#get_namespaceURI with
127                        None ->
128 debugs := ("XML_DIFF: DOM 1.0; creo un nuovo attributo " ^ attr#get_nodeName#to_string) ;
129                         None,attr#get_nodeName
130                      | Some namespaceURI as v ->
131 debugs := ("XML_DIFF: DOM 2.0; creo un nuovo attributo " ^ namespaceURI#to_string ^ ":" ^ match attr#get_localName with Some v -> v#to_string | None -> assert false);
132                        v, match attr#get_localName with
133                           None -> assert false
134                         | Some v -> v
135                    in
136                     if
137                      not
138                       (List.exists
139                         (function
140                             None,Some localName' ->
141                              (match namespaceURI with
142                                  None ->
143                                   localName#to_string = localName'#to_string
144                                | Some _ -> false)
145                           | Some namespaceURI', Some localName' ->
146                              (match namespaceURI with
147                                  None -> false
148                                | Some namespaceURI ->
149                                   localName#to_string = localName'#to_string &&
150                                   namespaceURI#to_string=namespaceURI'#to_string
151                              )
152                           | _,_ -> assert false
153                         ) !processed)
154                     then
155                      let attr' = from#importNode attr false in
156 myprerr_endline !debugs ;
157                       ignore (fattrs#setNamedItem attr')
158               done
159           | _,_ -> assert false
160         end ;
161         let fchildren = f#get_childNodes in
162         let tchildren = t#get_childNodes in
163          let rec dumb_diff =
164           function
165              [],[] -> ()
166            | he1::tl1,he2::tl2 ->
167 prerr_endline "XML_DIFF: processo una coppia di figli" ;
168               aux f he1 he2 ;
169               dumb_diff (tl1,tl2)
170            | [],tl2 ->
171 myprerr_endline "XML_DIFF: appendo i nodi residui" ;
172               List.iter
173                (function n ->
174                  let n' = from#importNode n true in
175                   ignore (f#appendChild n')
176                ) tl2
177            | tl1,[] ->
178 myprerr_endline "XML_DIFF: cancello i nodi residui" ;
179               List.iter (function n -> ignore (f#removeChild n)) tl1
180          in
181           let node_list_of_nodeList nl =
182            let rec aux i =
183             match nl#item ~index:i with
184                None -> []
185              | Some n when
186                    n#get_nodeType = GdomeNodeTypeT.ELEMENT_NODE
187                 or n#get_nodeType = GdomeNodeTypeT.TEXT_NODE ->
188                  n::(aux (i+1))
189              | Some n ->
190 prerr_endline ("XML_DIFF: mi sto perdendo i nodi di tipo " ^ string_of_int (Obj.magic n#get_nodeType)) ;
191                aux (i+1)
192            in
193             aux 0
194           in
195 for i = 0 to fchildren#get_length - 1 do
196 match fchildren#item i with
197 None -> prerr_endline "EUREKA: ma siamo matti?"
198 |Some n ->
199 match n#get_nodeType with GdomeNodeTypeT.ATTRIBUTE_NODE -> prerr_endline "EUREKA attr" | GdomeNodeTypeT.CDATA_SECTION_NODE -> prerr_endline "EUREKA text" | GdomeNodeTypeT.DOCUMENT_FRAGMENT_NODE -> prerr_endline "EUREKA document fragment" | _ -> prerr_endline ("EUREKA " ^ string_of_int (Obj.magic n#get_nodeType))
200 done ;
201 prerr_endline("XML_DIFF: from ha " ^ string_of_int fchildren#get_length ^ " nodi, ovvero " ^ string_of_int (List.length (node_list_of_nodeList fchildren)) ^ " figli");
202 prerr_endline("XML_DIFF: to   ha " ^ string_of_int tchildren#get_length ^ " nodi, ovvero " ^ string_of_int (List.length (node_list_of_nodeList tchildren)) ^ " figli");
203            dumb_diff
204             (node_list_of_nodeList fchildren, node_list_of_nodeList tchildren)
205    | t1,t2,_,_,_,_ when
206       (t1 = GdomeNodeTypeT.ELEMENT_NODE || t1 = GdomeNodeTypeT.TEXT_NODE) &&
207       (t2 = GdomeNodeTypeT.ELEMENT_NODE || t2 = GdomeNodeTypeT.TEXT_NODE) ->
208        let t' = from#importNode t true in
209 myprerr_endline "XML_DIFF: importo il nodo" ;
210 (*
211 prerr_endline ("Rimpiazzo" ^ (match f#get_namespaceURI with Some s -> s#to_string) ^ ":" ^ (match f#get_localName with Some s -> s#to_string) ^ " con " ^ (match t#get_namespaceURI with Some s -> s#to_string) ^ ":" ^ (match t#get_localName with Some s -> s#to_string) ^ " in " ^ (match p#get_localName with Some s -> s#to_string | None -> "_")) ;
212 *)
213         ignore (p#replaceChild ~newChild:t' ~oldChild:f)
214    | _,_,_,_,_,_ -> assert false
215  in
216   try
217    aux (d :> Gdome.node)
218     (from#get_documentElement :> Gdome.node)
219     (d#get_documentElement :> Gdome.node)
220   with
221      (GdomeInit.DOMException (e,msg) as ex) ->
222 (*
223     let module E = GdomeDOMExceptionT in
224 *)
225        prerr_endline
226         ("DOM EXCEPTION: " ^ msg ^ " --- " ^
227 string_of_int (Obj.magic e)) ;
228        raise ex
229  (*
230         match e with
231            E.NO_ERR -> "NO_ERR"
232          | E.INDEX_SIZE_ERR -> "INDEX_SIZE_ERR"
233          | E.DOMSTRING_SIZE_ERR -> "DOMSTRING_SIZE_ERR"
234          | E.HIERARCHY_REQUEST_ERR -> "HIERARCHY_REQUEST_ERR"
235          | E.WRONG_DOCUMENT_ERR -> "WRONG_DOCUMENT_ERR"
236          | E.INVALID_CHARACTER_ERR -> "INVALID_CHARACTER_ERR"
237          | E.NO_DATA_ALLOWED_ERR -> "NO_DATA_ALLOWER_ERR"
238          | E.NO_MODIFICATION_ALLOWED_ERR -> "NO_MODIFICATION_ALLOWED_ERR"
239          | E.NOT_FOUND_ERR -> "NOT_FOUND_ERR"
240          | E.NOT_SUPPORTED_ERR -> "NOT_SUPPORTED_ERR"
241          | E.INUSE_ATTRIBUTE_ERR -> "INUSE_ATTRIBUTE_ERR"
242          | E.INVALID_STATE_ERR -> "INVALID_STATE_ERR"
243          | E.SYNTAX_ERR -> "SYNTAX_ERR"
244          | E.INVALID_MODIFICATION_ERR -> "INVALID_MODIFICATION_ERR"
245          | E.NAMESPACE_ERR -> "NAMESPACE_ERR"
246          | E.INVALID_ACCESS_ERR -> "INVALID_ACCESS_ERR"
247 *)
248   | e ->
249     prerr_endline "PROBLEMA" ;
250     raise e
251 ;;