001    package com.thaiopensource.relaxng.impl;
002    
003    import java.io.IOException;
004    
005    import org.relaxng.datatype.DatatypeLibraryFactory;
006    import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
007    import org.xml.sax.EntityResolver;
008    import org.xml.sax.ErrorHandler;
009    import org.xml.sax.InputSource;
010    import org.xml.sax.SAXException;
011    
012    import com.oxygenxml.validate.nvdl.NvdlProperty;
013    import com.thaiopensource.relaxng.parse.Parseable;
014    import com.thaiopensource.util.PropertyId;
015    import com.thaiopensource.util.PropertyMap;
016    import com.thaiopensource.validate.AbstractSchema;
017    import com.thaiopensource.validate.IncorrectSchemaException;
018    import com.thaiopensource.validate.Option;
019    import com.thaiopensource.validate.Schema;
020    import com.thaiopensource.validate.SchemaReader;
021    import com.thaiopensource.validate.ValidateProperty;
022    import com.thaiopensource.validate.nrl.NrlProperty;
023    import com.thaiopensource.validate.rng.RngProperty;
024    import com.thaiopensource.xml.sax.XMLReaderCreator;
025    
026    public abstract class SchemaReaderImpl implements SchemaReader {
027      private static final PropertyId[] supportedPropertyIds = {
028        ValidateProperty.XML_READER_CREATOR,
029        ValidateProperty.ERROR_HANDLER,
030        RngProperty.DATATYPE_LIBRARY_FACTORY,
031        RngProperty.CHECK_ID_IDREF,
032        RngProperty.FEASIBLE,
033        NrlProperty.ATTRIBUTES_SCHEMA,
034        NvdlProperty.ATTRIBUTES_SCHEMA,
035      };
036    
037      public Schema createSchema(InputSource in, PropertyMap properties)
038              throws IOException, SAXException, IncorrectSchemaException {
039        SchemaPatternBuilder spb = new SchemaPatternBuilder();
040        XMLReaderCreator xrc = ValidateProperty.XML_READER_CREATOR.get(properties);
041        ErrorHandler eh = ValidateProperty.ERROR_HANDLER.get(properties);
042        EntityResolver er = ValidateProperty.ENTITY_RESOLVER.get(properties);
043        DatatypeLibraryFactory dlf = RngProperty.DATATYPE_LIBRARY_FACTORY.get(properties);
044        if (dlf == null)
045          dlf = new DatatypeLibraryLoader();
046        Pattern start = SchemaBuilderImpl.parse(createParseable(xrc, in, eh, er), eh, dlf, spb,
047                    properties.contains(NrlProperty.ATTRIBUTES_SCHEMA)||properties.contains(NvdlProperty.ATTRIBUTES_SCHEMA));
048        return wrapPattern(start, spb, properties);
049      }
050    
051      public Option getOption(String uri) {
052        return RngProperty.getOption(uri);
053      }
054    
055      static Schema wrapPattern(Pattern start, SchemaPatternBuilder spb, PropertyMap properties) throws SAXException, IncorrectSchemaException {
056        properties = AbstractSchema.filterProperties(properties, supportedPropertyIds);
057        if (properties.contains(RngProperty.FEASIBLE))
058          start = FeasibleTransform.transform(spb, start);
059        Schema schema = new PatternSchema(spb, start, properties);
060        if (spb.hasIdTypes() && properties.contains(RngProperty.CHECK_ID_IDREF)) {
061          ErrorHandler eh = ValidateProperty.ERROR_HANDLER.get(properties);
062          IdTypeMap idTypeMap = new IdTypeMapBuilder(eh, start).getIdTypeMap();
063          if (idTypeMap == null)
064            throw new IncorrectSchemaException();
065          Schema idSchema;
066          if (properties.contains(RngProperty.FEASIBLE))
067            idSchema = new FeasibleIdTypeMapSchema(idTypeMap, properties);
068          else
069            idSchema = new IdTypeMapSchema(idTypeMap, properties);
070          schema = new CombineSchema(schema, idSchema, properties);
071        }
072        return schema;
073      }
074    
075      protected abstract Parseable createParseable(XMLReaderCreator xrc, InputSource in, ErrorHandler eh, EntityResolver er);
076    }