skip to main |
skip to sidebar
RSS Feeds
ASP.NET, JavaScript, Oracle and SQL articles and code.
ASP.NET, JavaScript, Oracle and SQL articles and code.
10:55 AM
Posted by Michael Heliso
When I moved to windows 7 (clean install) I have done a mistake regarding the order in which I have set up the development environment. First, by mistake, I have installed Visual Studio 2008, .NET framework 3.5 and at the end .NET framework 2.0.*. This caused a big issue on IIS 7. Every virtual directory or application created on IIS caused an error on the application pool. I have tried different application pools but got same error: “The worker process failed to preload .Net Runtime version v2.0.40607” and “The worker process failed to initialize correctly and therefore could not be started. The data is the error.”. After some searched over the internet I have found a solution HERE. The fix consists in removing from Windows\Microsoft.Net\Framework of any folder like v2.0.* which is different than v2.0.50727.
1:41 AM
Posted by Michael Heliso
I always felt the need to have in JavaScript a more robust set of collections, like those from .NET: ArrayList, Dictionary, strong typed collections. So, some time ago I have decided to implement them everything having as base the JavaScript array object. The code I assume is self explanatory except the class definition which makes use of the custom pattern presented earlier on this blog. It shouldn’t matter too much because it’s very easy for you to implement same functionality using any desired inheritance pattern, like Base2 and Prototype. I think it’s a matter of copy/paste in most cases. You will notice that I didn’t use any special tricks in the code, just the well known JavaScript array object methods and properties. I did not use closures in this case so the ‘_array ‘ property it is consider private base on ‘_’ notation. Using closures eats up more resources so I preferred to avoid them in his case. If you have any questions feel free to post them and I’ll try to give you an answer as fast as possible. You can download the source from HERE.
if (typeof (MG) == 'undefined') throw ("MG.Core.js is required!"); if (typeof (MG.Collections) == 'undefined') MG.Collections = {}; MG.Collections.IComparer = function() { throw ("IComparer is an interface. Interfaces can't be instantiated directly!"); }; MG.Collections.IComparer.prototype = { Compare: function(object1, object2) { } } /******************************************************************************/ // IList interface definition. /******************************************************************************/ MG.Collections.IList = function() { throw ("IList is an interface. Interfaces can't be instantiated directly!"); }; MG.Collections.IList.prototype = { ___name: "IList", Add: function(object) { }, Clear: function() { }, Contains: function(object) { }, Remove: function(object) { }, IsReadOnly: Boolean, Item: function(index) { } }; /******************************************************************************/ // ICollection interface definition. /******************************************************************************/ MG.Collections.ICollection = function() { throw ("ICollection is an interface. Interfaces can't be instantiated directly!"); }; MG.Collections.ICollection.prototype = { ___name: "ICollection", CopyTo: function(array, arrayIndex) { }, Count: function() { } }; /******************************************************************************/ // IDictionary interface definition. /******************************************************************************/ MG.Collections.IDictionary = function() { throw ("IDictionary is an interface. Interfaces can't be instantiated directly!"); }; MG.Collections.IDictionary.prototype = { ___name: "IDictionary", Add: function(key, value) { }, Clear: function() { }, Contains: function(key) { }, Remove: function(key) { }, IsReadOnly: Boolean, Item: function(key) { } } /******************************************************************************/ // ArrayList class definition. // Implements interfaces: ICollection /******************************************************************************/ MG.Collections.ArrayList = MG.Class.Create( { _array: null, IsReadOnly: Boolean, constructor: function() { this._array = []; this.IsReadOnly = false; }, Add: function(object) { if (!this.IsReadOnly) this._array.push(object); else throw ("ArrayList is read only! Check IsReadOnly value."); }, Clear: function() { if (!this.IsReadOnly) this._array = []; else throw ("ArrayList is read only! Check IsReadOnly value."); }, Contains: function(object) { for (var index = 0; index < this._array.length; index++) { if (this._array[index] == object) return true; } return false; }, CopyTo: function(array, arrayIndex) { if (!array) throw ("Destination array is null!"); if (arrayIndex < 0 || arrayIndex > array.length) throw ("Index of destination array out of bound! Index value is: " + arrayIndex); for (var i = this._array.length - 1; i >= 0; i--) array.splice(arrayIndex, 0, this._array[i]); }, Remove: function(object) { if (!this.IsReadOnly) { for (var index = 0; index < this._array.length; index++) { if (this._array[index] == object) this._array.splice(index, 1); } } else throw ("ArrayList is read only! Check IsReadOnly value."); }, Count: function() { return this._array.length; }, Item: function(index) { if (index < 0 || index >= this._array.length) throw ("Index out of bound! Index value is: " + index); return this._array[index]; }, IndexOf: function(object) { for (var index = 0; index < this._array.length; index++) { if (this._array[index] == object) return index; } return -1; }, LastIndexOf: function(object) { var lastIndex = -1; for (var index = 0; index < this._array.length; index++) { if (this._array[index] == object) lastIndex = index; } return lastIndex; }, RemoveAt: function(index) { if (!this.IsReadOnly) { if (index < 0 || index >= this._array.length) throw ("Index out of bound! Index value is: " + index); this._array.splice(index, 1); } else throw ("ArrayList is read only! Check IsReadOnly value."); }, RemoveRange: function(index, Count) { if (!this.IsReadOnly) { if (index < 0 || index >= this._array.length) throw ("Index out of bound! Index value is: " + index); if (Count < 0 || (Count + index) > this._array.length) throw ("Range out of bound! Range value is: " + Count); this._array.splice(index, Count); } else throw ("ArrayList is read only! Check IsReadOnly value."); }, InsertAt: function(index, object) { if (!this.IsReadOnly) { if (index < 0 || index >= this._array.length) throw ("Index out of bound! Index value is: " + index); this._array.splice(index, 0, object); } else throw ("ArrayList is read only! Check IsReadOnly value."); }, InsertRange: function(index, _ICollection) { if (!this.IsReadOnly) { if (index < 0 || index >= this._array.length) throw ("Index out of bound! Index value is: " + index); var _newarray = _ICollection.GetRange(0, _ICollection.Count()); for (var i = 0; i < _newarray.length; i++) this.InsertAt(index, _newarray[i]); } else throw ("ArrayList is read only! Check IsReadOnly value."); }, GetRange: function(index, Count) { if (index < 0 || index >= this._array.length) throw ("Index out of bound! Index value is: " + index); if (Count < 0 || (Count + index) > this._array.length) throw ("Range out of bound! Range value is: " + Count); var arrayList = new ArrayList(); arrayList._array = this._array.slice(index, (Count + index)); return arrayList; }, Reverse: function() { if (!this.IsReadOnly) this._array.reverse(); else throw ("ArrayList is read only! Check IsReadOnly value."); }, Sort: function() { this._array.sort(); } }, null, [MG.Collections.ICollection]); /******************************************************************************/ // DictionaryEntry class definition. /******************************************************************************/ MG.Collections.DictionaryEntry = MG.Class.Create( { key: null, value: null, constructor: function(key, value) { this.key = key; this.value = value; } }); /******************************************************************************/ // Dictionary class definition. // Implements interfaces: IDictionary // ICollection /******************************************************************************/ MG.Collections.Dictionary = MG.Class.Create( { _dictionary: null, IsReadOnly: Boolean, constructor: function() { this._dictionary = []; this.IsReadOnly = false; }, Add: function(key, value) { if (!this.IsReadOnly) { if (this.Contains(key)) throw ("Dictionary does not allow duplicate keys!"); var dicEntry = new MG.Collections.DictionaryEntry(key, value); this._dictionary.push(dicEntry); } else throw ("Dictionary is read only! Check IsReadOnly value."); }, Clear: function() { if (!this.IsReadOnly) this._dictionary = []; else throw ("Dictionary is read only! Check IsReadOnly value."); }, Contains: function(key) { for (var index = 0; index < this._dictionary.length; index++) { if (this._dictionary[index].key == key) return true; } return false; }, Remove: function(key) { if (!this.IsReadOnly) { for (var index = 0; index < this._dictionary.length; index++) { if (this._dictionary[index].key == key) this._dictionary.splice(index, 1); } } else throw ("Dictionary is read only! Check IsReadOnly value."); }, Item: function(key) { if (!key) throw ("Invalid key! Key value is: " + key); for (var index = 0; index < this._dictionary.length; index++) { if (this._dictionary[index].key == key) return this._dictionary[index].value; } return null; }, CopyTo: function(array, arrayIndex) { if (!array) throw ("Destination array is null!"); if (arrayIndex < 0 || arrayIndex > array.length) throw ("Index of destination array out of bound! Index value is: " + arrayIndex); for (var i = this._dictionary.length - 1; i >= 0; i--) array.splice(arrayIndex, 0, this._dictionary[i]); }, Count: function() { return this._dictionary.length; }, Keys: function() { var keys = []; for (var index = 0; index < this._dictionary.length; index++) keys.push(this._dictionary[index].key); return keys.reverse(); }, Values: function() { var values = []; for (var index = 0; index < this._dictionary.length; index++) values.push(this._dictionary[index].value); return values.reverse(); }, IndexOf: function(key) { var keys = []; for (var index = 0; index < this._dictionary.length; index++) { if (this._dictionary[index].key == key) return index; } }, InsertAt: function(index, key, value) { if (!this.IsReadOnly) { if (index < 0 || index >= this._dictionary.length) throw ("Index out of bound! Index value is: " + index); var dicEntry = new MG.Collections.DictionaryEntry(key, value); this._dictionary.splice(index, 0, dicEntry); } else throw ("Dictionary is read only! Check IsReadOnly value."); }, Reverse: function() { if (!this.IsReadOnly) this._dictionary.reverse(); else throw ("Dictionary is read only! Check IsReadOnly value."); } }, null, [MG.Collections.IDictionary, MG.Collections.ICollection]); /******************************************************************************/ // Comparer class definition. // Implements interfaces: IComparer /******************************************************************************/ MG.Collections.Comparer = MG.Class.Create({ constructor: function() { }, Compare: function(object1, object2) { var result = false; var type = typeof object1; if (type !== typeof object2) throw ("Object 'object1' doesn't have same type as object 'object2'!"); else if (type === "object") { switch (object1.constructor) { case Array: { if (object1.length === object2.length) { for (var index = 0; index < object1.length; index++) { result = this.Compare(object1[index], object2[index]); if (!result) break; } } } break; case Dictionary: { if (object1.Count() === object2.Count()) { var keys = object1.Keys(); for (var index = 0; index < keys.length; index++) { if (object2.Contains(keys[index])) { result = this.Compare(object1.Item(keys[index]), object2.Item(keys[index])); if (!result) break; } else { result = false; break; } } } } break; case ArrayList: { if (object1.Count() === object2.Count()) { for (var index = 0; index < object1.Count(); index++) { result = this.Compare(object1.Item(index), object2.Item(index)); if (!result) break; } } } break; default: { if (object1 === object2) result = true; } break; } } switch (type) { case "string": case "number": case "boolean": if (object1 === object2) result = true; break; } return result; } }, null, [MG.Collections.IComparer]); MG.Collections.TypedCollection = MG.Class.Create({ Type: null, Browser: null, constructor: function(type) { var _type = typeof type; if (_type && _type === "function") this.Type = type; else throw ("The 'type' parameter must be a function object."); this.Browser = MG.Browser.getInstance(); }, Add: function() { var key = null; var value = null; if (arguments.length == 2) { key = arguments[0]; value = arguments[1]; } else if (arguments.length == 1) value = arguments[0]; else throw ("Invalid number of parameters. Number of parameters expected is two or one."); if (this.Browser.NS) { if (value.constructor !== this.Type.constructor) throw ("The 'value' parameter doesn't have same type as this collection."); } else if (this.Browser.IE) { if (value.constructor !== this.Type) throw ("The 'value' parameter doesn't have same type as this collection."); } if (!this.IsReadOnly) { if (key) { var dicEntry = new MG.Collections.DictionaryEntry(key, value); this._dictionary.push(dicEntry); } else { var dicEntry = new MG.Collections.DictionaryEntry("key", value); this._dictionary.push(dicEntry); } } else throw ("Dictionary is read only! Check IsReadOnly value."); }, Item: function() { if (!arguments.length == 1) throw ("Invalid number of parameters. Number of parameters expected is two or one."); var arg = arguments[0]; var type = typeof arg; var value = null; if (type == "string") value = this.___Item(arg); else if (type == "number") { if (this._dictionary.length > arg) value = this._dictionary[arg].value; else throw ("Index is out of range."); } return value; } }, MG.Collections.Dictionary, null);
9:51 AM
Posted by Michael Heliso
Here is a small library/wrapper for JavaScript XML. Some parts of it belong to other authors like the Opera serialization and the loading of the XML document from a string. I had to do a lot of work on the part related to namespaces, especially on Opera. At this time, the library doesn’t work under Chrome if the XML document makes use of namespaces. So you will not be able to create XPath expression for namespace-d XML documents under Chrome browser. You will notice that the library exposes two layers, first of them is an abstraction of the native DOM and of all its functionality and the second one is the native DOM its self. I have used this library for different XML related tasks; the most important one in my case is the SOAP library and the .NET DataSet serialization to JavaScript data objects. I’m too lazy to explain it in details, but if you have questions feel free to ask them and I’ll give you an answer as fast as possible. You can download the source from HERE
if (typeof (MG) == 'undefined') throw ("MG.Core.js is required!"); if(typeof(MG.Collections) === 'undefined') throw ("MG.Collections.js is required!"); if (typeof (MG.Xml) == 'undefined') MG.Xml = {}; MG.Xml.XmlDocument = function(rootTagName, namespaceURL) { if(document.implementation && document.implementation.createDocument) { Document.prototype.loadXML = function(strXML) { var domParser = new DOMParser(); var xmlDoc = domParser.parseFromString(strXML, "text/xml"); while(this.hasChildNodes()) this.removeChild(this.lastChild); for(var index = 0; index < xmlDoc.childNodes.length; index++) { var impNode = this.importNode(xmlDoc.childNodes[index], true); this.appendChild(impNode); } var nsResolvers = new MG.Collections.Dictionary(); if(xmlDoc.childNodes.length > 0) { nsResolvers = fixNS(strXML); } function fixNS(xml) { var regEx = /<[a-z\dA-Z\d]+:/g; var results = xml.match(regEx); var prefixes = new MG.Collections.ArrayList(); var resolvedPrefixes = new MG.Collections.ArrayList(); var unresolvedPrefixes = new MG.Collections.ArrayList(); var count = results !== null ? results.length : 0; for(var index = 0; index < count; index++) { var matchValue = results[index]; var value = matchValue.slice(1, matchValue.length - 1); if(prefixes.IndexOf(value) < 0) prefixes.Add(value); } regEx = /:[a-zA-Z]+=|[a-zA-Z]+=/g; results = xml.match(regEx); count = results !== null ? results.length : 0; var prefixesCount = prefixes.Count(); for(var index = 0; index < prefixesCount; index++) { var resolved = false; var prefix = prefixes.Item(index); for(var j = 0; j < count; j++) { var attribute = results[j]; var value= null; if(attribute.indexOf(":") === 0) value = attribute.slice(1, attribute.length - 1); else value = attribute.slice(0, attribute.length - 1); if(prefix === value) { if(resolvedPrefixes.IndexOf(value) < 0) resolvedPrefixes.Add(prefixes.Item(index)); resolved = true; } else { if(resolvedPrefixes.IndexOf(value) < 0) resolvedPrefixes.Add(value); } } if(!resolved) unresolvedPrefixes.Add(prefixes.Item(index)); } var uniqueNamespaces = new MG.Collections.Dictionary(); var exPrefixesCount = resolvedPrefixes.Count(); for(var index = 0; index < exPrefixesCount; index++) { var prefix = resolvedPrefixes.Item(index); var regexS = "\\b" + prefix + "=\s*\".*?\""; var regex = new RegExp(regexS); var results = regex.exec(xml); if(results !== null && results.length > 0) { var prefixValues = new MG.Collections.ArrayList(); for(var j = 0; j < results.length; j++) { var value = results[j].substring(prefix.length + 2, results[j].length - 1); prefixValues.Add(value); } uniqueNamespaces.Add(prefix, prefixValues); } } return uniqueNamespaces; } function createNSResolvers(node) { var childNodes = node.childNodes; for(var index = 0; index < childNodes.length; index++) { var prefix = childNodes[index].prefix; var nsURI = childNodes[index].namespaceURI; if(prefix && nsURI) { if(!nsResolvers.Item(prefix)) nsResolvers.Add(prefix, nsURI); } createNSResolvers(childNodes[index]); } } this.nsResolvers = nsResolvers; } function __getXml() { var xmlSerializer = new XMLSerializer(); var xml = xmlSerializer.serializeToString(this); return xml; } if(Node.prototype.__defineGetter__) Node.prototype.__defineGetter__("xml", __getXml); return new MG.Xml.XmlNode(document.implementation.createDocument(namespaceURL, rootTagName, null)); } else { var doc = new ActiveXObject("MSXML2.DOMDocument"); if(rootTagName) { var prefix = ""; var tagName = rootTagName; var pos = rootTagName.indexOf(":"); if(pos != -1) { rootTagName = rootTagName.substring(0, pos); tagName = rootTagName.substring(pos + 1); } if (namespaceURL) { if (!prefix) prefix = "a0"; } else prefix = ""; var text = "<" + (prefix?(prefix+":"):"") + tagName + (namespaceURL?(" xmlns:" + prefix + '="' + namespaceURL +'"'):"") + "/>"; doc.loadXML(text); } return new MG.Xml.XmlNode(doc); } }; MG.Xml.XmlNode = function(nativeNode) { if(nativeNode) { this.NativeNode = nativeNode; this.NativeAttributes = nativeNode.attributes; this.NativeChildNodes = nativeNode.childNodes; } }; MG.Xml.XmlNode.prototype.mdcXPath = function(node, xpathExpression, queryType) { var xpe = new XPathEvaluator(); var nsResolver = function(prefix) { var nsResolvers = node.nsResolvers; if(!nsResolvers) nsResolvers = node.ownerDocument.nsResolvers; var item = nsResolvers.Item(prefix); if(item) { if (item.Count() > 0) { return item.Item(0); } } else return xpe.createNSResolver(node.ownerDocument == null ? node.documentElement : node.ownerDocument.documentElement); }; var result = xpe.evaluate(xpathExpression, node, nsResolver, queryType, null); return result; }; MG.Xml.XmlNode.prototype.fixNameSpaces = function(node, nsResolvers, xml) { if(nsResolvers) { if(node.prefix) { var nsResolver = nsResolvers.Item(node.prefix); if(nsResolver) { xml += " " + "xmlns:" + node.prefix + "=\"" + nsResolver + "\""; nsResolvers.Remove(node.prefix); } } for(var index = 0; index < node.childNodes.length; index++) xml = this.fixNameSpaces(node.childNodes[index], nsResolvers, xml); } return xml; }
MG.Xml.XmlNode.prototype.operaSerialize = function(nativeNode) { var xml = null; switch(nativeNode.nodeType) { case 1: { if(this.Name() === nativeNode.nodeName) xml = "<" + nativeNode.localName; else xml = "<" + nativeNode.tagName; var nsResolvers = null; var xmlnsAdded = false; for (var i = 0; i < nativeNode.attributes.length; i++) { var localName = nativeNode.attributes[i].localName; var name = nativeNode.attributes[i].name; var value = nativeNode.attributes[i].value; if(this.Name() === nativeNode.nodeName) { if(nativeNode.ownerDocument) { nsResolvers = nativeNode.ownerDocument.nsResolvers; if(nsResolvers && nativeNode.ownerDocument.nsResolvers.Contains(localName)) nsResolvers.Remove(localName); } else { nsResolvers = nativeNode.nsResolvers; if(nsResolvers && nsResolvers.Contains(name)) nsResolvers.Remove(name); } } if(name === "xmlns") xmlnsAdded = true; xml += " " + name + "=\"" + value + "\""; } if(this.Name() === nativeNode.nodeName) { if(!nsResolvers) { if(nativeNode.ownerDocument) nsResolvers = nativeNode.ownerDocument.nsResolvers; else nsResolvers = nativeNode.nsResolvers; } if(nsResolvers) { var item = nsResolvers.Item("xmlns"); if(item) xml += " " + "xmlns" + "=\"" + item + "\""; else if(!xmlnsAdded) xml += " " + "xmlns" + "=\"" + "http://tempuri.org/" + "\""; xml = this.fixNameSpaces(nativeNode, nsResolvers, xml); } } xml += ">"; for (var i = 0; i < nativeNode.childNodes.length; i++) xml += this.operaSerialize(nativeNode.childNodes[i]); if(this.Name() === nativeNode.nodeName) xml += "</" + nativeNode.localName + ">"; else xml += "</" + nativeNode.tagName + ">"; } break; case 3: xml = nativeNode.nodeValue; break; case 4: xml = "<![CDATA[" + nativeNode.nodeValue + "]]>"; break; case 7: xml = "<?" + nativeNode.nodevalue + "?>"; break; case 8: xml = "<!--" + nativeNode.nodevalue + "-->"; break; case 9: { for (var i = 0; i < nativeNode.childNodes.length; i++) xml += this.operaSerialize(nativeNode.childNodes[i]); } break; } return xml; };
MG.Xml.XmlNode.prototype.ChildNodes = function(index) { if(this.NativeChildNodes) { if(arguments.length === 0) return new MG.Xml.XmlNodes(this.NativeChildNodes); else { var nativeNode = this.NativeChildNodes[index]; return (new MG.Xml.XmlNode(nativeNode)); } } return null; }; MG.Xml.XmlNode.prototype.NextSibling = function() { if(this.NativeNode) return new MG.Xml.XmlNode(this.NativeNode.nextSibling); return null; }; MG.Xml.XmlNode.prototype.FirstChild = function() { if(this.NativeNode) return new MG.Xml.XmlNode(this.NativeNode.firstChild); return null; }; MG.Xml.XmlNode.prototype.Name = function() { if(this.NativeNode) { var browser = MG.Browser.getInstance(); if(browser.NS || browser.OPERA) return this.NativeNode.nodeName; else if(browser.IE) return this.NativeNode.nodeName; } return null; }; MG.Xml.XmlNode.prototype.LocalName = function() { if(this.NativeNode) { var browser = MG.Browser.getInstance(); if(browser.NS || browser.OPERA) return this.NativeNode.localName; else if(browser.IE) return this.NativeNode.baseName; } return null; }; MG.Xml.XmlNode.prototype.Text = function() { if(this.NativeNode) { var browser = MG.Browser.getInstance(); if(arguments.length === 1) { if(browser.NS || browser.OPERA) return this.NativeNode.textContent = arguments[0]; else if(browser.IE) return this.NativeNode.text = arguments[0]; } else if(arguments.length === 0) { if(browser.NS || browser.OPERA) return this.NativeNode.textContent; else if(browser.IE) return this.NativeNode.text; } else throw("Only one parameter is expected."); } return null; }; MG.Xml.XmlNode.prototype.Value = function() { if(this.NativeNode) { if(arguments.length === 1) this.NativeNode.nodeValue = arguments[0]; else if(arguments.length === 0) return this.NativeNode.nodeValue; else throw("Only one parameter is expected."); } }; MG.Xml.XmlNode.prototype.Xml = function() { if(this.NativeNode) { var browser = MG.Browser.getInstance(); if(browser.NS || browser.IE) return this.NativeNode.xml; else if(browser.OPERA) return this.NativeNode.xml; } return null; }; MG.Xml.XmlNode.prototype.SelectSingleNode = function(xpathExpression) { if(this.NativeNode) { var nativeNode = null; var browser = MG.Browser.getInstance(); if(browser.NS || browser.OPERA) { var result = this.mdcXPath(this.NativeNode, xpathExpression, XPathResult.FIRST_ORDERED_NODE_TYPE); nativeNode = result ? result.singleNodeValue : null; } else if(browser.IE) nativeNode = this.NativeNode.selectSingleNode(xpathExpression); if(nativeNode) return new MG.Xml.XmlNode(nativeNode); } return null; }; MG.Xml.XmlNode.prototype.SelectNodes = function(xpathExpression) { if(this.NativeNode) { var nativeNodes = null; var browser = MG.Browser.getInstance(); if(browser.NS || browser.OPERA) { var result = this.mdcXPath(this.NativeNode, xpathExpression, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); if(result) { var pseudoNodes = new MG.Collections.ArrayList(); for(var index = 0; index < result.snapshotLength; index++) pseudoNodes.Add(new MG.Xml.XmlNode(result.snapshotItem(index))); nativeNodes = pseudoNodes; } } else if(browser.IE) nativeNodes = this.NativeNode.selectNodes(xpathExpression); if(nativeNodes) return new MG.Xml.XmlNodes(nativeNodes); } return null; }; MG.Xml.XmlNode.prototype.CreateNode = function(type, name, namespaceURI) { if(this.NativeNode) { var nativeNode = this.NativeNode.createNode(type, name, namespaceURI); if(nativeNode) return new MG.Xml.XmlNode(nativeNode); } return null; }; MG.Xml.XmlNode.prototype.AppendChild = function(node) { if(this.NativeNode) this.NativeNode.appendChild(node.NativeNode); }; MG.Xml.XmlNode.prototype.RemoveChild = function(node) { if(this.NativeNode) this.NativeNode.removeChild(node.NativeNode); }; MG.Xml.XmlNode.prototype.ReplaceChild = function(newNode, oldNode) { if(this.NativeNode) this.NativeNode.replaceChild(newNode.NativeNode, oldNode.NativeNode); }; MG.Xml.XmlNode.prototype.ParentNode = function() { if(this.NativeNode) return new MG.Xml.XmlNode(this.NativeNode.parentNode); return null; }; MG.Xml.XmlNode.prototype.Prefix = function() { if(this.NativeNode) return this.NativeNode.prefix; return null; }; MG.Xml.XmlNode.prototype.LoadXML = function(xmlString) { this.NativeNode.loadXML(xmlString); }; MG.Xml.XmlNode.prototype.SetAttributeNode = function(attributeNode) { if(this.NativeNode) this.NativeNode.setAttributeNode(attributeNode.NativeAttribute); }; MG.Xml.XmlNode.prototype.SetAttribute = function(name, value) { if(this.NativeNode) this.NativeNode.setAttribute(name, value); }; MG.Xml.XmlNode.prototype.Attributes = function() { if(this.NativeAttributes) return new MG.Xml.Attributes(this.NativeAttributes); return null; }; MG.Xml.Attributes = function(nativeAttributes) { this.NativeAttributes = nativeAttributes; }; MG.Xml.Attributes.prototype.GetNamedItem = function(itemName) { if(this.NativeAttributes) return new MG.Xml.Attribute(this.NativeAttributes.getNamedItem(itemName)); return null; }; MG.Xml.Attributes.prototype.Item = function(index) { if(this.NativeAttributes) return new MG.Xml.Attribute(this.NativeAttributes[index]); return null; }; MG.Xml.Attributes.prototype.Length = function() { if(this.NativeAttributes) return this.NativeAttributes.length; return null; }; MG.Xml.Attribute = function(nativeAttribute) { this.NativeAttribute = nativeAttribute; }; MG.Xml.Attribute.prototype.Value = function() { if(this.NativeAttribute) return this.NativeAttribute.value; }; MG.Xml.Attribute.prototype.Name = function() { if(this.NativeAttribute) return this.NativeAttribute.name; }; MG.Xml.XmlNodes = function(nativeNodes) { var isPseudo = false; var browser = MG.Browser.getInstance(); if(browser.NS || browser.OPERA) { if(nativeNodes.constructor === MG.Collections.ArrayList.constructor) isPseudo = true; } else if(browser.IE) { if(nativeNodes.constructor === MG.Collections.ArrayList) isPseudo = true; } if(!isPseudo) { this.NativeNodes = new MG.Collections.ArrayList(); for(var index = 0; index < nativeNodes.length; index++) this.NativeNodes.Add(new MG.Xml.XmlNode(nativeNodes[index])); } else this.NativeNodes = nativeNodes; }; MG.Xml.XmlNodes.prototype.Length = function() { if(this.NativeNodes) { var browser = MG.Browser.getInstance(); if(browser.NS || browser.OPERA) { if(this.NativeNodes.constructor === MG.Collections.ArrayList.constructor) return this.NativeNodes.Count(); else return this.NativeNodes.length; } else if(browser.IE) { if(this.NativeNodes.constructor === MG.Collections.ArrayList) return this.NativeNodes.Count(); else return this.NativeNodes.length; } } return null; }; MG.Xml.XmlNodes.prototype.Item = function(index) { if(this.NativeNodes) return this.NativeNodes.Item(index); return null; };
6:09 AM
Posted by Michael Heliso
Today I tried to create a Gmail account for a friend of mine. I was stupefied when I saw that they require you to provide your phone number to confirm that you are not a spammer. This is crap, the capcha is more than enough to do the job. They are going to far this time.
BWOOOOO!!
1:56 AM
Posted by Michael Heliso
Here are the benchmark results from JSLitmus for JavaScript inheritance from Mugen library which I have presented in the previous posts compared with other existing JavaScript libraries.
1. Results for IE7
9:38 AM
Posted by Michael Heliso
Here are two different approaches in using the previous motioned inheritance technique.
1. Standard way where all members are public:
var Human = MG.Class.Create({ Gender: null, constructor: function(gender) { this.Gender = gender; }, IsMale: function() { return this.Gender == 'F' ? false : true; }, GenderString: function() { return this.Gender == 'F' ? "female" : "male"; }, ToOverride: function() { return "Called from Human"; } }, null, null); var Individual = MG.Class.Create({ Unique: null, constructor: function(unique) { this.Unique = unique; }, IsUnique: function() { return this.Unique ? "Yes" : "No"; }, DummyMethod: function() { return "Individual dummy method."; }, ToOverride: function() { return "Called from Individual which is " + (this.Unique ? "unique" : "not unique") + " / " + this.base(); } }, Human, null); var Person = MG.Class.Create({ constructor: function(firstName, lastName, birthDate) { this.FirstName = firstName; this.LastName = lastName; this.BirthDate = birthDate; }, GetName: function() { return this.FirstName + " " + this.LastName; }, GetDetails: function() { return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate; }, ToOverride: function() { return "Called from Person with first name " + this.FirstName + " / " + this.base(); } }, Individual, null); var Jhon = MG.Class.Create({ constructor: function(age) { this.Age = age; }, GetDetails: function() { return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate + "."; }, ToOverride: function() { return "Called from Jhon/ " + this.base(); } }, Person, null);
var Human = MG.Class.Create({ constructor: function(gender) { this.Gender = gender; return { IsMale: function() { return this.Gender == 'F' ? false : true; }, GenderString: function() { return this.Gender == 'F' ? "female" : "male"; }, ToOverride: function() { return "Called from Human"; } }; } }, null, null); var Individual = MG.Class.Create({ constructor: function(unique) { this.Unique = unique; var PrivateDummyMethod = function() { return "Individual dummy method."; }; return { IsUnique: function() { return this.Unique ? "Yes" : "No"; }, ToOverride: function() { return "Called from Individual / " + this.base(); } }; } }, Human, null); var Person = MG.Class.Create({ constructor: function(firstName, lastName, birthDate) { this.FirstName = firstName; this.LastName = lastName; this.BirthDate = birthDate; return { GetName: function() { return this.FirstName + " " + this.LastName; }, GetDetails: function() { return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate; }, ToOverride: function() { return "Called from Person / " + this.base(); } }; } }, Individual, null); var Kate = MG.Class.Create({ constructor: function(age) { this.Age = age; return { GetDetails: function() { return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate + "."; }, ToOverride: function() { return "Called from Kate/ " + this.base(); }}; } }, Person, null);
6:35 AM
Posted by Michael Heliso
As a background I’m a .NET developer (C#) and I really like this technology :D. Since I got in contact with JavaScript, I always wanted to find an approach, a way to adapt it and used it as more as possible as an object oriented programming language. I found different approaches/techniques regarding this aspect of JavaScript (Crockford inheritance, Dean Edward with base2, Prototype, John Resig with a mixture of base2 and Prototype). After I studied the previous mentioned techniques I decided to have fun by trying to create a mixture and add new desired functionality. You can download the source from HERE
For example in the case of Base2 inheritance you can’t create an object which has private and public members in a elegant way. Let us assume that we have following object:
var Human = base2.Base.extend({ constructor: function(name, hairColour, eyeColour, height, weight) { this.Name = name; this.HairColour = hairColour; this.EyeColour = eyeColour; this.Height = height; this.Weight = weight}, IsHeavy: function() { return this.Weight > 100 ? true : false; }, Dance: function() { return this.Name + " is dancing!"; }});
var Human = base2.Base.extend({ constructor: function(name, hairColour, eyeColour, height, weight) { var Dance = function() { return this.Name + " is dancing!";}; return{Name: name, HairColour: hairColour, EyeColour: eyeColour, Height: height, Weight: weight, IsHeavy: function() { return this.Weight > 100 ? true : false; }}; });
var Person = Human.extend({ constructor: function(name, hairColour, eyeColour, height, weight) { this.base(name, hairColour, eyeColour, height, weight); }, IsUnique: function() { return true; }}); var obj = new Person("Bob Doe", "brown'", "blue", 6, 12); obj.IsHeavy();
MG.Class.Create = function() { var ___descendant = arguments[0]; var ___parent = arguments[1]; var interfaces = arguments[2]; var Implements = MG.Class.Implements; var instance = function() { // Copy 'base' (overridden) properties this.base = instance.base; // Copy properties from 'instance' // structure object for (var prop in instance) { this[prop] = instance[prop]; } var publicParentProps = []; /**********************************************/ // Create the appropriate arguments and // initialize ___parent/___descendant by calling // their constructors /**********************************************/ var args = arguments; var desArgsCount = ___descendant.constructor.length; var desArgs = new Array(desArgsCount); for (var index = 0; index < desArgsCount; index++) desArgs[index] = args[index]; if (this.base && this.base.inheritanceList) { var length = this.base.inheritanceList.length; var startParams = args.length; for (var k = 0; k < length; k++) { var ctor = this.base.inheritanceList[k]; var prnArgsCount = ctor.length; var prnArgs = new Array(prnArgsCount); startParams -= prnArgsCount; var nextParams = prnArgsCount > startParams ? (startParams + prnArgsCount) : (startParams - prnArgsCount); for (var index = startParams, i = 0; (prnArgsCount > startParams ? index < nextParams : index > nextParams); (prnArgsCount > startParams ? index++ : index--)) { prnArgs[i] = args[Math.abs(index)]; i++; } var publicParentProp = ctor.apply(this, prnArgs); if (publicParentProp) { if (publicParentProps.length > 0) publicParentProps[publicParentProps.length] = publicParentProp; else publicParentProps[0] = publicParentProp; } this.base.inheritanceList[k] = null; } this.base.inheritanceList = null; delete this.base.inheritanceList; } var publicDescendant = instance.constructor.apply(this, desArgs); if (publicDescendant) { for (var prop in publicDescendant) this[prop] = publicDescendant[prop]; } if (publicParentProps) { var length = publicParentProps.length; for (var index = 0; index < length; index++) { var publicParentProperty = publicParentProps[index]; for (var prop in publicParentProperty) { if (!this[prop]) this[prop] = publicParentProperty[prop]; else { this.base[prop] = publicParentProperty[prop]; } } } } return this; }; /**************************************************/ // Create the structure of the object // which will be instantiated /**************************************************/ // Set the constructor from the ___descendant instance.constructor = ___descendant.constructor; // Copy peoperties from ___descendant for (var prop in ___descendant) instance[prop] = ___descendant[prop]; if (___parent) { // Create a 'base' function which will hold properties // overridden by the ___descendant instance.base = function() { var overrideFunction = null; for (var prop in this) { if (typeof (this[prop]) !== 'function') instance.base[prop] = this[prop]; else if (this[prop] === arguments.caller.callee) overrideFunction = prop; } if (overrideFunction) instance.base[overrideFunction](); }; var inheritanceList = new Array(); if (___parent.base && ___parent.base.inheritanceList) { var parentInheritanceList = ___parent.base['inheritanceList']; var length = parentInheritanceList.length; for (var index = 0; index < length; index++) inheritanceList[index] = parentInheritanceList[index]; } var constructorExists = inheritanceList[inheritanceList.length - 1] === ___parent.constructor; if (inheritanceList.length > 0 && !constructorExists) inheritanceList[inheritanceList.length] = ___parent.constructor; else if (!constructorExists) inheritanceList[0] = ___parent.constructor; instance.base.inheritanceList = inheritanceList; // Copy properties from ___parent for (var prop in ___parent) { if (!instance[prop]) instance[prop] = ___parent[prop]; else { if (typeof (___parent[prop]) == 'function') instance.base[prop] = ___parent[prop]; } } // Copy properties from ___parent prototype if (___parent.prototype) { for (var prop in ___parent.prototype) { if (!instance[prop]) instance[prop] = ___parent.prototype[prop]; else instance.base[prop] = ___parent.prototype[prop]; } } } instance.Compare = function(object) { for (var prop in this) { if (this[prop] === object[prop]) return false; } return true; } return instance; };
6:03 AM
Posted by Michael Heliso
Today something very stupid happened. I’ve managed to lose the changes of an entire package. As you know if a package is opened in two different sessions, like session A and session B, if changes are made from session A to the package and session B still has the package opened, when session B will make its changes, all modifications performed by session A on the opened package will be lost. Thanks God that I was able to retrieve the lost changes by making use of SYS.SOURCE$ table. This table is composed from 3 columns: OBJ# which represents the object ID, LINE which is the line number of the source in the object, and SOURCE the column which store the line of code.
SELECT * FROM SYS.SOURCE$;
SELECT * FROM SYS.SOURCE$ WHERE SOURCE LIKE ‘%MYPACKAGE%’;
After digging into the results returned, I was able to find 3 versions of my package. One of them contained the lost changes.
You can find more details about SYS.SOURCE$ table here.
4:52 AM
Posted by Michael Heliso
At the office I’m using Windows Vista 64 bit, we had a lot of bad surprises when it came to combine 32 bit DLLs from Oracle client with 64 bit DLLs of the projects. The most common exception in which we bumped was “Invalid image format”. We were using Oracle 10.2.0.3 which is a 32 bit client. To solve the issue we had to migrate to Oracle 10.2.0.4 client which has support for 64 bit applications. Once we did this we have discovered other inconvenient, PL/SQL didn't worked at all, the reason…it required a 32 bit Oracle client to be installed on the machine. The only solution found by one of my colleagues is that beside Oracle 10.2.0.4 client we should install also 10.2.0.3. Until now everything works just fine. By the way, same thing applies also to TOAD.
2:14 AM
Posted by Michael Heliso
In one of the project I have been involved, I had to create an Ajax menu. The issue showed up when the resource text of the menu items were in Greek. The response of the Ajax request was just junk. The issue resided in the fact that I have not specified on my Ajax request what character set it should be used. The problem was solved once I have specified that the value of charset it should be utf-8.
var url = location.protocol + "//" + location.host + "/MyWebSite/Default.aspx/GetMenuXml"; xmlHttp = GetXmlHttpObject(); xmlHttp.open("POST", url, true); xmlHttp.onreadystatechange = initializeMenu; xmlHttp.setRequestHeader("Man", "POST" + url); xmlHttp.setRequestHeader("MessageType", "CALL"); xmlHttp.setRequestHeader("Content-Type", "application/json; charset=utf-8"); xmlHttp.send(null);
12:40 AM
Posted by Michael Heliso
Here is a very useful tool which allows you to create nice benchmark tests for your JavaScript code. You can check all the details on their home page:
JSLitmus
12:13 PM
Posted by Michael Heliso
The followinf function will return current date in dd/mm/yyyy format.
/*Define the namespaces*/ var JavaScript = {}; JavaScript.Utils = {}; JavaScript.Utils.Date = {}; JavaScript.Utils.Date.Current = function(){ var current = new Date(); //In JavaScript Date object the months counter starts from 0, so //we have to correct this. current.setMonth(current.getMonth() + 1); var changedDate = current.getDate() + "/" + current.getMonth() + "/" + current.getYear(); return changedDate; }
11:56 AM
Posted by Michael Heliso
Note: Please check JavaScript Utility Functions Note.
The following javascript function allows you to compare two dates. At this time only dd/mm/yyyy format is supported, but you can extend it very easily. The function will return -1 if first date is smaller than the second date, 1 if it is greater and 0 if both dates are equal.
/*Define the namespaces*/
var JavaScript = {};
JavaScript.Utils = {};
JavaScript.Utils.Date = {};
JavaScript.Utils.Date.Compare = function(firstDate, secondDate, format) {
if (!(typeof firstDate === "string") || !(typeof secondDate === "string"))
throw "Date must be a string.";
if (!format)
throw "invalid date format specified.";
var result = -1;
switch (format) {
case "dd/mm/yyyy":
{
var fdate = firstDate.match(/^(\d{2})\/(\d{2})\/(\d{4})$/i);
var ldate = secondDate.match(/^(\d{2})\/(\d{2})\/(\d{4})$/i);
if (parseInt(fdate[3]) < parseInt(ldate[3]))
result = -1;
else if (parseInt(fdate[3]) > parseInt(ldate[3]))
result = 1;
else
result = 0;
if (result == 0) {
if (parseInt(fdate[2]) < parseInt(ldate[2]))
result = -1;
else if (parseInt(fdate[2]) > parseInt(ldate[2]))
result = 1;
else
result = 0;
}
if (result == 0) {
if (parseInt(fdate[1]) < parseInt(ldate[1]))
result = -1;
else if (parseInt(fdate[1]) > parseInt(ldate[1]))
result = 1;
else
result = 0;
}
}
break;
}
return result;
};
11:39 AM
Posted by Michael Heliso
Note: Please check JavaScript Utility Functions Note.
The following javascript function allows you to convert an UTC date into a user specified format. At this time the implementation will convert the UTC date into dd/mm/yyyy and dd/mm/yyyy hh:mm:ss formats. You can easily extend it's functionality.
/*Define the namespaces*/
var JavaScript = {};
JavaScript.Utils = {};
JavaScript.Utils.Date = {};
JavaScript.Utils.Date.UtcFormat = function(utcDate, format) {
if (!(typeof utcDate === "string"))
throw "UTC date must be a string.";
if (!format)
throw "invalid date format specified.";
//Extract UTC date components using regex.
var date = utcDate.match(/^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z(([+-])(\d{2}):(\d{2}))?)$/i);
if (!date)
throw "Invalid UTC date format.";
var newDate = null;
switch (format) {
case "dd/mm/yyyy":
{
newDate = date[3] + "/" + date[2] + "/" + date[1];
}
break;
case "dd/mm/yyyy hh:mm:ss":
{
newDate = date[3] + "/" + date[2] + "/" + date[1] + " " + date[4] + ":" + date[5] + ":" + date[6];
}
break;
}
return newDate;
};
JavaScript.Utils.Date.ToUtcFormat = function(date) {
if (!(typeof date === "string"))
throw "Date must be a string.";
var ndate = date.match(/^(\d{2})\/(\d{2})\/(\d{4})$/i);
if (!ndate)
throw "Invalid date format. Format must be dd/mm/yyyy";
var newDate = ndate[3] + "-" + ndate[2] + "-" + ndate[1] + "T00:00:00Z";
return newDate;
11:09 AM
Posted by Michael Heliso
Note: Please check JavaScript Utility Functions Note.
The following function will allow you to change the value of a specified parameter from the URL. You just have to pass the parameter name and desired parameter value.
/*Define the namespaces*/
var JavaScript = {};
JavaScript.Utils = {};
JavaScript.Utils.URL = {};
JavaScript.Utils.URL.ReplaceUrlParam = function(name, value) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if (results == null)
return false;
else {
var form = document.forms[0];
if (form) {
form.action = form.action.replace(results[0], results[0].replace(/=(.*)/, '=' + value));
}
}
};