Statistics
| Revision:

gvsig-catalog / org.gvsig.catalog / branches / org.gvsig.catalog-CSW2.0.2 / org.gvsig.catalog / org.gvsig.catalog.lib / src / main / java / org / gvsig / catalog / metadataxml / XMLTree.java @ 55

History | View | Annotate | Download (10.5 KB)

1

    
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 *  Generalitat Valenciana
23
 *   Conselleria d'Infraestructures i Transport
24
 *   Av. Blasco Ib??ez, 50
25
 *   46010 VALENCIA
26
 *   SPAIN
27
 *
28
 *      +34 963862235
29
 *   gvsig@gva.es
30
 *      www.gvsig.gva.es
31
 *
32
 *    or
33
 *
34
 *   IVER T.I. S.A
35
 *   Salamanca 50
36
 *   46005 Valencia
37
 *   Spain
38
 *
39
 *   +34 963163400
40
 *   dac@iver.es
41
 */
42
package org.gvsig.catalog.metadataxml;
43
import java.io.ByteArrayInputStream;
44
import java.io.File;
45
import java.io.FileWriter;
46
import java.io.IOException;
47
import java.io.InputStream;
48
import java.io.StringWriter;
49
import java.util.ArrayList;
50
import java.util.StringTokenizer;
51

    
52
import org.apache.xml.serialize.OutputFormat;
53
import org.apache.xml.serialize.XMLSerializer;
54
import org.gvsig.catalog.utils.Strings;
55
import org.w3c.dom.Document;
56

    
57
/**
58
 * Utils to parse XML trees using DOM
59
 * @author Jorge Piera Llodra (piera_jor@gva.es)
60
 */
