Statistics
| Revision:

gvsig-catalog / trunk / appCatalog / src / org / gvsig / catalog / metadataxml / XMLTree.java @ 6

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

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

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

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

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

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

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

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

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

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

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

    
239
        } 
240

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

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

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

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

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

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

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

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

    
362
                st = labels[1];
363

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

    
367
                return st;
368
        } 
369

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

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