follow me on Twitter
    hacker emblem

    Page trailPage trail: Python programming languag... :: Zend: PHP-based web framew... :: JavaScript programming lan...

    JavaScript programming language

    IconDetails...


    JavaScript programming language

    The idea is simple... a topic map store (that is, back-end) that talks to the web front-end by means of JSON and said front-end being nothing else than a basic HTML-layout and jQuery taking care of the UI dynamics. Take that, Flex! ;-)

    The code below has all the usual object-oriented JavaScript patterns, e.g.:

    • namespaces (simulated by using dictionaries)
    • private members (made by the constructor, varS and parameters of the constructor become the private members)
    • public (prototype) methods
    • public members (using the constructor's this variable)
    • privileged methods (assigned with this in the constructor, e.g., this.method = function() { };)
    • Observer pattern (to notify the UI-components of any changes)

    All of the above goodness is made possible because of closures (that is, an inner function can access the variables and parameters of its outer function, even after the outer function has finished executing).

    JavaScript topic map objects

    // setting up Base (infrastructure) namespace
    var Base = {};
    
    // observer pattern
    Base.Subject = function(subject) {
        // private members
        var observers = new Array();    
        
        // privileged methods
        this.addObserver = function(observer) {
            observers.push(observer);
        }
    
        this.removeObserver = function(observer) {
            // missing code
        }
    
        this.notifyObserver = function() {
            // http://www.prototypejs.org/api/array
            for (var i = 0, len = observers.length; i < len; ++i) {
                var observer = observers[i];
                // TODO: check.
                observer.update(subject);
            }
        }
    }
    
    // public (prototype) methods of Base.Subject object
    
    // ======================================================================
    
    // setting up Utilities namespace
    var Utilities = {};
    
    Utilities.defaultHandler = function(defaults, params) {
        var i;
        for (i in params) {
            defaults[i] = params[i];
        }
        return defaults;
    } 
    
    Utilities.S4 = function() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }
    
    Utilities.guid = function() {
        return (Utilities.S4() + 
            Utilities.S4() + "-" + 
            Utilities.S4() + "-" + 
            Utilities.S4() + "-" + 
            Utilities.S4() + "-" + 
            Utilities.S4() + 
            Utilities.S4() + 
            Utilities.S4());
    }
    
    Utilities.sanitizeId = function(identifier) {
        return identifier.replace(/ /gi, identifier).toLowerCase();
    }
    
    // setting up Topicmap.Models namespace
    var Topicmap = {};
    Topicmap.Models = {};
    
    // ======================================================================
    
    Topicmap.Models.Node = function(obj) {
        // private members
        var that = this;
        var params = 
          Utilities.defaultHandler({identifier: Utilities.guid(), instanceOf: 'node'}, obj);
        var identifier = Utilities.sanitizeId(params['identifier']);
        
        // priviliged methods
        this.getId = function() {
            return identifier;
        }
        
        // public properties
        this.instanceOf = Utilities.sanitizeId(params['instanceOf']);
    }
    
    // public (prototype) methods of Node object
    Topicmap.Models.Node.prototype.getIdentifier = function() {
        return this.getId();
    }
    
    // ======================================================================
    
    Topicmap.Models.Topic = function(obj) {
        // private members
        var params = Utilities.defaultHandler({
            identifier: Utilities.guid(), 
            instanceOf: 'topic', 
            baseName: 'unknown'}, obj);
        
        // call to super constructor
        Topicmap.Models.Node.call(this, {
            identifier: params['identifier'], 
            instanceOf: params['instanceOf']}, obj);
        
        var baseNames = new Array();
        baseNames.push(params['baseName']);
        
        this.subject = new Base.Subject(this);
        
        // privileged methods
        this.getBaseName = function(index) {
            return baseNames[index];
        }
        
        this.getBaseNames = function() {
            return baseNames;        
        }
        
        // public properties
    }
    
    // setting up inheritance: Topic extends Node
    Topicmap.Models.Topic.prototype = new Topicmap.Models.Node();
    
    Topicmap.Models.Topic.prototype.constructor = Topicmap.Models.Topic;
    
    // public (prototype) methods of Topic object
    Topicmap.Models.Topic.prototype.getFirstName = function() {    
        return this.getBaseName(0);
    }
    
    Topicmap.Models.Topic.prototype.addBaseName = function(baseName) {
        this.getBaseNames().push(baseName);
        this.subject.notifyObserver();
    }
    
    Topicmap.Models.Topic.prototype.removeBaseName = function() {
        // TODO: implement
    }
    
    Topicmap.Models.Topic.prototype.clearBaseNames = function() {
        // TODO: implement
    }
    
    Topicmap.Models.Topic.prototype.addOccurrence = function() {
        // TODO: implement
    }
    
    // ======================================================================
    
    Topicmap.Models.Occurrence = function(obj) {
        // private members
        var params = Utilities.defaultHandler({
            identifier: Utilities.guid(), 
            instanceOf: 'occurrence',
            topicIdentifier: null,
            scope: '*',
            resourceRef: ''}, obj);
        
        // call to super constructor
        Topicmap.Models.Node.call(this, {
            identifier: params['identifier'], 
            instanceOf: params['instanceOf']}, obj);
        
        // public properties
        this.topicIdentifier = Utilities.sanitizeId(params['topicIdentifier']);
        this.scope = Utilities.sanitizeId(params['scope']);
        this.resourceRef = params['resourceRef'];  
    }
    
    // setting up inheritance: Occurrence extends Node
    Topicmap.Models.Occurrence.prototype = new Topicmap.Models.Node();
    Topicmap.Models.Occurrence.prototype.constructor = Topicmap.Models.Occurrence;
    
    // ======================================================================
    
    Topicmap.Models.Member = function(obj) {
        // private members
        var params = Utilities.defaultHandler({
            roleSpec: '', topicRef: '', 
            identifier: Utilities.guid()}, obj);
        var identifier = Utilities.sanitizeId(params['identifier']);    
        var topicRefs = new Array();
        
        topicRefs.push(Utilities.sanitizeId(params['topicRef']));
        
        // priviliged methods
        this.getIdentifier = function() {
            return identifier;
        }
        
        this.getTopicRefs = function() {
            return topicRefs;
        }
        
        this.addTopicRef = function(topicRef) {
            topicRefs.push(topicRef);
        }
        
        this.removeTopicRef = function(topicRef) {
            // TODO: implement code
        }
        
        this.clearTopicRefs = function() {
            // TODO: implement code
        }
        
        // public properties
        this.roleSpec = Utilities.sanitizeId(params['roleSpec']);
    }
    
    // public (prototype) methods of Member object
    
    // ======================================================================
    
    Topicmap.Models.Association = function(obj) {
        // private members
        var params = Utilities.defaultHandler({
            srcRoleSpec: '', 
            srcTopicRef: '', 
            destRoleSpec: '',
            destTopicRef: '',
            identifier: Utilities.guid(),
            instanceOf: 'association',
            scope: '*',
            baseName: 'unknown'}, obj);
        
        // call to super constructor
        Topicmap.Models.Topic.call(this, {
            identifier: Utilities.sanitizeId(params['identifier']), 
            instanceOf: Utilities.sanitizeId(params['instanceOf']), 
            baseName: params['baseName']}, obj);
        
        var members = new Array();
        
        var srcMember = new Topicmap.Models.Member({
          roleSpec: Utilities.sanitizeId(params['srcRoleSpec']), 
          topicRef: Utilities.sanitizeId(params['srcTopicRef'])});
        var destMember = new Topicmap.Models.Member({
          roleSpec: Utilities.sanitizeId(params['destRoleSpec']), 
          topicRef: Utilities.sanitizeId(params['destTopicRef'])});
        members.push(srcMember);
        members.push(destMember);    
        
        // priviliged methods
        this.createMember = function(roleSpec, topicRef) {
            var member = new Topicmap.Models.Member({
              roleSpec: Utilities.sanitizeId(params['roleSpec']), 
              topicRef: Utilities.sanitizeId(params['topicRef'])});
            members.push(member);
        }
        
        this.createMembers = function(srcRoleSpec, srcTopicRef, destRoleSpec, destTopicRef) {
            var srcMember = new Topicmap.Models.Member({
              roleSpec: Utilities.sanitizeId(srcRoleSpec), 
              topicRef: Utilities.sanitizeId(srcTopicRef)});
            var destMember = new Topicmap.Models.Member({
              roleSpec: Utilities.sanitizeId(destRoleSpec), 
              topicRef: Utilities.sanitizeId(destTopicRef)});
            members.push(srcMember);
            members.push(destMember);
        }
        
        this.addMember = function(member) {
            members.push(member);
        }
        
        this.getMember = function(identifier) {
            // TODO: implement code
        }
        
        this.getMembers = function() {
            return members;
        }
        
        this.removeMember = function(identifer) {
            // TODO: implement code
        }
        
        this.removeMembers = function() {
            // TODO: implement code
        }
        
        // public properties
        this.scope = Utilities.sanitizeId(params['scope']);
    }
    
    // setting up inheritance: Association extends Topic
    Topicmap.Models.Association.prototype = new Topicmap.Models.Topic();
    Topicmap.Models.Association.prototype.constructor = Topicmap.Models.Association;
    
    // ======================================================================
    
    Topicmap.Models.MetaDatum = function(obj) {
      // private members
        var params = Utilities.defaultHandler({
            parentIdentifier: '', 
            name: '', 
            value: '',
            identifier: Utilities.guid(),
            scope: '*'}, obj);
        var parentIdentifier = Utilities.sanitizeId(params['parentIdentifier']);
        var name = Utilities.sanitizeId(params['name']);
        var identifier = Utilities.sanitizeId(params['identifier']);
        
        // priviliged methods
        this.getParentIdentifier = function() {
            return parentIdentifier;
        }
        
        this.getIdentifier = function() {
            return identifier;
        }
        
        this.getName = function() {
            return name;
        }
        
        // public properties
        this.value = params['value'];
        this.scope = params['scope'];
    }
    
    // ======================================================================
    
    Topicmap.Models.Map = function() {    
        // privileged methods
        this.update = function(subject) {
            // TODO: show type of object that has been created or updated; either 
            // Topic or Association
            console.log("The following subject has changed: [%s]", subject.getIdentifier());
        }
    }
    

    Click here to be able to create pages, upload images and file attachments, and link to other users and their pages.


    blog comments powered by Disqus