/* Uiml.Net: a Uiml.Net renderer (http://research.edm.uhasselt.be/kris/research/uiml.net/) Copyright (C) 2005 Kris Luyten (kris.luyten@uhasselt.be) Expertise Centre for Digital Media (http://edm.uhasselt.be) Hasselt University This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Authors: Jo Vermeulen jo.vermeulen@student.luc.ac.be */ using System; using System.Xml; using System.Collections; namespace Uiml.Peers { /// /// Summary description for Vocabulary. /// public class Vocabulary { // a Hashtable of (name, DClass) key-value pairs protected Hashtable m_dictDCls; // a Hashtable of (name, DComponent) key-value pairs protected Hashtable m_dictDCmp; protected string m_identifier; protected XmlDocument m_doc; protected string m_vocName; public Vocabulary() { m_dictDCls = new Hashtable(); m_dictDCmp = new Hashtable(); } public Vocabulary(string vocName) { m_dictDCls = new Hashtable(); m_dictDCmp = new Hashtable(); m_vocName = vocName; Load(vocName); } protected void Load(string vocName) { //first try to load the string "as is". If this does not work //try to load the online vocabulary provided this exists m_doc = new XmlDocument(); XmlTextReader xr = null; try { xr = new XmlTextReader(vocName); m_doc.Load(xr); Parse(); } catch(XmlException xe) { Console.WriteLine("Could not load {0} because of: ", vocName); Console.WriteLine(xe); Console.WriteLine("Trying other possible vocabulary locations..."); try { xr = new XmlTextReader(VOCABULARY_BASE + vocName + VOCABULARY_EXT); m_doc.Load(xr); Parse(); } catch(Exception e) { xr = new XmlTextReader(VOCABULARY_BASE2 + vocName + VOCABULARY_EXT); m_doc.Load(xr); Parse(); } } catch(Exception e) { Console.WriteLine("Could not load {0}", vocName); Console.WriteLine(e); } } public void MergeLogic(Logic l) { XmlNode logicNode = m_doc.ImportNode(l.Tag, true); XmlNode n = MoveToUimlElement(m_doc); if(n != null) { n.AppendChild(logicNode); ParseLogic(logicNode); } else throw new Exception("UIML file not in correct format. Could not find uiml element."); } protected void Parse(XmlNode n) { IEnumerator enumNodes = n.ChildNodes.GetEnumerator(); while(enumNodes.MoveNext()) { XmlNode c = (XmlNode) enumNodes.Current; switch(c.Name) { case Presentation.IAM: ParsePresentation(c); break; case Logic.IAM: ParseLogic(c); break; } } } protected void Parse() { XmlNode n = MoveToUimlElement(m_doc); if(n != null) Parse(n); else throw new Exception("Vocabulary not in correct format. Could not find uiml element."); } protected XmlNode MoveToUimlElement(XmlNode n) { n = n.FirstChild; while(n != null && !(n.Name == "uiml" && n.NodeType == XmlNodeType.Element)) { n = n.NextSibling; } return n; } protected void ParsePresentation(XmlNode n) { XmlNode b = n.Attributes.GetNamedItem(Presentation.BASE); try { m_identifier = b.Value; } catch(NullReferenceException nre) { Console.WriteLine("The presentation has no base attribute, please check your UIML file!"); Console.WriteLine(nre); } IEnumerator enumChildren = n.ChildNodes.GetEnumerator(); while(enumChildren.MoveNext()) { XmlNode c = (XmlNode) enumChildren.Current; switch(c.Name) { case DClass.IAM: ParseDClass(c); break; } } } protected void ParseLogic(XmlNode n) { IEnumerator enumChildren = n.ChildNodes.GetEnumerator(); while(enumChildren.MoveNext()) { XmlNode c = (XmlNode) enumChildren.Current; switch(c.Name) { case DComponent.IAM: ParseDComponent(c); break; } } } protected void ParseDClass(XmlNode n) { DClass cls = new DClass(n); AddDClass(cls.Identifier, cls); } protected void ParseDComponent(XmlNode n) { DComponent cmp = new DComponent(n); AddDComponent(cmp.Identifier, cmp); } /// /// Represents the <presentation> element's base attribute. /// public string Identifier { get { return m_identifier; } } protected void AddDClass(string abstractName, DClass cls) { try { m_dictDCls.Add(abstractName, cls); } catch(ArgumentException ae) { Console.WriteLine("Duplicate class entry: <{0}>", abstractName); Console.WriteLine("Please check the elements in the structure!"); } } protected void AddDComponent(string abstractName, DComponent cmp) { try { m_dictDCmp.Add(abstractName, cmp); } catch(ArgumentException ae) { Console.WriteLine("Duplicate component entry: <{0}>", abstractName); Console.WriteLine("Please check the elements in the structure!"); } } protected DClass FindDClass(string abstractName) { IDictionaryEnumerator e = m_dictDCls.GetEnumerator(); while (e.MoveNext()) { if(((string)e.Key) == abstractName) return (DClass) e.Value; } // no such class return null; } protected DComponent FindDComponent(string abstractName) { IDictionaryEnumerator e = m_dictDCmp.GetEnumerator(); while (e.MoveNext()) { if(((string)e.Key) == abstractName) return (DComponent) e.Value; } // no such component return null; } public string MapsOnCls(string abstractName) { DClass cls = FindDClass(abstractName); if(cls != null) return cls.MapsTo; else throw new MappingNotFoundException(abstractName); } public string MapsOnCmp(string abstractName) { DComponent cmp = FindDComponent(abstractName); if(cmp != null) return cmp.MapsTo; else throw new MappingNotFoundException(abstractName); } protected DMethod FindDMethod(ArrayList l, string identifier) { IEnumerator enumMethods = l.GetEnumerator(); while(enumMethods.MoveNext()) { DMethod method = ((DMethod)enumMethods.Current); if(method.Identifier == identifier) return method; } // no such method return null; } public string GetMethodCls(string identifier, string abstractName) { DClass cls = FindDClass(abstractName); if(cls == null) throw new MappingNotFoundException(abstractName); DMethod method = FindDMethod(cls.Search(typeof(DMethod)), identifier); if(method != null) return method.MapsTo; else throw new MappingNotFoundException(identifier); } public string GetMethodCmp(string identifier, string abstractName) { DComponent cmp = FindDComponent(abstractName); if(cmp == null) throw new MappingNotFoundException(abstractName); DMethod method = FindDMethod(cmp.Search(typeof(DMethod)), identifier); if(method != null) return method.MapsTo; else throw new MappingNotFoundException(identifier); } public Location GetLocationCmp(string abstractName) { DComponent cmp = FindDComponent(abstractName); if (cmp != null) return cmp.Location; else throw new MappingNotFoundException(abstractName); } protected DProperty FindDProperty(ArrayList l, string identifier) { IEnumerator e = l.GetEnumerator(); while(e.MoveNext()) { DProperty prop = ((DProperty)e.Current); if(prop.Identifier == identifier) return prop; } // no such property return null; } protected DProperty FindDProperty(ArrayList l, string identifier, string mapsType) { IEnumerator e = l.GetEnumerator(); while(e.MoveNext()) { DProperty prop = ((DProperty)e.Current); if(prop.Identifier == identifier && prop.MapsType == mapsType) return prop; } // no such property return null; } protected string GetProperty(string identifier, string abstractName, string mapsType) { DClass cls = FindDClass(abstractName); if(cls == null) throw new MappingNotFoundException(abstractName); DProperty prop = FindDProperty(cls.Search(typeof(DProperty)), identifier, mapsType); if(prop != null) return prop.MapsTo; else throw new MappingNotFoundException(abstractName, identifier); } public string GetPropertyGetter(string identifier, string abstractName) { return GetProperty(identifier, abstractName, DProperty.GET_METHOD); } public string GetPropertySetter(string identifier, string abstractName) { return GetProperty(identifier, abstractName, DProperty.SET_METHOD); } public string MapsOnHandler(string abstractName) { DClass cls = FindDClass(abstractName); if(cls == null || cls.MapsType != "delegate") throw new MappingNotFoundException(abstractName); return cls.MapsTo; } public string GetEventFor(string abstractName, string delegateTypeName) { DClass cls = FindDClass(abstractName); if(cls == null) throw new MappingNotFoundException(abstractName); // search through all elements IEnumerator enumProp = cls.Search(typeof(DProperty)).GetEnumerator(); while(enumProp.MoveNext()) { DProperty prop = ((DProperty)enumProp.Current); // search through all elements IEnumerator enumParam = prop.Search(typeof(DParam)).GetEnumerator(); while(enumParam.MoveNext()) { DParam param = ((DParam)enumParam.Current); if(param.Type == delegateTypeName) return prop.MapsTo; } } throw new MappingNotFoundException(delegateTypeName); } public DParam[] GetParams(string identifier, string abstractName) { DClass cls = FindDClass(abstractName); if(cls == null) throw new MappingNotFoundException(abstractName); DProperty prop = FindDProperty(cls.Search(typeof(DProperty)), identifier); if(prop != null) return (DParam[]) prop.Search(typeof(DParam)).ToArray(typeof(DParam)); else throw new MappingNotFoundException(identifier); } public DParam[] GetMethodParams(string componentName, string methodName) { DComponent cmp = FindDComponent(componentName); if(cmp == null) throw new MappingNotFoundException(componentName); DMethod method = FindDMethod(cmp.Search(typeof(DMethod)), methodName); if(method != null) return (DParam[]) method.Search(typeof(DParam)).ToArray(typeof(DParam)); else throw new MappingNotFoundException(methodName); } public Hashtable DClasses { get { return m_dictDCls; } } public Hashtable DComponents { get { return m_dictDCmp; } } public string VocabularyName { get { return m_vocName; } } public const string VOCABULARY_BASE = "http://uiml.org/toolkits/"; public const string VOCABULARY_BASE2 = "http://research.edm.uhasselt.be/kris/projects/uiml.net/"; public const string VOCABULARY_EXT = "uiml"; } }