Statistics
| Revision:

root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / util / SpecHelper.java @ 15280

History | View | Annotate | Download (11 KB)

1
/*
2
 *  $Id: SpecHelper.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
3
 *  IzPack
4
 *  Copyright (C) 2004 Klaus Bartz
5
 *
6
 *  File :               SpecHelper.java
7
 *  Description :        Helper for XML specifications.
8
 *  Author's email :     klaus.bartz@coi.de
9
 *  Author's Website :   http://www.coi.de/
10
 *
11
 *  This program is free software; you can redistribute it and/or
12
 *  modify it under the terms of the GNU General Public License
13
 *  as published by the Free Software Foundation; either version 2
14
 *  of the License, or any later version.
15
 *
16
 *  This program is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this program; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24
 */
25

    
26
package com.izforge.izpack.util;
27

    
28
import java.io.FileInputStream;
29
import java.io.FileOutputStream;
30
import java.io.File;
31
import java.io.InputStream;
32
import java.util.Iterator;
33
import java.util.Vector;
34

    
35
import com.izforge.izpack.installer.InstallerException;
36
import com.izforge.izpack.installer.ResourceManager;
37
import com.izforge.izpack.installer.VariableSubstitutor;
38

    
39
import net.n3.nanoxml.NonValidator;
40
import net.n3.nanoxml.StdXMLBuilder;
41
import net.n3.nanoxml.StdXMLParser;
42
import net.n3.nanoxml.StdXMLReader;
43
import net.n3.nanoxml.XMLElement;
44

    
45
/**
46
 * This class contains some helper methods to simplify handling of 
47
 * xml specification files. 
48
 *
49
 * @author  Klaus Bartz
50
 *
51
 */
