Source for javax.xml.validation.SchemaFactory

   1: /* SchemaFactory.java -- 
   2:    Copyright (C) 2004, 2005, 2006  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 javax.xml.validation;
  39: 
  40: import java.io.BufferedReader;
  41: import java.io.File;
  42: import java.io.FileInputStream;
  43: import java.io.InputStream;
  44: import java.io.InputStreamReader;
  45: import java.io.IOException;
  46: import java.net.URL;
  47: import java.util.Properties;
  48: import javax.xml.XMLConstants;
  49: import javax.xml.transform.Source;
  50: import javax.xml.transform.stream.StreamSource;
  51: import org.w3c.dom.ls.LSResourceResolver;
  52: import org.xml.sax.ErrorHandler;
  53: import org.xml.sax.SAXException;
  54: import org.xml.sax.SAXNotRecognizedException;
  55: import org.xml.sax.SAXNotSupportedException;
  56: 
  57: /**
  58:  * Factory for obtaining schemata.
  59:  *
  60:  * @author Chris Burdess (dog@gnu.org)
  61:  * @since 1.5
  62:  */
  63: public abstract class SchemaFactory
  64: {
  65:   protected SchemaFactory()
  66:   {
  67:   }
  68: 
  69:   /**
  70:    * Returns an implementation of <code>SchemaFactory</code> that supports
  71:    * the specified schema language.
  72:    * @param schemaLanguage the URI of a schema language (see
  73:    * <code>XMLConstants</code>)
  74:    */
  75:   public static final SchemaFactory newInstance(String schemaLanguage)
  76:   {
  77:     ClassLoader loader = Thread.currentThread().getContextClassLoader();
  78:     if (loader == null)
  79:       {
  80:         loader = SchemaFactory.class.getClassLoader();
  81:       }
  82:     final String factoryClassName = "javax.xml.validation.SchemaFactory";
  83:     String className = null;
  84:     int count = 0;
  85:     do
  86:       {
  87:         className = getFactoryClassName(loader, schemaLanguage, count++);
  88:         if (className != null)
  89:           {
  90:             try
  91:               {
  92:                 Class t = (loader != null) ? loader.loadClass(className) :
  93:                     Class.forName(className);
  94:                 return (SchemaFactory) t.newInstance();
  95:               }
  96:             catch (Exception e)
  97:               {
  98:                 // Ignore any errors and continue algorithm.
  99:                 // This method doesn't have a means of propagating
 100:                 // class instantiation errors.
 101:                 className = null;
 102:               }
 103:         }
 104:     }
 105:     while (className == null && count < 2);
 106:     try
 107:       {
 108:         String serviceKey = "/META-INF/services/" + factoryClassName;
 109:         InputStream in = (loader != null) ?
 110:           loader.getResourceAsStream(serviceKey) :
 111:           SchemaFactory.class.getResourceAsStream(serviceKey);
 112:         if (in != null)
 113:           {
 114:             BufferedReader r =
 115:               new BufferedReader(new InputStreamReader(in));
 116:             try
 117:               {
 118:                 for (String line = r.readLine(); line != null;
 119:                         line = r.readLine())
 120:                   {
 121:                     Class t = (loader != null) ? loader.loadClass(className) :
 122:                         Class.forName(className);
 123:                     SchemaFactory ret = (SchemaFactory) t.newInstance();
 124:                     if (ret.isSchemaLanguageSupported(schemaLanguage))
 125:                       return ret;
 126:                   }
 127:               }
 128:             catch (Exception e)
 129:               {
 130:                 // Fall through. See above.
 131:               }
 132:             finally
 133:               {
 134:                 r.close();
 135:               }
 136:           }
 137:       }
 138:     catch (IOException e)
 139:       {
 140:       }
 141:     // Default schema factories for Classpath
 142:     if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schemaLanguage))
 143:       return new gnu.xml.validation.xmlschema.XMLSchemaSchemaFactory();
 144:     if (XMLConstants.RELAXNG_NS_URI.equals(schemaLanguage))
 145:       return new gnu.xml.validation.relaxng.RELAXNGSchemaFactory();
 146:     throw new IllegalArgumentException(schemaLanguage);
 147:   }
 148: 
 149:   private static String getFactoryClassName(ClassLoader loader,
 150:           String schemaLanguage, int attempt)
 151:   {
 152:     final String factoryClassName = "javax.xml.validation.SchemaFactory";
 153:     final String propertyName = factoryClassName + ":" + schemaLanguage;
 154:     switch (attempt)
 155:       {
 156:         case 0:
 157:           return System.getProperty(propertyName);
 158:         case 1:
 159:           try
 160:             {
 161:               File file = new File(System.getProperty("java.home"));
 162:               file = new File(file, "lib");
 163:               file = new File(file, "jaxp.properties");
 164:               InputStream in = new FileInputStream(file);
 165:               Properties props = new Properties();
 166:               props.load(in);
 167:               in.close();
 168:               return props.getProperty(propertyName);
 169:             }
 170:           catch (IOException e)
 171:             {
 172:               return null;
 173:             }
 174:         default:
 175:           return null;
 176:       }
 177:   }
 178: 
 179:   /**
 180:    * Indicates whether the specified schema language is supported.
 181:    * @param schemaLanguage the URI of a schema language (see
 182:    * <code>XMLConstants</code>)
 183:    */
 184:   public abstract boolean isSchemaLanguageSupported(String schemaLanguage);
 185: 
 186:   public boolean getFeature(String name)
 187:     throws SAXNotRecognizedException, SAXNotSupportedException
 188:   {
 189:     throw new SAXNotRecognizedException(name);
 190:   }
 191:   
 192:   public void setFeature(String name, boolean value)
 193:     throws SAXNotRecognizedException, SAXNotSupportedException
 194:   {
 195:     throw new SAXNotRecognizedException(name);
 196:   }
 197:   
 198:   public Object getProperty(String name)
 199:     throws SAXNotRecognizedException, SAXNotSupportedException
 200:   {
 201:     throw new SAXNotRecognizedException(name);
 202:   }
 203:   
 204:   public void setProperty(String name, Object value)
 205:     throws SAXNotRecognizedException, SAXNotSupportedException
 206:   {
 207:     throw new SAXNotRecognizedException(name);
 208:   }
 209:   
 210:   public abstract ErrorHandler getErrorHandler();
 211:   
 212:   public abstract void setErrorHandler(ErrorHandler errorHandler);
 213: 
 214:   public abstract LSResourceResolver getResourceResolver();
 215: 
 216:   public abstract void setResourceResolver(LSResourceResolver resourceResolver);
 217:   
 218:   /**
 219:    * Returns a schema based on the specified source resource.
 220:    * @param schema the source resource
 221:    */
 222:   public Schema newSchema(Source schema)
 223:     throws SAXException
 224:   {
 225:     return newSchema(new Source[] { schema });
 226:   }
 227: 
 228:   /**
 229:    * Returns a schema based on the specified source file.
 230:    * @param schema the source resource
 231:    */
 232:   public Schema newSchema(File schema)
 233:     throws SAXException
 234:   {
 235:     return newSchema(new StreamSource(schema));
 236:   }
 237:   
 238:   /**
 239:    * Returns a schema based on the specified URL.
 240:    * @param schema the source resource
 241:    */
 242:   public Schema newSchema(URL schema)
 243:     throws SAXException
 244:   {
 245:     return newSchema(new StreamSource(schema.toString()));
 246:   }
 247:   
 248:   /**
 249:    * Parses the specified sources, and combine them into a single schema.
 250:    * The exact procedure and semantics of this depends on the schema
 251:    * language.
 252:    * @param schemata the schema resources to load
 253:    */
 254:   public abstract Schema newSchema(Source[] schemata)
 255:     throws SAXException;
 256:   
 257:   /**
 258:    * Creates a special schema.
 259:    * The exact semantics of this depends on the schema language.
 260:    */
 261:   public abstract Schema newSchema()
 262:     throws SAXException;
 263:   
 264: }