001    package com.thaiopensource.validate.mns;
002    
003    import java.io.IOException;
004    import java.net.URL;
005    
006    import org.xml.sax.InputSource;
007    import org.xml.sax.SAXException;
008    import org.xml.sax.XMLReader;
009    
010    import com.oxygenxml.validate.nvdl.NvdlProperty;
011    import com.thaiopensource.util.PropertyMap;
012    import com.thaiopensource.util.PropertyMapBuilder;
013    import com.thaiopensource.validate.IncorrectSchemaException;
014    import com.thaiopensource.validate.Schema;
015    import com.thaiopensource.validate.SchemaReader;
016    import com.thaiopensource.validate.auto.AutoSchemaReader;
017    import com.thaiopensource.validate.auto.SchemaFuture;
018    import com.thaiopensource.validate.auto.SchemaReceiver;
019    import com.thaiopensource.validate.auto.SchemaReceiverFactory;
020    import com.thaiopensource.validate.nrl.NrlProperty;
021    import com.thaiopensource.validate.rng.CompactSchemaReader;
022    import com.thaiopensource.validate.rng.SAXSchemaReader;
023    
024    class SchemaReceiverImpl implements SchemaReceiver {
025      private static final String MNS_SCHEMA = "mns.rng";
026      private static final String RNC_MEDIA_TYPE = "application/x-rnc";
027      private final PropertyMap properties;
028      private final PropertyMap attributeSchemaProperties;
029      private final boolean attributesSchema;
030      private final SchemaReader autoSchemaLanguage;
031      private Schema mnsSchema = null;
032    
033      public SchemaReceiverImpl(PropertyMap properties) {
034        this.attributesSchema = properties.contains(NrlProperty.ATTRIBUTES_SCHEMA) ||
035                                                    properties.contains(NvdlProperty.ATTRIBUTES_SCHEMA);
036        PropertyMapBuilder builder = new PropertyMapBuilder(properties);
037        if (attributesSchema) {
038          attributeSchemaProperties = properties;
039          builder.put(NrlProperty.ATTRIBUTES_SCHEMA, null);
040          builder.put(NvdlProperty.ATTRIBUTES_SCHEMA, null);
041          this.properties = builder.toPropertyMap();
042        }
043        else {
044          this.properties = properties;
045          NrlProperty.ATTRIBUTES_SCHEMA.add(builder);
046          NvdlProperty.ATTRIBUTES_SCHEMA.add(builder);
047          attributeSchemaProperties = builder.toPropertyMap();
048        }
049        this.autoSchemaLanguage = new AutoSchemaReader(SchemaReceiverFactory.PROPERTY.get(properties));
050      }
051    
052      public SchemaFuture installHandlers(XMLReader xr) {
053        return new SchemaImpl(attributesSchema).installHandlers(xr, this);
054      }
055    
056      Schema getMnsSchema() throws IOException, IncorrectSchemaException, SAXException {
057       if (mnsSchema == null) {
058          String className = SchemaReceiverImpl.class.getName();
059          String resourceName = className.substring(0, className.lastIndexOf('.')).replace('.', '/') + "/resources/" + MNS_SCHEMA;
060          URL mnsSchemaUrl = getResource(resourceName);
061          mnsSchema = SAXSchemaReader.getInstance().createSchema(
062                  new InputSource(mnsSchemaUrl.toString()),
063                  properties);
064        }
065        return mnsSchema;
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, boolean isAttributesSchema) throws IOException, IncorrectSchemaException, SAXException {
082        SchemaReader lang = isRnc(schemaType) ? CompactSchemaReader.getInstance() : autoSchemaLanguage;
083        return lang.createSchema(inputSource,
084                                 isAttributesSchema ? attributeSchemaProperties : properties);
085      }
086    
087      private static boolean isRnc(String schemaType) {
088        if (schemaType == null)
089          return false;
090        schemaType = schemaType.trim();
091        return schemaType.equals(RNC_MEDIA_TYPE);
092      }
093    }