package com;

import java.io.IOException;
import java.util.Hashtable;
import javax.xml.namespace.QName;

import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.xsd2inst.SampleXmlUtil;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class Schema2Instance {

	/**
	 * @param args
	 */
	static Hashtable schemas;
	public static void main(String[] args) 
	{
		populateImportedSchemas();
		printSchema2Instance();
	}
	private static void populateImportedSchemas()
	{
		schemas = new Hashtable();
		String product = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""+
				            "xmlns=\"http://example.org/prod\""+
				            "targetNamespace=\"http://example.org/prod\">"+
				
				      		"<xs:complexType name=\"ItemsType\">"+
				      			"<xs:sequence>"+
				      				"<xs:element name=\"productid\" type=\"string\"/>"+
				      			"</xs:sequence>"+
				      		"</xs:complexType>"+
				      	"<xs:schema>";	
		schemas.put("prod.xsd", product);

	}
	private static void printSchema2Instance()
	{
		try 
		{
			String rootElementName = "order";
			String sourceSchema = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""+
						    		" targetNamespace=\"http://example.org/ord\""+
						    		" xmlns=\"http://example.org/ord\""+
						    		" xmlns:prod=\"http://example.org/prod\">"+
									"<xs:import namespace=\"http://example.org/prod\""+
											" schemaLocation=\"prod.xsd\"/>"+
									" <xs:element name=\"order\" type=\"OrderType\"/>"+
										      " <xs:complexType name=\"OrderType\">"+
										      	" <xs:sequence>"+
										      		" <xs:element name=\"orderid\" type=\"xs:string\"/>"+
										      		" <xs:element name=\"items\" type=\"prod:ItemsType\"/>"+
										      	" </xs:sequence>"+
										      " </xs:complexType>" +
								"</xs:schema>";
			XmlOptions xmlOptions = new XmlOptions();
			MyEntityResolver myEntityResolver = new MyEntityResolver();
			xmlOptions.setEntityResolver(myEntityResolver);
			XmlObject schemaObj = XmlObject.Factory.parse(sourceSchema);
			XmlObject[] schemaArray = new XmlObject[1];
			schemaArray[0] = schemaObj;
			SchemaTypeSystem sts = XmlBeans.compileXsd(schemaArray, XmlBeans.getBuiltinTypeSystem(), xmlOptions);
			SchemaType globalElems[] = sts.documentTypes();
			SchemaType target = null;
	        for(int i = 0; i < globalElems.length; i++)
	        {
	        	String currElementName = globalElems[i].getDocumentElementName().getLocalPart();
	        	if(rootElementName.equals(currElementName))
	        	{
	        		target = globalElems[i];
	        		break;
	        	}
	        }
			/*SchemaTypeLoader stl = XmlBeans.loadXsd(schemaArray, xmlOptions);
			SchemaType st = stl.findDocumentType(new QName("catalog"));*/
			System.out.println("\n \n Result  : " + SampleXmlUtil.createSampleForType(target));
		} 
		catch (XmlException e) 
		{
			e.printStackTrace();
		}
	}
	public static class MyEntityResolver implements EntityResolver
	{
		public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException 
		{
			try 
			{
				System.out.println("MyEntityResolver.resolveEntity()    Namespace : " + arg0 + " SchemaLocation : " + arg1);
				String schema = (String)schemas.get(arg1);
				System.out.println("Returning from resolver.. Imported schema content : " + schema);
				return new InputSource(schema);
			} 
			catch (Exception e) 
			{
				e.printStackTrace();
				return null;
			}
			
		}
	}
}
