package com.thaiopensource.relaxng.jaxp;

import com.thaiopensource.datatype.DatatypeLibraryLoader;
import com.thaiopensource.relaxng.parse.IllegalSchemaException;
import com.thaiopensource.relaxng.parse.Parseable;
import com.thaiopensource.relaxng.pattern.SchemaBuilderImpl;
import com.thaiopensource.relaxng.pattern.SchemaPatternBuilder;
import com.thaiopensource.resolver.Resolver;
import com.thaiopensource.resolver.xml.ls.LS;
import com.thaiopensource.resolver.xml.sax.SAXResolver;
import com.thaiopensource.xml.sax.DraconianErrorHandler;
import org.relaxng.datatype.DatatypeLibraryFactory;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;

import javax.xml.transform.Source;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.IOException;

public abstract class SchemaFactoryImpl extends SchemaFactory {
  private ErrorHandler errorHandler = null;
  private LSResourceResolver resourceResolver = null;
  private DatatypeLibraryFactory dlf = null;

  protected SchemaFactoryImpl() {
  }

  public void setErrorHandler(ErrorHandler errorHandler) {
    this.errorHandler = errorHandler;
  }

  public ErrorHandler getErrorHandler() {
    return errorHandler;
  }

  public void setResourceResolver(LSResourceResolver resourceResolver) {
    this.resourceResolver = resourceResolver;
  }

  public LSResourceResolver getResourceResolver() {
    return resourceResolver;
  }

  public Schema newSchema() throws SAXException {
    throw new UnsupportedOperationException();
  }

  public Schema newSchema(Source[] schemas) throws SAXException {
    if (schemas.length != 1)
      throw new UnsupportedOperationException();
    Source source = schemas[0];
    Resolver resolver = null;
    if (resourceResolver != null)
      resolver = LS.createResolver(resourceResolver);
    SAXResolver saxResolver = new SAXResolver(resolver);
    ErrorHandler eh = errorHandler;
    if (eh == null)
      eh = new DraconianErrorHandler();
    // XXX add a property to enable user to set this
    if (dlf == null)
      dlf = new DatatypeLibraryLoader();
    Parseable parseable = createParseable(source, saxResolver, eh);
    SchemaPatternBuilder spb = new SchemaPatternBuilder();
    try {
      return new SchemaImpl(spb, SchemaBuilderImpl.parse(parseable, eh, dlf, spb, false));
    }
    catch (IOException e) {
      throw new SAXException(e);
    }
    catch (IllegalSchemaException e) {
      // XXX not sure what we're supposed to do here
      throw new SAXException("invalid schema");
    }
  }

  abstract protected Parseable createParseable(Source source, SAXResolver resolver, ErrorHandler eh) throws SAXException;
}

@@ -696,16 +696,107 @@
 ception;
+%0Aimport org.xml.sax.SAXNotRecognizedException;%0Aimport org.xml.sax.SAXNotSupportedException;
 %0A%0Aimport
@@ -1132,17 +1132,417 @@
 ry d
-lf = null
+atatypeLibraryFactory = null;%0A  /* If this is true, then logically datatypeLibraryFactory is an instance of DatatypeLibraryLoader,%0A     but we create it lazily, so that we don't need to create it if the user specifies their own. */%0A  private boolean defaultDatatypeLibraryFactory = true;%0A  static final public String PROPERTY_DATATYPE_LIBRARY_FACTORY = %22http://relaxng.org/properties/datatype-library-factory%22
 ;%0A%0A 
@@ -2516,123 +2516,8 @@
 ();%0A
-    // XXX add a property to enable user to set this%0A    if (dlf == null)%0A      dlf = new DatatypeLibraryLoader();%0A
     
@@ -2725,11 +2725,35 @@
 eh, 
-dlf
+getDatatypeLibraryFactory()
 , sp
@@ -2977,16 +2977,16 @@
 hema%22);%0A
-
     %7D%0A  
@@ -2988,16 +2988,1146 @@
  %7D%0A  %7D%0A%0A
+  public void setProperty(String name, Object object) throws SAXNotRecognizedException, SAXNotSupportedException %7B%0A    if (PROPERTY_DATATYPE_LIBRARY_FACTORY.equals(name)) %7B%0A      if (object instanceof DatatypeLibraryFactory) %7B%0A        datatypeLibraryFactory = (DatatypeLibraryFactory)object;%0A        defaultDatatypeLibraryFactory = false;%0A      %7D%0A      else%0A        throw new SAXNotSupportedException(%22value of %5C%22%22 + PROPERTY_DATATYPE_LIBRARY_FACTORY +%0A                                           %22%5C%22 property does not implement org.relaxng.datatype.DatatypeLibraryFactory%22);%0A    %7D%0A    else%0A      super.setProperty(name, object);%0A  %7D%0A%0A  public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException %7B%0A    if (PROPERTY_DATATYPE_LIBRARY_FACTORY.equals(name))%0A      return getDatatypeLibraryFactory();%0A    return super.getProperty(name);%0A  %7D%0A%0A  private DatatypeLibraryFactory getDatatypeLibraryFactory() %7B%0A    if (defaultDatatypeLibraryFactory) %7B%0A      datatypeLibraryFactory = new DatatypeLibraryLoader();%0A      defaultDatatypeLibraryFactory = false;%0A    %7D%0A    return datatypeLibraryFactory;%0A  %7D%0A%0A
   abstra

Implement property for DatatypeLibraryFactory in JAXP interface.