001    package com.thaiopensource.validate.nrl;
002    
003    import com.thaiopensource.util.PropertyId;
004    import com.thaiopensource.util.PropertyMap;
005    import com.thaiopensource.util.PropertyMapBuilder;
006    import com.thaiopensource.validate.IncorrectSchemaException;
007    import com.thaiopensource.validate.Option;
008    import com.thaiopensource.validate.Schema;
009    import com.thaiopensource.validate.SchemaReader;
010    import com.thaiopensource.validate.ValidateProperty;
011    import com.thaiopensource.validate.auto.AutoSchemaReader;
012    import com.thaiopensource.validate.auto.SchemaFuture;
013    import com.thaiopensource.validate.auto.SchemaReceiver;
014    import com.thaiopensource.validate.auto.SchemaReceiverFactory;
015    import com.thaiopensource.validate.rng.CompactSchemaReader;
016    import com.thaiopensource.validate.rng.SAXSchemaReader;
017    import org.xml.sax.InputSource;
018    import org.xml.sax.SAXException;
019    import org.xml.sax.XMLReader;
020    
021    import java.io.IOException;
022    import java.net.URL;
023    
024    class SchemaReceiverImpl implements SchemaReceiver {
025      private static final String NRL_SCHEMA = "nrl.rng";
026      private static final String RNC_MEDIA_TYPE = "application/x-rnc";
027      private final PropertyMap properties;
028      private final boolean attributesSchema;
029      private final SchemaReader autoSchemaReader;
030      private Schema nrlSchema = null;
031      private static final PropertyId subSchemaProperties[] = {
032        ValidateProperty.ERROR_HANDLER,
033        ValidateProperty.XML_READER_CREATOR,
034        ValidateProperty.ENTITY_RESOLVER,
035        SchemaReceiverFactory.PROPERTY,
036      };
037    
038      public SchemaReceiverImpl(PropertyMap properties) {
039        this.attributesSchema = properties.contains(NrlProperty.ATTRIBUTES_SCHEMA);
040        PropertyMapBuilder builder = new PropertyMapBuilder();
041        for (int i = 0; i < subSchemaProperties.length; i++) {
042          Object value = properties.get(subSchemaProperties[i]);
043          if (value != null)
044            builder.put(subSchemaProperties[i], value);
045        }
046        this.properties = builder.toPropertyMap();
047        this.autoSchemaReader = new AutoSchemaReader(SchemaReceiverFactory.PROPERTY.get(properties));
048      }
049    
050      public SchemaFuture installHandlers(XMLReader xr) {
051        PropertyMapBuilder builder = new PropertyMapBuilder(properties);
052        if (attributesSchema)
053          NrlProperty.ATTRIBUTES_SCHEMA.add(builder);
054        return new SchemaImpl(builder.toPropertyMap()).installHandlers(xr, this);
055      }
056    
057      Schema getNrlSchema() throws IOException, IncorrectSchemaException, SAXException {
058       if (nrlSchema == null) {
059          String className = SchemaReceiverImpl.class.getName();
060          String resourceName = className.substring(0, className.lastIndexOf('.')).replace('.', '/') + "/resources/" + NRL_SCHEMA;
061          URL nrlSchemaUrl = getResource(resourceName);
062         nrlSchema = SAXSchemaReader.getInstance().createSchema(new InputSource(nrlSchemaUrl.toString()),
063                                                                  properties);
064        }
065        return nrlSchema;
066      }
067    
068      private static URL getResource(String resourceName) {
069        ClassLoader cl = SchemaReceiverImpl.class.getClassLoader();
070        // XXX see if we should borrow 1.2 code from Service
071        if (cl == null)
072          return ClassLoader.getSystemResource(resourceName);
073        else
074          return cl.getResource(resourceName);
075      }
076    
077      PropertyMap getProperties() {
078        return properties;
079      }
080    
081      Schema createChildSchema(InputSource inputSource, String schemaType, PropertyMap options, boolean isAttributesSchema) throws IOException, IncorrectSchemaException, SAXException {
082        SchemaReader reader = isRnc(schemaType) ? CompactSchemaReader.getInstance() : autoSchemaReader;
083        PropertyMapBuilder builder = new PropertyMapBuilder(properties);
084        if (isAttributesSchema)
085          NrlProperty.ATTRIBUTES_SCHEMA.add(builder);
086        for (int i = 0, len = options.size(); i < len; i++)
087          builder.put(options.getKey(i), options.get(options.getKey(i)));
088        return reader.createSchema(inputSource, builder.toPropertyMap());
089      }
090    
091      Option getOption(String uri) {
092        Option option = autoSchemaReader.getOption(uri);
093        if (option != null)
094          return option;
095        return CompactSchemaReader.getInstance().getOption(uri);
096      }
097    
098      private static boolean isRnc(String schemaType) {
099        if (schemaType == null)
100          return false;
101        schemaType = schemaType.trim();
102        return schemaType.equals(RNC_MEDIA_TYPE);
103      }
104    }