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 }