52
public class SpecHelper 
53
{
54
  private String specFilename;
55
  private XMLElement spec;
56
  private boolean _haveSpec;
57

    
58
  public static final String YES = "yes";
59
  public static final String NO = "no";
60
  private static final String PACK_KEY  = "pack";
61
  private static final String PACK_NAME = "name";
62

    
63

    
64
  /**
65
   *  The default constructor.
66
   */
67
  public SpecHelper()
68
  {
69
    super();
70
  }
71

    
72
   /*--------------------------------------------------------------------------*/
73
  /**
74
   * Reads the XML specification given by the file name. The result is
75
   * stored in spec.
76
   *
77
   * @exception Exception for any problems in reading the specification
78
   */
79
  /*--------------------------------------------------------------------------*/
80
   public void readSpec (String specFileName) throws Exception
81
   {
82
     readSpec( specFileName, null );
83
   }
84

    
85
   /*--------------------------------------------------------------------------*/
86
   /**
87
    * Reads the XML specification given by the file name. The result is
88
    * stored in spec.
89
    *
90
    * @exception Exception for any problems in reading the specification
91
    */
92
   /*--------------------------------------------------------------------------*/
93
    public void readSpec (String specFileName, VariableSubstitutor substitutor) throws Exception
94
    {
95
      // open an input stream
96
      InputStream input = null;
97
      try
98
      {
99
        input = getResource (specFileName);
100
      }
101
      catch (Exception exception)
102
      {
103
        _haveSpec = false;
104
        return;
105
      }
106
      if (input == null)
107
      {
108
        _haveSpec = false;
109
        return;
110
      }
111
        
112
      readSpec( input, substitutor );
113
         
114
      // close the stream
115
      input.close ();
116
      this.specFilename = specFileName;
117
    }
118

    
119
    /*--------------------------------------------------------------------------*/
120
    /**
121
     * Reads the XML specification given by the input stream. The result is
122
     * stored in spec.
123
     *
124
     * @exception Exception for any problems in reading the specification
125
     */
126
    /*--------------------------------------------------------------------------*/
127
     public void readSpec (InputStream input) throws Exception
128
     {
129
       readSpec( input, null );
130
     }
131
    
132
   /*--------------------------------------------------------------------------*/
133
   /**
134
    * Reads the XML specification given by the input stream. The result is
135
    * stored in spec.
136
    *
137
    * @exception Exception for any problems in reading the specification
138
    */
139
   /*--------------------------------------------------------------------------*/
140
    public void readSpec (InputStream input, VariableSubstitutor substitutor) throws Exception
141
    {
142
      // first try to substitute the variables
143
      if (substitutor != null)
144
      {
145
        input = substituteVariables( input, substitutor );
146
      }
147

    
148
      // initialize the parser
149
      StdXMLParser parser = new StdXMLParser ();
150
      parser.setBuilder   (new StdXMLBuilder ());
151
      parser.setValidator (new NonValidator ());
152
      parser.setReader    (new StdXMLReader (input));
153
         
154
      // get the data
155
      spec = (XMLElement) parser.parse ();
156
      _haveSpec = true;
157
    }
158

    
159
   /**
160
   *  Gets the stream to a resource.
161
   *
162
   * @param  res            The resource id.
163
   * @return                The resource value, null if not found
164
   */
165
  public InputStream getResource(String res)
166
  {
167
    try
168
    {
169
      //System.out.println ("retrieving resource " + res);
170
      return ResourceManager.getInstance().getInputStream(res);
171
    } catch (Exception e)
172
    { // Cannot catch ResourceNotFoundException because it is not public.
173
      return null;
174
    }
175
  }
176

    
177
  /**
178
   * Returns a XML element which represents the pack for the given name.
179
   * @param packDestName name of the pack which should be returned
180
   * @return a XML element which represents the pack for the given name
181
   */
182
  public XMLElement getPackForName(String packDestName )
183
  {
184
    Vector packs = getSpec().getChildrenNamed(PACK_KEY);
185
    Iterator iter = null;
186
    if( packs == null )
187
      return(null);
188
    iter = packs.iterator();
189
    while (iter.hasNext())
190
    {
191
      
192
      XMLElement pack = (XMLElement) iter.next();
193
      String packName = pack.getAttribute(PACK_NAME); 
194
      if( packName.equals(packDestName))
195
        return( pack );
196
    }
197
    return(null);
198
  
199
  }
200

    
201
  /**
202
   * Create parse error with consistent messages. Includes file name and line #
203
   * of parent. It is an error for 'parent' to be null.
204
   *
205
   * @param parent  The element in which the error occured
206
   * @param message Brief message explaining error
207
   */
208
  public void parseError(XMLElement parent, String message)
209
    throws InstallerException
210
  {
211
    throw new InstallerException(
212
      specFilename + ":" + parent.getLineNr() + ": " + message);
213
  }
214

    
215
  /**
216
   * Returns true if a specification exist, else false.
217
   * @return true if a specification exist, else false
218
   */
219
  public boolean haveSpec()
220
  {
221
    return _haveSpec;
222
  }
223

    
224
  /**
225
   * Returns the specification.
226
   * @return the specification
227
   */
228
  public XMLElement getSpec()
229
  {
230
    return spec;
231
  }
232

    
233
  /**
234
   * Sets the specifaction to the given XML element.
235
   * @param element
236
   */
237
  public void setSpec(XMLElement element)
238
  {
239
    spec = element;
240
  }
241

    
242
  /**
243
   * Returns a Vector with all leafs of the tree which is described
244
   * with childdef.
245
   * 
246
   * @param root the XMLElement which is the current root for the search
247
   * @param childdef a String array which describes the tree; the last element
248
   * contains the leaf name
249
   * @return a Vector of XMLElements of all leafs founded under root
250
   */
251
        public Vector getAllSubChildren( XMLElement root, String [] childdef)
252
  {
253
    return( getSubChildren( root, childdef, 0 ));
254
  }
255

    
256
  /**
257
   * Returns a Vector with all leafs of the tree which is described
258
   * with childdef beginning at the given depth.
259
   * 
260
   * @param root the XMLElement which is the current root for the search
261
   * @param childdef a String array which describes the tree; the last element
262
   * contains the leaf name
263
   * @param depth depth to start in childdef
264
   * @return a Vector of XMLElements of all leafs founded under root
265
   */
266
  private Vector getSubChildren( XMLElement root, String [] childdef, int depth)
267
  {
268
    Vector retval = null;
269
    Vector retval2 = null;
270
    Vector children = root != null ? root.getChildrenNamed(childdef[depth]) : null;
271
    if( children == null )
272
      return( null );
273
    if( depth < childdef.length - 1)
274
    {
275
      Iterator iter = children.iterator();
276
      while( iter.hasNext() )
277
      {
278
        retval2 = getSubChildren((XMLElement) iter.next(), childdef, depth + 1 );
279
        if( retval2 != null)
280
        {
281
          if( retval == null )
282
            retval = new Vector();
283
          retval.addAll(retval2);
284
        }
285
      }
286
    }
287
    else
288
      return( children);
289
    return( retval);
290
  }
291

    
292

    
293
  /**
294
   * Creates an temp file in to the substitutor the
295
   * substituted contents of input writes; close it and
296
   * (re)open it as FileInputStream.
297
   * The file will be deleted on exit.
298
   * @param input the opened input stream which contents should be substituted
299
   * @param substitutor substitutor which should substitute the contents of input
300
   * @return a file input stream of the created temporary file
301
   * @throws Exception
302
   */
303
  public InputStream substituteVariables( InputStream input, VariableSubstitutor substitutor)
304
    throws Exception
305
  {
306
    File tempFile = File.createTempFile("izpacksubs", "");
307
    FileOutputStream fos = null;
308
    tempFile.deleteOnExit();
309
    try
310
    {
311
      fos = new FileOutputStream( tempFile );
312
      substitutor.substitute(input,fos,null,null);
313
    }
314
    finally
315
    {
316
      if( fos != null )
317
        fos.close();
318
    }
319
    return new FileInputStream( tempFile );
320
  }
321

    
322
  /**
323
   * Returns whether the value to the given attribute is
324
   * "yes" or not. If the attribute does not exist, or the
325
   * value is not "yes" and not "no", the default value is
326
   * returned.
327
   * @param element the XML element which contains the attribute
328
   * @param attribute the name of the attribute
329
   * @param defaultValue the default value
330
   * @return whether the value to the given attribute is
331
   * "yes" or not
332
   */
333
  public boolean isAttributeYes( XMLElement element,
334
    String attribute, boolean defaultValue )
335
  {
336
    String value =
337
      element.getAttribute(attribute, (defaultValue ? YES : NO));
338
    if (value.equalsIgnoreCase(YES))
339
      return true;
340
    if (value.equalsIgnoreCase(NO))
341
      return false;
342

    
343
    return defaultValue;
344
  }
345

    
346
  /**
347
   * Returns the attribute for the given attribute name.
348
   * If no attribute exist, an InstallerException with
349
   * a detail message is thrown.
350
   * @param element XML element which should contain the attribute
351
   * @param attrName key of the attribute
352
   * @return the attribute as string 
353
   * @throws Exception
354
   */
355
  public String getRequiredAttribute(XMLElement element,String attrName ) 
356
    throws InstallerException
357
  {
358
    String attr = element.getAttribute(attrName);
359
    if( attr == null )
360
    {
361
      parseError(element, "<" + element.getName() + 
362
        "> requires attribute '" + attrName + "'.");
363
    }
364
    return( attr );
365
  }
366
}