package com.lafabrick.converter { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.net.URLLoader; import flash.net.URLRequest; import mx.rpc.xml.Schema; import mx.rpc.xml.SchemaManager; import mx.rpc.xml.SchemaTypeRegistry; import mx.rpc.xml.XMLDecoder; import mx.rpc.xml.XMLEncoder; /** * Distached when the import of XML to Object is complete */ [Event("importSuccess", type="com.lafabrick.converter.XSDEvent")] /** * Distached when the export of Object to XML is complete */ [Event("exportSuccess", type="com.lafabrick.converter.XSDEvent")] /** * Distached when there's a problem on loading XSD Schema, or during export/import operations */ [Event("conversionError", type="com.lafabrick.converter.XSDEvent")] public class XSDConverter extends EventDispatcher { /** * @private */ private var _schema:Schema; /** * @private */ private var _xmlEncoder:XMLEncoder; /** * @private */ private var _xmlDecoder:XMLDecoder; /** * @private */ private var _schemaManager:SchemaManager; /** * @private */ private var _schemaTypeRegistry : SchemaTypeRegistry; /** * Constructor */ public function XSDConverter() { _schema = new Schema(); _xmlDecoder = new XMLDecoder(); _xmlEncoder = new XMLEncoder(); _schemaManager = new SchemaManager(); _xmlDecoder.schemaManager = _schemaManager; _xmlEncoder.schemaManager = _schemaManager; _schemaTypeRegistry = SchemaTypeRegistry.getInstance(); } /** * @private * registration of all schema Types and related Classes */ private function registerSchemaType( schemaTypes : Vector.<XSDType> = null ) : void { for each( var obj : XSDType in schemaTypes ) { _schemaTypeRegistry.registerClass(new QName(_schema.targetNamespace.uri, obj.typeName), obj.classMapping); } } /** * @private * unregistration of all schema Types */ private function unregisterSchemaType( schemaTypes : Vector.<XSDType> = null ) : void { for each( var obj : XSDType in schemaTypes ) { _schemaTypeRegistry.unregisterClass(new QName(_schema.targetNamespace.uri, obj.typeName) ); } } /** * import a target XML to Object, following an XSD Schema file * @param xml source xml. Can be a String, XML, XMLList * @param xsdUrl the url of the target XSD Schema * @param schemaTypes a Vector of XSDType Object. Define all schema type of the XSD, with the mapped class * @see com.lafabrick.converter.XSDType * @see com.lafabrick.converter.XSDEvent */ public function importFromXml( xml : *, xsdUrl : String, schemaTypes : Vector.<XSDType> = null ) : void { _schemaManager.reset(); var urlLoader : URLLoader = new URLLoader(); urlLoader.addEventListener(IOErrorEvent.IO_ERROR, loadIoError ); urlLoader.addEventListener( Event.COMPLETE, function( event : Event ) : void { _schema.xml = XML( urlLoader.data ); _schemaManager.addSchema( _schema ); var evt : XSDEvent; try { registerSchemaType( schemaTypes ); var obj : * = _xmlDecoder.decode( xml, new QName( _schema.targetNamespace.uri, _schema.xml.*::element.@name) ); unregisterSchemaType( schemaTypes ); evt = new XSDEvent( XSDEvent.IMPORT_SUCCESS ); evt.data = obj; evt.message = "import complete"; dispatchEvent( evt ); } catch( e:Error ) { evt = new XSDEvent( XSDEvent.CONVERSION_ERROR ); evt.message = "[catch Error] problem decoding target XML ( Error message : "+e.message+" )"; dispatchEvent( evt ); } } ); urlLoader.load( new URLRequest( xsdUrl ) ); } /** * import a target XML to Object, following an XSD Schema file * @param target target Object * @param xsdUrl the url of the target XSD Schema * @param schemaTypes a Vector of XSDType Object. Define all schema type of the XSD, with the mapped class * @see com.lafabrick.converter.XSDType * @see com.lafabrick.converter.XSDEvent */ public function exportToXml( target : Object, xsdUrl : String, schemaTypes : Vector.<XSDType> = null ) : void { _schemaManager.reset(); var urlLoader : URLLoader = new URLLoader(); urlLoader.addEventListener(IOErrorEvent.IO_ERROR, loadIoError ); urlLoader.addEventListener( Event.COMPLETE, function( event : Event ) : void { _schema.xml = XML( urlLoader.data ); _schemaManager.addSchema( _schema ); var evt : XSDEvent; try { registerSchemaType( schemaTypes ); var obj : * = _xmlEncoder.encode( target, new QName( _schema.targetNamespace.uri, _schema.xml.*::element.@name) ); unregisterSchemaType( schemaTypes ); evt = new XSDEvent( XSDEvent.EXPORT_SUCCESS ); evt.data = obj; evt.message = "export complete"; dispatchEvent( evt ); } catch( e:Error ) { evt = new XSDEvent( XSDEvent.CONVERSION_ERROR ); evt.message = "[catch Error] problem encoding target object ( Error message : "+e.message+" )"; dispatchEvent( evt ); } } ); urlLoader.load( new URLRequest( xsdUrl ) ); } /** * @private * Distached an XSDEvent.CONVERSION_ERROR event, when there's a problem on loading XSD Schema */ private function loadIoError( event : IOErrorEvent ) : void { var evt : XSDEvent = new XSDEvent( XSDEvent.CONVERSION_ERROR ); evt.message = "[IOError] problem loading the XSD schema ( IOError message : "+event.text+" )"; dispatchEvent( evt ); } } }