Source for gnu.xml.libxmlj.util.XMLJ

   1: /* XMLJ.java -
   2:    Copyright (C) 2004 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.xml.libxmlj.util;
  39: 
  40: import java.io.FileInputStream;
  41: import java.io.FileOutputStream;
  42: import java.io.InputStream;
  43: import java.io.IOException;
  44: import java.io.OutputStream;
  45: import java.io.Reader;
  46: import java.io.Writer;
  47: import java.net.MalformedURLException;
  48: import java.net.URL;
  49: import java.net.URLConnection;
  50: 
  51: import javax.xml.transform.Result;
  52: import javax.xml.transform.Source;
  53: import javax.xml.transform.sax.SAXSource;
  54: import javax.xml.transform.stream.StreamResult;
  55: import javax.xml.transform.stream.StreamSource;
  56: 
  57: import org.xml.sax.InputSource;
  58: 
  59: import gnu.xml.libxmlj.transform.GnomeTransformerFactory;
  60: 
  61: import gnu.xml.dom.ls.ReaderInputStream;
  62: import gnu.xml.dom.ls.WriterOutputStream;
  63: 
  64: /**
  65:  * Utility functions for libxmlj.
  66:  */
  67: public final class XMLJ
  68: {
  69: 
  70:   static class XMLJShutdownHook
  71:     implements Runnable
  72:   {
  73: 
  74:     public void run ()
  75:     {
  76:       // Make sure finalizers are run
  77:       System.gc ();
  78:       Runtime.getRuntime ().runFinalization ();
  79: 
  80:       // Perform global cleanup on the native level
  81:       GnomeTransformerFactory.freeLibxsltGlobal ();
  82:     }
  83: 
  84:   }
  85: 
  86:   private static boolean initialised = false;
  87: 
  88:   public static void init ()
  89:   {
  90:     if (!initialised)
  91:       {
  92:         System.loadLibrary ("xmlj");
  93: 
  94:         XMLJShutdownHook hook = new XMLJShutdownHook ();
  95:         Runtime.getRuntime ().addShutdownHook (new Thread (hook));
  96:       }
  97:     initialised = true;
  98:   }
  99: 
 100:   private static final int LOOKAHEAD = 50;
 101: 
 102:   /**
 103:    * Returns an input stream for the specified input source.
 104:    * This returns a pushback stream that libxmlj can use to detect the
 105:    * character encoding of the stream.
 106:    */
 107:   public static NamedInputStream getInputStream (InputSource input)
 108:     throws IOException
 109:   {
 110:     InputStream in = input.getByteStream ();
 111:     String systemId = input.getSystemId ();
 112:     if (in == null)
 113:       {
 114:        Reader r = input.getCharacterStream();
 115:        if (r != null)
 116:          in = new ReaderInputStream(r);
 117:       }
 118:     if (in == null)
 119:       {
 120:         in = getInputStream(systemId);
 121:       }
 122:     return new NamedInputStream (systemId, in, LOOKAHEAD);
 123:   }
 124: 
 125:   /**
 126:    * Returns an input stream for the specified transformer source.
 127:    * This returns a pushback stream that libxmlj can use to detect the
 128:    * character encoding of the stream.
 129:    */
 130:   public static NamedInputStream getInputStream (Source source)
 131:     throws IOException
 132:   {
 133:     if (source instanceof SAXSource)
 134:       {
 135:         return getInputStream (((SAXSource) source).getInputSource ());
 136:       }
 137:     InputStream in = null;
 138:     String systemId = source.getSystemId ();
 139:     if (source instanceof StreamSource)
 140:       {
 141:         in = ((StreamSource) source).getInputStream ();
 142:       }
 143:     if (in == null)
 144:       {
 145:         in = getInputStream(systemId);
 146:       }
 147:     return new NamedInputStream (systemId, in, LOOKAHEAD);
 148:   }
 149: 
 150:   private static InputStream getInputStream(String systemId)
 151:     throws IOException
 152:   {
 153:     if (systemId == null)
 154:       {
 155:         throw new IOException("no system ID");
 156:       }
 157:     try
 158:       {
 159:         return new URL(systemId).openStream();
 160:       }
 161:     catch (MalformedURLException e)
 162:       {
 163:         return new FileInputStream(systemId);
 164:       }
 165:   }
 166: 
 167:   /**
 168:    * Returns an input stream for the specified URL.
 169:    * This returns a pushback stream that libxmlj can use to detect the
 170:    * character encoding of the stream.
 171:    */
 172:   public static NamedInputStream getInputStream (URL url)
 173:     throws IOException
 174:   {
 175:     return new NamedInputStream (url.toString (), url.openStream(),
 176:                                  LOOKAHEAD);
 177:   }
 178: 
 179:   /**
 180:    * Convenience method for xmljDocLoader
 181:    */
 182:   static NamedInputStream xmljGetInputStream(String base, String url)
 183:     throws IOException
 184:   {
 185:     try
 186:       {
 187:         if (base != null)
 188:           {
 189:             url = new URL(new URL(base), url).toString();
 190:           }
 191:       }
 192:     catch (MalformedURLException e)
 193:       {
 194:       }
 195:     InputStream in = getInputStream(url);
 196:     return new NamedInputStream(url, in, LOOKAHEAD);
 197:   }
 198: 
 199:   /**
 200:    * Returns an output stream for the specified transformer result.
 201:    */
 202:   public static OutputStream getOutputStream (Result result)
 203:     throws IOException
 204:   {
 205:     OutputStream out = null;
 206:     if (result instanceof StreamResult)
 207:       {
 208:         out = ((StreamResult) result).getOutputStream ();
 209:       }
 210:     if (out == null)
 211:       {
 212:        Writer w = ((StreamResult) result).getWriter ();
 213:        if (w != null)
 214:          out = new WriterOutputStream (w);
 215:       }
 216:     if (out == null)
 217:       {
 218:         String systemId = result.getSystemId ();
 219:         if (systemId == null)
 220:           {
 221:             throw new IOException ("no system ID");
 222:           }
 223:         try
 224:           {
 225:             URL url = new URL (systemId);
 226:             URLConnection connection = url.openConnection ();
 227:             connection.setDoOutput (true);
 228:             out = connection.getOutputStream ();
 229:           }
 230:         catch (MalformedURLException e)
 231:           {
 232:             out = new FileOutputStream (systemId);
 233:           }
 234:       }
 235: 
 236:     return out;
 237:   }
 238: 
 239:   /**
 240:    * Returns the absolute form of the specified URI.
 241:    * If the URI is already absolute, returns it as-is.
 242:    * Otherwise returns a new URI relative to the given base URI.
 243:    */
 244:   public static String getAbsoluteURI (String base, String uri)
 245:   {
 246:     if (uri != null &&
 247:         base != null &&
 248:         (uri.length() > 0) &&
 249:         (uri.indexOf(':') == -1) &&
 250:         (uri.charAt(0) != '/'))
 251:       {
 252:         // URI is relative
 253:         if (base.charAt(base.length() - 1) != '/')
 254:           {
 255:             int i = base.lastIndexOf('/');
 256:             base = base.substring(0, i + 1);
 257:           }
 258:         return base + uri;
 259:       }
 260:     else
 261:       {
 262:         // URI is absolute or no base specified
 263:         return uri;
 264:       }
 265:   }
 266: 
 267:   public static String getBaseURI(String uri)
 268:   {
 269:     if (uri != null)
 270:       {
 271:         int si = uri.lastIndexOf('/');
 272:         if (si != -1)
 273:           {
 274:             uri = uri.substring(0, si + 1);
 275:           }
 276:       }
 277:     return uri;
 278:   }
 279: 
 280: }