61
public class XMLTree {
62
        public static final String SEPARATOR = "->";
63

    
64
        /**
65
         * Create a XML node from a File
66
         * @return XML node
67
         * @param file File name
68
         */
69
        public static XMLNode xmlToTree(File file) {        
70
                try {
71
                        return new XMLNode(file);
72
                } catch (Exception e) {
73
                        // TODO Auto-generated catch block
74
                        e.printStackTrace();
75
                        return null;
76
                }
77
        } 
78

    
79
        /**
80
         * Create a XML node from a InputStream
81
         * @return XML node
82
         * @param stream InputStream
83
         */
84
        public static XMLNode xmlToTree(InputStream stream) {        
85
                try {
86
                        return new XMLNode(stream);
87
                } catch (Exception e) {
88
                        // TODO Auto-generated catch block
89
                        //e.printStackTrace();
90
                        return null;
91
                }
92
        } 
93

    
94
        /**
95
         * Create a XML node from a String
96
         * @return XML node
97
         * @param stream InputStream
98
         */
99
        public static XMLNode xmlToTree(String string) {        
100
                try {
101
                        return new XMLNode(new ByteArrayInputStream(string.getBytes()));
102
                } catch (Exception e) {
103
                        // Unconvertible UTF-8 character 
104
                        string = Strings.replace(string,
105
                                        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
106
                        "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
107
                        try {
108
                                return new XMLNode(new ByteArrayInputStream(string.getBytes()));
109
                        } catch (Exception e1) {
110
                                // TODO Auto-generated catch block
111
                                e1.printStackTrace();
112
                                return null;
113
                        }           
114
                }
115
        } 
116

    
117
        /**
118
         * Devuelve un fichero que crea a partir de un arbol XML
119
         * @return Devuelve el fichero escrito
120
         * @param dom Documento en XML
121
         * @param nombreFichero Nombre del fichero.
122
         */
123
        public static File treeToXML(Document dom, String nombreFichero) {        
124
                OutputFormat format = null;
125
                StringWriter stringOut = null;
126
                XMLSerializer serial = null;
127
                FileWriter file = null;
128
                //Creamos un fichero para almacenar la respuesta
129
                File file_answer = new File(nombreFichero);
130
                format = new OutputFormat(dom);
131
                format.setEncoding("ISO-8859-1");
132
                format.setIndent(5);
133
                stringOut = new StringWriter();
134
                serial = new XMLSerializer(stringOut, format);
135
                try {
136
                        serial.asDOMSerializer();
137
                        serial.serialize(dom);
138
                        file = new FileWriter(file_answer);
139
                        file.write(stringOut.toString());
140
                        file.close();
141
                } catch (IOException e) {
142
                        // TODO Auto-generated catch block
143
                        e.printStackTrace();
144
                        return null;
145
                }
146
                return file_answer;
147
        } 
148

    
149
        /**
150
         * Busca un Nodo dado una ruta de nodo del tipo "nodoRaiz:nodoPrimerNivel:...:nodoNivelN":
151
         * @return Devuelve el Nodo que corresponde a la ruta correcta o 'null' si no
152
         * lo encuentra
153
         * @param nodoRaiz Nodo a partir del cual se quiere hacer la b?squeda
154
         * @param etiqueta Ruta del campo que queremos buscar, separando los niveles por ':'
155
         */
156
        public static XMLNode searchNode(XMLNode nodoRaiz, String etiqueta) {        
157
                XMLNode[] nodes = searchMultipleNode(nodoRaiz, etiqueta);
158
                if ((nodes != null) && (nodes.length > 0)) {
159
                        return nodes[0];
160
                } else {
161
                        return null;
162
                }
163
        } 
164

    
165
        /**
166
         * Busca el padre de un Nodo dado una ruta de nodo del tipo "nodoRaiz:nodoPrimerNivel:...:nodoNivelN":
167
         * 
168
         * @param nodoRaiz Nodo a partir del cual se quiere hacer la b?squeda
169
         * @param etiqueta Ruta del campo que queremos buscar, separando los niveles por ':'
170
         * 
171
         * @return Devuelve el Nodo padre que corresponde a la ruta correcta o 'null' si no
172
         * lo encuentra
173
         * @param rootNode 
174
         * @param label 
175
         */
176
        public static XMLNode searchParentNode(XMLNode rootNode, String label) {        
177
                StringTokenizer sti = new StringTokenizer(label, "->");
178
                if (rootNode == null) {
179
                        return null;
180
                }
181

    
182
                XMLNode currentNode = rootNode.getSubNode(0);
183
                XMLNode parentNode = rootNode;
184

    
185
                //A cuantos niveles est? el TOKEN
186
                int niveles = sti.countTokens();
187
                String nombreNodo = cutNamespace(sti.nextToken());
188
                int nivelActual = 1;
189
                int i = 0;
190
                while (i < parentNode.getNumSubNodes()) {
191
                        if (nombreNodo.equals(cutNamespace(currentNode.getName()))) {
192
                                if (niveles == nivelActual) {
193
                                        return parentNode;
194
                                }
195
                                parentNode = currentNode;
196
                                currentNode = currentNode.getSubNode(0);
197
                                nombreNodo = sti.nextToken();
198
                                nivelActual++;
199
                                i = 0;
200
                        } else {
201
                                currentNode = currentNode.getSubNode(i);
202
                                i ++;
203
                        }
204
                }
205
                return null;
206
        } 
207

    
208
        /**
209
         * Hace una busqueda de un atributo de un nodo
210
         * 
211
         * @param nodo Nodo del que se quiere buscar el atributo
212
         * @param nombreAtributo Nombre del atributo
213
         * 
214
         * @return Valor del atributo, o null si no lo ha encontrado
215
         * @param node 
216
         * @param attributeName 
217
         */
218
        public static String searchAtribute(XMLNode node, String attributeName) {        
219
                return node.getAttribute(attributeName);
220
        } 
221

    
222
        /**
223
         * Hace una busqueda de una etiqueta en un nodo y devuelve
224
         * su valor
225
         * 
226
         * @param nodo Nodo del que se quiere buscar el atributo
227
         * 
228
         * @return Valor de la etiqueta
229
         * @param node 
230
         * @param etiqueta Nombre de la etiqueta
231
         */
232
        public static String searchNodeValue(XMLNode node, String etiqueta) {        
233
                XMLNode nodoB = searchNode(node, etiqueta);
234
                if (nodoB == null)
235
                        return null;
236
                return nodoB.getText();
237

    
238
        } 
239

    
240
        /**
241
         * Hace una busqueda de una etiqueta en un nodo y devuelve
242
         * el valor del atributo correspondiente
243
         * 
244
         * @param nodo Nodo del que se quiere buscar el atributo
245
         * 
246
         * @return Valor del atributo de la etiqueta o null
247
         * @param node 
248
         * @param etiqueta Nombre de la etiqueta
249
         * @param atributo 
250
         */
251
        public static String searchNodeAtribute(XMLNode node, String etiqueta, String atributo) {        
252
                XMLNode nodoB = searchNode(node, etiqueta);
253
                if (nodoB == null) {
254
                        return null;
255
                } else {
256
                        return searchAtribute(nodoB, atributo);
257
                }
258
        } 
259

    
260
        /**
261
         * Hace una busqueda de nodos que se llaman igual y devuleve el valor
262
         * 
263
         * @param parentLabel Ruta del campo que queremos buscar, separando los niveles por '->'
264
         * 
265
         * @return Un vector con valores de las etiquetas
266
         * @param rootNode Nodo a partir del cual se quiere hacer la b?squeda
267
         * @param label Node label
268
         */
269
        public static String[] searchMultipleNodeValue(XMLNode rootNode, String label) {        
270
                XMLNode[] nodes = searchMultipleNode(rootNode, label);
271
                if ((nodes == null) || (nodes.length == 0)) {
272
                        return null;
273
                }
274
                String[] values = new String[nodes.length];
275
                for (int i = 0; i < nodes.length; i++)
276
                        //if (nodes[i].getFirstChild() != null) {
277
                        values[i] = nodes[i].getText();
278
                //}
279
                return values;
280
        } 
281

    
282
        /**
283
         * Hace una busqueda de nodos que se llaman igual desde uno dado(sin recursividad)
284
         * 
285
         * @param etiqueta Ruta del campo que queremos buscar, separando los niveles por ':'
286
         * 
287
         * @return Un vector con los nodos que ha encontrado
288
         * @param nodoRaiz Nodo a partir del cual se quiere hacer la b?squeda
289
         * @param label 
290
         */
291
        public static XMLNode[] searchMultipleNode(XMLNode nodoRaiz, String label) {        
292
                ArrayList rootNodes = new ArrayList();
293
                ArrayList leafNodes = new ArrayList();
294
                String firstLabel = null;
295
                leafNodes.add(nodoRaiz);
296
                int level = getLevelNumber(label);
297
                int k = 1;
298
                while (k <= level) {
299
                        firstLabel = cutNamespace(getParentLabel(label));
300
                        label = getChildLabel(label);
301
                        rootNodes = new ArrayList(leafNodes);
302
                        leafNodes.clear();
303
                        for (int i = 0; i < rootNodes.size(); i++) {
304
                                XMLNode root = (XMLNode) rootNodes.get(i);
305
                                if (root != null) {
306
                                        XMLNode[] nodes = root.getSubnodes();
307
                                        for (int j = 0; j < nodes.length; j++) {
308
                                                if (cutNamespace(nodes[j].getName()).equals(firstLabel)) {
309
                                                        leafNodes.add(nodes[j]);
310
                                                }
311
                                        }
312
                                }
313
                        }
314
                        k++;
315
                }
316
                XMLNode[] nodes = new XMLNode[leafNodes.size()];
317

    
318
                for (int i = 0; i < leafNodes.size(); i++)
319
                        nodes[i] = (XMLNode) leafNodes.get(i);
320
                return nodes;
321
        } 
322

    
323
        /**
324
         * Gets the parent node label
325
         * 
326
         * 
327
         * @return The parent node label
328
         * @param nodeLabel Node label
329
         */
330
        private static String getParentLabel(String nodeLabel) {        
331
                return separateParams(nodeLabel,SEPARATOR)[0];
332
        } 
333

    
334
        /**
335
         * It cuts an String in an array of Strings separated by a pattern
336
         * 
337
         * 
338
         * @return An array of Strings
339
         * @param text Text to cut
340
         * @param separator Pattent to find      *
341
         */
342
        private static String[] separateParams(String text, String separator) {        
343
                return text.split(separator);        
344
        } 
345

    
346
        /**
347
         * Gets the node label
348
         * 
349
         * 
350
         * @return The node label
351
         * @param nodeLabel Node label
352
         */
353
        private static String getChildLabel(String nodeLabel) {        
354
                String st = null;
355
                String[] labels = separateParams(nodeLabel,SEPARATOR);
356

    
357
                if (labels.length  == 1){
358
                        return labels[0];
359
                }
360

    
361
                st = labels[1];
362

    
363
                for (int i=2 ; i<labels.length ; i++)
364
                        st = st + SEPARATOR + labels[i];
365

    
366
                return st;
367
        } 
368

    
369
        /**
370
         * @return 
371
         * @param nodeLabel 
372
         */
373
        private static int getLevelNumber(String nodeLabel) {        
374
                String[] labels = separateParams(nodeLabel,SEPARATOR);
375
                return labels.length;
376
        } 
377

    
378
        /**
379
         * Remove the namespace from a label
380
         * @param label
381
         */
382
        private static String cutNamespace(String label){
383
                if (label == null){
384
                        return null;
385
                }
386
                int i =  label.indexOf(":");
387
                if (i > 0){
388
                        return label.substring(i + 1, label.length());
389
                }
390
                return label;
391
        }
392
}