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 }