<commit_before>/*
this type of import is for merge purposes
it tries to import not only the outgoing relations but the incoming ones as well
it also tries to keep both the GUID and the relid's
if it finds the same guid in the same place then it overwrites the node with the imported one!!!
it not searches for GUID!!! so be careful when to use this method
*/

define([
    'coreclient/meta'
],function(
    BaseMeta
    ){
    var _core = null,
        _root = null,
        _rootPath = "",
        _cache = {},
        _underImport = {},
        _internalRefHash = {},
        META = new BaseMeta();

    function internalRefCreated(intPath,node){
        _cache[_core.getPath(node)] = node;
        _internalRefHash[intPath] = _core.getPath(node);
        var callbacks = _underImport[intPath] || [];
        delete _underImport[intPath];
        for(var i=0;i<callbacks.length;i++){
            callbacks[i](null,node);
        }
    }
    function objectLoaded(error,node){
        if(error === null){
            _cache[_core.getPath(node)] = node;
        }

        var callbacks = _underImport[_core.getPath(node)] || [];
        delete _underImport[_core.getPath(node)];
        for(var i=0;i<callbacks.length;i++){
            callbacks[i](error,node);
        }
    }
    function isInternalReference(refObj){
        if(refObj && typeof refObj['$ref'] === 'string'){
            if(refObj['$ref'].indexOf('#') === 0){
                return true;
            }
        }
        return false;
    }
    function getReferenceNode(refObj,callback){
        //we allow the internal references and the
        if(refObj && typeof refObj['$ref'] === 'string'){
            if(refObj['$ref'].indexOf('#') === 0){
                //we assume that it is an internal reference
                if(_internalRefHash[refObj['$ref']]){
                    callback(null,_cache[_internalRefHash[refObj['$ref']]]);
                } else if(_underImport[refObj['$ref']]){
                    _underImport[refObj['$ref']].push(callback);
                } else {
                    _underImport[refObj['$ref']] = [callback]; //TODO we should check if the loading order is really finite this way
                }
            } else if(refObj['$ref'] === null){
                callback(null,null);
            } else {
                if(_cache[refObj['$ref']]){
                    callback(null,_cache[refObj['$ref']]);
                } else if(_underImport[refObj['$ref']]){
                    _underImport[refObj['$ref']].push(callback);
                } else {
                    _underImport[refObj['$ref']] = [callback];
                    _core.loadByPath(_root,refObj['$ref'],function(err,node){
                        if(err){
                            objectLoaded(err, null);
                        } else {
                            if(refObj['GUID']){
                                if(refObj['GUID'] === _core.getGuid(node)){
                                    objectLoaded(err,node);
                                } else {
                                    objectLoaded('GUID mismatch',node);
                                }
                            } else {
                                objectLoaded(err,node);
                            }
                        }
                    });
                }
            }
        } else {
            callback(null,null);
        }
    }
    function importChildren(node,jNode,pIntPath,callback){
        if(jNode && jNode.children && jNode.children.length){
            var needed = jNode.children.length;

            if(needed > 0){
                var error = null;
                for(var i=0;i<jNode.children.length;i++){
                    importNode(jNode.children[i],node,pIntPath+'/children['+i+']',function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback(null);
            }

        } else {
            callback(null); //TODO maybe we should be more strict
        }
    }
    function importAttributes(node,jNode){
        if(typeof jNode.attributes === 'object'){
            var names = Object.keys(jNode.attributes);
            if(jNode.OWN){
                names = jNode.OWN.attributes;
            }

            for(var i=0;i<names.length;i++){
                var value = jNode.attributes[names[i]];
                if(value !== undefined){
                    _core.setAttribute(node,names[i],value);
                }
            }
        }
    }
    function importRegistry(node,jNode){
        if(typeof jNode.registry === 'object'){
            var names = Object.keys(jNode.registry);
            if(jNode.OWN){
                names = jNode.OWN.registry;
            }

            for(var i=0;i<names.length;i++){
                var value = jNode.registry[names[i]];
                if(value !== undefined){
                    _core.setRegistry(node,names[i],value);
                }
            }
        }
    }
    function importPointer(node,jNode,pName,callback){
        if(jNode.pointers[pName].to && jNode.pointers[pName].from){
            var needed = jNode.pointers[pName].to.length + jNode.pointers[pName].from.length,
                i,
                error = null;
            var ownPointer = true;
            if(jNode.OWN){
                if(jNode.OWN.pointers.indexOf(pName) === -1){
                    ownPointer = false;
                    needed -= jNode.pointers[pName].to.length;
                }
            }
            if(needed === 0){
                callback(null);
            } else {
                if(ownPointer){
                    for(i=0;i<jNode.pointers[pName].to.length;i++){
                        getReferenceNode(jNode.pointers[pName].to[i],function(err,target){
                            error = error || err;
                            _core.setPointer(node,pName,target);

                            if(--needed === 0){
                                callback(error);
                            }
                        });
                    }
                }

                for(i=0;i<jNode.pointers[pName].from.length;i++){
                    if(!isInternalReference(jNode.pointers[pName].from[i])){
                        getReferenceNode(jNode.pointers[pName].from[i],function(err,source){
                            error = error || err;
                            if(source){
                                _core.setPointer(source,pName,node);
                            }

                            if(--needed === 0){
                                callback(error);
                            }
                        });
                    } else {
                        if(--needed === 0){
                            callback(error);
                        }
                    }
                }
            }
        } else {
            callback(null);
        }
    }
    function importSet(node,jNode,sName, callback){
        if(jNode.pointers[sName].to && jNode.pointers[sName].from){
            var needed = 0,
                importSetRegAndAtr = function(sOwner,sMember,atrAndReg){
                    _core.addMember(sOwner,sName,sMember);
                    var mPath = _core.getPath(sMember);
                    atrAndReg.attributes = atrAndReg.attributes || {};
                    for(var i in atrAndReg.attributes){
                        _core.setMemberAttribute(sOwner,sName,mPath,i,atrAndReg.attributes[i]);
                    }
                    atrAndReg.registry = atrAndReg.registry || {};
                    for(var i in atrAndReg.registry){
                        _core.setMemberRegistry(sOwner,sName,mPath,i,atrAndReg.registry[i]);
                    }
                },
                importSetReference = function(isTo,index,cb){
                    var jObj = isTo === true ? jNode.pointers[sName].to[index] : jNode.pointers[sName].from[index];
                    getReferenceNode(jObj,function(err,sNode){
                        if(err){
                            cb(err);
                        } else {
                            if(sNode){
                                var sOwner = isTo === true ? node : sNode,
                                    sMember = isTo === true ? sNode : node;
                                importSetRegAndAtr(sOwner,sMember,jObj);
                            }
                            cb(null);
                        }
                    });
                },
                error = null;

            if(jNode.pointers[sName].to.length > 0){
                needed += jNode.pointers[sName].to.length;
                _core.createSet(node,sName);
            }
            if(jNode.pointers[sName].from.length > 0){
                needed += jNode.pointers[sName].from.length;
            }

            if(needed > 0){
                for(var i=0;i<jNode.pointers[sName].to.length;i++){
                    importSetReference(true,i,function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
                for(var i=0;i<jNode.pointers[sName].from.length;i++){
                    importSetReference(false,i,function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback(null);
            }
        } else {
            callback(null); //TODO now we just simply try to ignore faulty data import
        }
    }
    function importRelations(node,jNode,callback){
        //TODO now se use the pointer's 'set' attribute to decide if it is a set or a pointer really
        var pointers = [],
            sets = [],
            needed = 0,
            error = null,
            i;
        if(! typeof jNode.pointers === 'object'){
            callback(null); //TODO should we drop an error???
        } else {
            for(i in jNode.pointers){
                if(jNode.pointers[i].set === true){
                    sets.push(i);
                } else {
                    pointers.push(i);
                }
            }

            needed = sets.length + pointers.length;

            if(needed > 0){
                for(i=0;i<pointers.length;i++){
                    importPointer(node,jNode,pointers[i],function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
                for(i=0;i<sets.length;i++){
                    importSet(node,jNode,sets[i],function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback(null);
            }
        }
    }
    function importMeta(node,jNode,callback){

        //TODO now this function searches the whole meta data for reference objects and load them, then call setMeta
        var loadReference = function(refObj,cb){
                getReferenceNode(refObj,function(err,rNode){
                    if(err){
                        cb(err);
                    } else {
                        if(rNode){
                            refObj['$ref'] = _core.getPath(rNode);
                        }
                        cb(null);
                    }
                });
            },
            loadMetaReferences = function(jObject,cb){
                var needed = 0,
                    error = null;
                for(var i in jObject){
                    if(jObject[i] !== null && typeof jObject[i] === 'object'){
                        needed++;
                    }
                }

                if(needed>0){
                    for(var i in jObject){
                        if(jObject[i] !== null && typeof jObject[i] === 'object'){
                            if(jObject[i]['$ref']){
                                loadReference(jObject[i],function(err){
                                    error = error || err;
                                    if(--needed === 0){
                                        cb(error);
                                    }
                                });
                            } else {
                                loadMetaReferences(jObject[i],function(err){
                                    error = error || err;
                                    if(--needed === 0){
                                        cb(error);
                                    }
                                });
                            }
                        }
                    }
                } else {
                    cb(error);
                }
            };

        loadMetaReferences(jNode.meta || {}, function(err){
            if(err){
                callback(err);
            } else {
                META.setMeta(_core.getPath(node),jNode.meta || {});
                callback(null);
            }
        });
    };
    function importRoot(jNode,callback){
        //first we create the root node itself, then the other parts of the function is pretty much like the importNode
        _root = _core.createNode({guid:jNode.GUID});
        internalRefCreated('#',_root);
        importAttributes(_root,jNode);
        importRegistry(_root,jNode);
        importChildren(_root,jNode,'#',function(err){
            if(err){
                callback(err);
            } else {
                importRelations(_root,jNode,function(err){
                    if(err){
                        callback(err);
                    } else {
                        importMeta(_root,jNode,function(err){
                            callback(err,_root);
                        });
                    }
                });
            }
        });
    }
    function clearOldNode(relid,guid,parentNode,callback){
        var relids = _core.getChildrenRelids(parentNode);
        if(relids.indexOf(relid) !== -1){
            _core.loadChild(parentNode,relid,function(err,oldChild){
                if(err){
                    callback(err);
                } else {
                    if(_core.getGuid(oldChild) === guid){
                        var root = _core.getRoot(oldChild);
                        _core.deleteNode(oldChild);
                        _core.persist(root,function(){
                            callback(null)
                        });
                    } else {
                        callback(null);
                    }
                }
            });
        } else {
            callback(null);
        }
    }
    function importNode(jNode,parentNode,intPath,callback){
        //first we have to get the base of the node
        if(jNode.pointers && jNode.pointers.base && jNode.pointers.base.to){
            getReferenceNode(jNode.pointers.base.to[0],function(err,base){
                if(err){
                    callback(err);
                } else {
                   clearOldNode(jNode.RELID,jNode.GUID,parentNode,function(err){
                        if(err){
                            callback(err);
                        } else {
                            //now we are ready to create the node itself
                            var node = _core.createNode({base:base,parent:parentNode,relid:jNode.RELID,guid:jNode.GUID});
                            internalRefCreated(intPath,node);
                            importAttributes(node,jNode);
                            importRegistry(node,jNode);
                            importChildren(node,jNode,intPath,function(err){
                                if(err){
                                    callback(err);
                                } else {
                                    importRelations(node,jNode,function(err){
                                        if(err){
                                            callback(err);
                                        } else {
                                            importMeta(node,jNode,function(err){
                                                callback(err);
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    });
                }
            });
        } else {
            callback('wrong import format: base info is wrong');
        }
    }

    function importing(core,parent,jNode,callback){
        _core = core;
        _cache = {};
        _underImport = {};
        _internalRefHash = {};
        META.initialize(_core,_cache,function(){});

        if(jNode.length){
            //multiple objects
            if(parent){
                var needed = jNode.length,
                    error = null;
                _cache[core.getPath(parent)] = parent;
                _root = core.getRoot(parent);
                for(var i=0;i<jNode.length;i++){
                    importNode(jNode[i],parent,'#['+i+']',function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback('no parent given!!!');
            }
        } else {
            //single object
            if(parent){
                _cache[core.getPath(parent)] = parent;
                _root = core.getRoot(parent);
                importNode(jNode,parent,'#',callback);
            } else {
                importRoot(jNode,callback);
            }
        }
    }

    return importing;
});

<commit_msg>fixes - now even the logic gates can be imported, but there are too many unnecessary error logs -<commit_after>/*
this type of import is for merge purposes
it tries to import not only the outgoing relations but the incoming ones as well
it also tries to keep both the GUID and the relid's
if it finds the same guid in the same place then it overwrites the node with the imported one!!!
it not searches for GUID!!! so be careful when to use this method
*/

define([
    'coreclient/meta'
],function(
    BaseMeta
    ){
    var _core = null,
        _root = null,
        _rootPath = "",
        _cache = {},
        _underImport = {},
        _internalRefHash = {},
        META = new BaseMeta();

    function internalRefCreated(intPath,node){
        _cache[_core.getPath(node)] = node;
        _internalRefHash[intPath] = _core.getPath(node);
        var callbacks = _underImport[intPath] || [];
        delete _underImport[intPath];
        for(var i=0;i<callbacks.length;i++){
            callbacks[i](null,node);
        }
    }
    function objectLoaded(error,node){
        if(error === null){
            _cache[_core.getPath(node)] = node;
        }

        var callbacks = _underImport[_core.getPath(node)] || [];
        delete _underImport[_core.getPath(node)];
        for(var i=0;i<callbacks.length;i++){
            callbacks[i](error,node);
        }
    }
    function isInternalReference(refObj){
        if(refObj && typeof refObj['$ref'] === 'string'){
            if(refObj['$ref'].indexOf('#') === 0){
                return true;
            }
        }
        return false;
    }
    function getReferenceNode(refObj,callback){
        //we allow the internal references and the
        if(refObj && typeof refObj['$ref'] === 'string'){
            if(refObj['$ref'].indexOf('#') === 0){
                //we assume that it is an internal reference
                if(_internalRefHash[refObj['$ref']]){
                    callback(null,_cache[_internalRefHash[refObj['$ref']]]);
                } else if(_underImport[refObj['$ref']]){
                    _underImport[refObj['$ref']].push(callback);
                } else {
                    _underImport[refObj['$ref']] = [callback]; //TODO we should check if the loading order is really finite this way
                }
            } else if(refObj['$ref'] === null){
                callback(null,null);
            } else {
                if(_cache[refObj['$ref']]){
                    callback(null,_cache[refObj['$ref']]);
                } else if(_underImport[refObj['$ref']]){
                    _underImport[refObj['$ref']].push(callback);
                } else {
                    _underImport[refObj['$ref']] = [callback];
                    _core.loadByPath(_root,refObj['$ref'],function(err,node){
                        if(err){
                            objectLoaded(err, null);
                        } else {
                            if(refObj['GUID']){
                                if(refObj['GUID'] === _core.getGuid(node)){
                                    objectLoaded(err,node);
                                } else {
                                    objectLoaded('GUID mismatch',node);
                                }
                            } else {
                                objectLoaded(err,node);
                            }
                        }
                    });
                }
            }
        } else {
            callback(null,null);
        }
    }
    function importChildren(node,jNode,pIntPath,callback){
        if(jNode && jNode.children && jNode.children.length){
            var needed = jNode.children.length;

            if(needed > 0){
                var error = null;
                for(var i=0;i<jNode.children.length;i++){
                    importNode(jNode.children[i],node,pIntPath+'/children['+i+']',true,function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback(null);
            }

        } else {
            callback(null); //TODO maybe we should be more strict
        }
    }
    function importAttributes(node,jNode){
        if(typeof jNode.attributes === 'object'){
            var names = Object.keys(jNode.attributes);
            if(jNode.OWN){
                names = jNode.OWN.attributes;
            }

            for(var i=0;i<names.length;i++){
                var value = jNode.attributes[names[i]];
                if(value !== undefined){
                    _core.setAttribute(node,names[i],value);
                }
            }
        }
    }
    function importRegistry(node,jNode){
        if(typeof jNode.registry === 'object'){
            var names = Object.keys(jNode.registry);
            if(jNode.OWN){
                names = jNode.OWN.registry;
            }

            for(var i=0;i<names.length;i++){
                var value = jNode.registry[names[i]];
                if(value !== undefined){
                    _core.setRegistry(node,names[i],value);
                }
            }
        }
    }
    function importPointer(node,jNode,pName,callback){
        if(jNode.pointers[pName].to && jNode.pointers[pName].from){
            var needed = jNode.pointers[pName].to.length + jNode.pointers[pName].from.length,
                i,
                error = null;
            var ownPointer = true;
            if(jNode.OWN){
                if(jNode.OWN.pointers.indexOf(pName) === -1){
                    ownPointer = false;
                    needed -= jNode.pointers[pName].to.length;
                }
            }
            if(needed === 0){
                callback(null);
            } else {
                if(ownPointer){
                    for(i=0;i<jNode.pointers[pName].to.length;i++){
                        getReferenceNode(jNode.pointers[pName].to[i],function(err,target){
                            error = error || err;
                            _core.setPointer(node,pName,target);

                            if(--needed === 0){
                                callback(error);
                            }
                        });
                    }
                }

                for(i=0;i<jNode.pointers[pName].from.length;i++){
                    if(!isInternalReference(jNode.pointers[pName].from[i])){
                        getReferenceNode(jNode.pointers[pName].from[i],function(err,source){
                            error = error || err;
                            if(source){
                                _core.setPointer(source,pName,node);
                            }

                            if(--needed === 0){
                                callback(error);
                            }
                        });
                    } else {
                        if(--needed === 0){
                            callback(error);
                        }
                    }
                }
            }
        } else {
            callback(null);
        }
    }
    function importSet(node,jNode,sName, callback){
        if(jNode.pointers[sName].to && jNode.pointers[sName].from){
            var needed = 0,
                importSetRegAndAtr = function(sOwner,sMember,atrAndReg){
                    _core.addMember(sOwner,sName,sMember);
                    var mPath = _core.getPath(sMember);
                    atrAndReg.attributes = atrAndReg.attributes || {};
                    for(var i in atrAndReg.attributes){
                        _core.setMemberAttribute(sOwner,sName,mPath,i,atrAndReg.attributes[i]);
                    }
                    atrAndReg.registry = atrAndReg.registry || {};
                    for(var i in atrAndReg.registry){
                        _core.setMemberRegistry(sOwner,sName,mPath,i,atrAndReg.registry[i]);
                    }
                },
                importSetReference = function(isTo,index,cb){
                    var jObj = isTo === true ? jNode.pointers[sName].to[index] : jNode.pointers[sName].from[index];
                    getReferenceNode(jObj,function(err,sNode){
                        if(err){
                            cb(err);
                        } else {
                            if(sNode){
                                var sOwner = isTo === true ? node : sNode,
                                    sMember = isTo === true ? sNode : node;
                                importSetRegAndAtr(sOwner,sMember,jObj);
                            }
                            cb(null);
                        }
                    });
                },
                error = null;

            if(jNode.pointers[sName].to.length > 0){
                needed += jNode.pointers[sName].to.length;
                _core.createSet(node,sName);
            }
            if(jNode.pointers[sName].from.length > 0){
                needed += jNode.pointers[sName].from.length;
            }

            if(needed > 0){
                for(var i=0;i<jNode.pointers[sName].to.length;i++){
                    importSetReference(true,i,function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
                for(var i=0;i<jNode.pointers[sName].from.length;i++){
                    importSetReference(false,i,function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback(null);
            }
        } else {
            callback(null); //TODO now we just simply try to ignore faulty data import
        }
    }
    function importRelations(node,jNode,callback){
        //TODO now se use the pointer's 'set' attribute to decide if it is a set or a pointer really
        var pointers = [],
            sets = [],
            needed = 0,
            error = null,
            i;
        if(! typeof jNode.pointers === 'object'){
            callback(null); //TODO should we drop an error???
        } else {
            for(i in jNode.pointers){
                if(jNode.pointers[i].set === true){
                    sets.push(i);
                } else {
                    pointers.push(i);
                }
            }

            needed = sets.length + pointers.length;

            if(needed > 0){
                for(i=0;i<pointers.length;i++){
                    importPointer(node,jNode,pointers[i],function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
                for(i=0;i<sets.length;i++){
                    importSet(node,jNode,sets[i],function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback(null);
            }
        }
    }
    function importMeta(node,jNode,callback){

        //TODO now this function searches the whole meta data for reference objects and load them, then call setMeta
        var loadReference = function(refObj,cb){
                getReferenceNode(refObj,function(err,rNode){
                    if(err){
                        cb(err);
                    } else {
                        if(rNode){
                            refObj['$ref'] = _core.getPath(rNode);
                        }
                        cb(null);
                    }
                });
            },
            loadMetaReferences = function(jObject,cb){
                var needed = 0,
                    error = null;
                for(var i in jObject){
                    if(jObject[i] !== null && typeof jObject[i] === 'object'){
                        needed++;
                    }
                }

                if(needed>0){
                    for(var i in jObject){
                        if(jObject[i] !== null && typeof jObject[i] === 'object'){
                            if(jObject[i]['$ref']){
                                loadReference(jObject[i],function(err){
                                    error = error || err;
                                    if(--needed === 0){
                                        cb(error);
                                    }
                                });
                            } else {
                                loadMetaReferences(jObject[i],function(err){
                                    error = error || err;
                                    if(--needed === 0){
                                        cb(error);
                                    }
                                });
                            }
                        }
                    }
                } else {
                    cb(error);
                }
            };

        loadMetaReferences(jNode.meta || {}, function(err){
            if(err){
                callback(err);
            } else {
                META.setMeta(_core.getPath(node),jNode.meta || {});
                callback(null);
            }
        });
    };
    function importRoot(jNode,callback){
        //first we create the root node itself, then the other parts of the function is pretty much like the importNode
        _root = _core.createNode({guid:jNode.GUID});
        internalRefCreated('#',_root);
        importAttributes(_root,jNode);
        importRegistry(_root,jNode);
        importChildren(_root,jNode,'#',function(err){
            if(err){
                callback(err);
            } else {
                importRelations(_root,jNode,function(err){
                    if(err){
                        callback(err);
                    } else {
                        importMeta(_root,jNode,function(err){
                            callback(err,_root);
                        });
                    }
                });
            }
        });
    }
    function clearOldNode(relid,guid,parentNode,callback){
        var relids = _core.getChildrenRelids(parentNode);
        if(relids.indexOf(relid) !== -1){
            _core.loadChild(parentNode,relid,function(err,oldChild){
                if(err){
                    callback(err);
                } else {
                    if(_core.getGuid(oldChild) === guid){
                        var root = _core.getRoot(oldChild);
                        _core.deleteNode(oldChild);
                        _core.persist(root,function(){
                            callback(null)
                        });
                    } else {
                        callback(null);
                    }
                }
            });
        } else {
            callback(null);
        }
    }
    function getEmptyNode(jNode,parentNode,baseNode,noClear,callback){
        var relids = _core.getChildrenRelids(parentNode),
            returnNewNode = function(){
                var node = _core.createNode({base:baseNode,parent:parentNode,relid:jNode.RELID,guid:jNode.GUID});
                callback(null,node);
            };
        if(relids.indexOf(jNode.RELID) != -1){
            _core.loadChild(parentNode,jNode.RELID,function(err,oldChild){
                if(err){
                    callback(err,null);
                } else {
                    if(_core.getGuid(oldChild) === jNode.GUID){
                        if(noClear === true){
                            callback(null,oldChild);
                        } else {
                            var root = _core.getRoot(oldChild);
                            _core.deleteNode(oldChild);
                            _core.persist(root,function(){
                                returnNewNode();
                            });
                        }
                    } else {
                        returnNewNode();
                    }
                }
            });
        } else {
            returnNewNode();
        }
    }
    function importNode(jNode,parentNode,intPath,noClear,callback){
        //first we have to get the base of the node
        if(jNode.pointers && jNode.pointers.base && jNode.pointers.base.to){
            getReferenceNode(jNode.pointers.base.to[0],function(err,base){
                if(err){
                    callback(err);
                } else {
                   getEmptyNode(jNode,parentNode,base,noClear,function(err,node){
                        if(err){
                            callback(err);
                        } else {
                            internalRefCreated(intPath,node);
                            importAttributes(node,jNode);
                            importRegistry(node,jNode);
                            importChildren(node,jNode,intPath,function(err){
                                if(err){
                                    callback(err);
                                } else {
                                    importRelations(node,jNode,function(err){
                                        if(err){
                                            callback(err);
                                        } else {
                                            importMeta(node,jNode,function(err){
                                                callback(err);
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    });
                }
            });
        } else {
            callback('wrong import format: base info is wrong');
        }
    }

    function importing(core,parent,jNode,callback){
        _core = core;
        _cache = {};
        _underImport = {};
        _internalRefHash = {};
        META.initialize(_core,_cache,function(){});

        if(jNode.length){
            //multiple objects
            if(parent){
                var needed = jNode.length,
                    error = null;
                _cache[core.getPath(parent)] = parent;
                _root = core.getRoot(parent);
                for(var i=0;i<jNode.length;i++){
                    importNode(jNode[i],parent,'#['+i+']',false,function(err){
                        error = error || err;
                        if(--needed === 0){
                            callback(error);
                        }
                    });
                }
            } else {
                callback('no parent given!!!');
            }
        } else {
            //single object
            if(parent){
                _cache[core.getPath(parent)] = parent;
                _root = core.getRoot(parent);
                importNode(jNode,parent,'#',false,callback);
            } else {
                importRoot(jNode,callback);
            }
        }
    }

    return importing;
});

<|endoftext|>


<commit_before>angular.module('anol.measure')
/**
 * @ngdoc directive
 * @name anol.measure.directive:anolLineMeasure
 *
 * @requires anol.map.MapService
 * @requires anol.map.ControlsSerivce
 * @requries anol.map.LayersService
 *
 * @param {string} anolMeasure Type of measurement. Supported values are *line* and *area*. Default: *line*
 * @param {boolean} geodesic Use geodesic measure method
 * @param {ol.style.Style} style Style for drawed measures
 * @param {string} tooltipPlacement Position of tooltip
 * @param {number} tooltipDelay Time in milisecounds to wait before display tooltip
 * @param {boolean} tooltipEnable Enable tooltips. Default true for non-touch screens, default false for touchscreens
 * @param {string} templateUrl Url to template to use instead of default one
 * @param {boolean} addToMap Create control and add to map when placed inside map. Default: true
 * @param {function} activate Pass name of function to activate control from outer scope
 * @param {function} decativate Pass name of function to deactivate control from outer scope
 * @param {function} measureResultCallback Given function is called when measure result is available
 * @param {function} activatedCallback Given function is called when control is activated
 * @param {function} deactivatedCallback Given function is called when control is deactivated
 *
 * @description
 * Point, Line or area measurement
 */
.directive('anolMeasure', ['$timeout', 'ControlsService', 'LayersService', 'MapService', function($timeout, ControlsService, LayersService, MapService) {
    // create a sphere whose radius is equal to the semi-major axis of the WGS84 ellipsoid
    var wgs84Sphere = new ol.Sphere(6378137);
    var measureStyle = new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.5)',
            lineDash: [10, 10],
            width: 2,
            opacity: 0.5
        }),
        image: new ol.style.Circle({
            radius: 5,
            stroke: new ol.style.Stroke({
                color: 'rgba(0, 0, 0, 0.7)'
            })
        })
    });

    var calculateCoordinate = function(geometry, projection, geodesic) {
        return geometry.getCoordinates();
    };

    var calculateLength = function(geometry, projection, geodesic) {
        var length;
        if (geodesic) {
            var coordinates = geometry.getCoordinates();
            if(coordinates.length === 1) {
                return 0;
            }
            length = 0;
            for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
                var c1 = ol.proj.transform(coordinates[i], projection, 'EPSG:4326');
                var c2 = ol.proj.transform(coordinates[i + 1], projection, 'EPSG:4326');
                length += wgs84Sphere.haversineDistance(c1, c2);
            }
        } else {
            length = Math.round(geometry.getLength() * 100) / 100;
        }
        return length;
    };

    var calculateArea = function(geometry, projection, geodesic) {
        if(geometry.getType() !== 'Polygon') {
            return 0.0;
        }
        var area;
        if (geodesic) {
            var geom = /** @type {ol.geom.Polygon} */(geometry.clone().transform(
                projection, 'EPSG:4326'));
            var coordinates = geom.getLinearRing(0).getCoordinates();
            area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
        } else {
            area = geometry.getArea();
        }
        return area;
    };

    var formatCoordinateResult = function(geometry, projection, geodesic) {
        var coord = ol.proj.transform(geometry.getCoordinates(),
                                     projection,
                                     'EPSG:4326');
        var output = '';
        output += coord[0] + ' lat | ';
        output += coord[1] + ' lon';
        return output;
    };

    var formatLineResult = function(geometry, projection, geodesic) {
        var length = calculateLength(geometry, projection, geodesic);
        var output;
        if (length > 100) {
            output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km';
        } else {
            output = (Math.round(length * 100) / 100) + ' ' + 'm';
        }
        return output;
    };

    var formatAreaResult = function(geometry, projection, geodesic) {
        var area = calculateArea(geometry, projection, geodesic);
        var output;
        if (area > 10000) {
            output = (Math.round(area / 10000 * 100) / 100) +
                     ' ' + 'ha';
        } else {
            output = Math.round(area) +
                     ' ' + 'm2';
      }
      return output;
    };

    var handlePointMeasure = function(geometry, coordinate) {
        return new ol.geom.Point(coordinate);
    };

    var handleLineMeasure = function(geometry, coordinate) {
        switch(geometry.getType()) {
            case 'Point':
                return new ol.geom.LineString([
                    geometry.getCoordinates(),
                    coordinate
                ]);
            case 'LineString':
                var coords = geometry.getCoordinates();
                coords.push(coordinate);
                return new ol.geom.LineString(coords);
        }
    };

    var handleAreaMeasure = function(geometry, coordinate) {
        var coords;
        switch(geometry.getType()) {
            case 'Point':
                return new ol.geom.LineString([
                    geometry.getCoordinates(),
                    coordinate
                ]);
            case 'LineString':
                coords = geometry.getCoordinates();
                coords.push(coordinate);
                coords.push(coords[0]);
                return new ol.geom.Polygon([coords]);
            case 'Polygon':
                coords = geometry.getCoordinates()[0];
                coords.splice(coords.length - 1, 0, coordinate);
                return new ol.geom.Polygon([coords]);
        }
    };

    var createMeasureOverlay = function() {
        var element = angular.element('

');
        element.addClass('anol-overlay');
        element.addClass('anol-measure-overlay');
        var overlay = new ol.Overlay({
            element: element[0],
            offset: [0, -15],
            positioning: 'bottom-center'
        });
        return overlay;
    };

    var createModifyInteraction = function(measureSource, measureType, measureOverlay, measureResultCallback, projection, geodesic) {
        var modify = new ol.interaction.Modify({
            features: measureSource.getFeaturesCollection()
        });
        modify.on('modifyend', function(evt) {
            var resultFormatter, resultCalculator;
            switch(measureType) {
                case 'point':
                    resultCalculator = calculateCoordinate;
                    resultFormatter = formatCoordinateResult;
                    break;
                case 'line':
                    resultCalculator = calculateLength;
                    resultFormatter = formatLineResult;
                    break;
                case 'area':
                    resultCalculator = calculateArea;
                    resultFormatter = formatAreaResult;
                    break;
            }
            var geometry = measureSource.getFeatures()[0].getGeometry();

            if(angular.isFunction(measureResultCallback)) {
                measureResultCallback({
                    type: measureType,
                    value: resultCalculator(geometry, projection, geodesic)
                });
                return;
            }

            measureOverlay.getElement().innerHTML = resultFormatter(geometry, projection, geodesic);
            measureOverlay.setPosition(geometry.getLastCoordinate());
        });
        return modify;
    };

    var createDrawInteraction = function(measureSource, measureType, measureOverlay, measureResultCallback, projection, geodesic) {
        var draw = new ol.interaction.Draw({
            type: 'Point',
            style: new ol.style.Style({})
        });

        draw.on('drawstart',
            function(evt) {
                var sketch = evt.feature;

                /** @type {ol.Coordinate|undefined} */
                var coord = evt.coordinate;
                measureOverlay.setPosition(coord);

                var geometryCreator;
                var resultCalculator;
                var resultFormatter;
                switch(measureType) {
                    case 'point':
                        geometryCreator = handlePointMeasure;
                        resultCalculator = calculateCoordinate;
                        resultFormatter = formatCoordinateResult;
                        break;
                    case 'line':
                        geometryCreator = handleLineMeasure;
                        resultCalculator = calculateLength;
                        resultFormatter = formatLineResult;
                        break;
                    case 'area':
                        geometryCreator = handleAreaMeasure;
                        resultCalculator = calculateArea;
                        resultFormatter = formatAreaResult;
                        break;
                }

                var features = measureSource.getFeatures();
                if(features.length === 0) {
                    measureSource.addFeature(sketch);
                    if(angular.isFunction(measureResultCallback)) {
                        measureResultCallback({
                            type: measureType,
                            value: resultCalculator(sketch.getGeometry(), projection, geodesic)
                        });
                    }
                    return;
                }

                var newGeometry = geometryCreator(features[0].getGeometry(),
                                                  sketch.getGeometry().getCoordinates());
                features[0].setGeometry(newGeometry);

                if(angular.isFunction(measureResultCallback)) {
                    measureResultCallback({
                        type: measureType,
                        value: resultCalculator(newGeometry, projection, geodesic)
                    });
                    return;
                }

                measureOverlay.getElement().innerHTML = resultFormatter(newGeometry, projection, geodesic);
                measureOverlay.setPosition(newGeometry.getLastCoordinate());
            }, this
        );
        return draw;
    };

    return {
        restrict: 'A',
        require: '?^anolMap',
        replace: true,
        scope: {
            measureType: '@anolMeasure',
            geodesic: '@',
            style: '=?',
            tooltipPlacement: '@',
            tooltipDelay: '@',
            tooltipEnable: '@',
            addToMap: '@?',
            activate: '=?',
            deactivate: '=?',
            measureResultCallback: '=?',
            activatedCallback: '=?',
            deactivatedCallback: '=?'
        },
        templateUrl: function(tElement, tAttrs) {
            var defaultUrl = 'src/modules/measure/templates/measure.html';
            return tAttrs.templateUrl || defaultUrl;
        },
        link: function(scope, element, attrs, AnolMapController) {
            //attribute defaults
            scope.tooltipPlacement = angular.isDefined(scope.tooltipPlacement) ?
                scope.tooltipPlacement : 'right';
            scope.tooltipDelay = angular.isDefined(scope.tooltipDelay) ?
                scope.tooltipDelay : 500;
            scope.tooltipEnable = angular.isDefined(scope.tooltipEnable) ?
                scope.tooltipEnable : !ol.has.TOUCH;
            scope.geodesic = scope.geodesic === true || scope.geodesic === 'true';
            var control;

            // create layer to draw in
            var measureSource = new ol.source.Vector({
                useSpatialIndex: false
            });
            var _measureLayer = new ol.layer.Vector({
                source: measureSource,
                style: scope.style || measureStyle
            });

            var layerOptions = {
                title: 'lineMeasureLayer',
                name: 'lineMeasureLayer',
                displayInLayerswitcher: false,
                olLayer: _measureLayer
            };

            var map = MapService.getMap();

            var measureOverlay = createMeasureOverlay();

            var draw = createDrawInteraction(measureSource,
                                             scope.measureType,
                                             measureOverlay,
                                             scope.measureResultCallback,
                                             map.getView().getProjection(),
                                             scope.geodesic);

            var modify = createModifyInteraction(measureSource,
                                                 scope.measureType,
                                                 measureOverlay,
                                                 scope.measureResultCallback,
                                                 map.getView().getProjection(),
                                                 scope.geodesic);

            scope.measure = function() {
                if(control.active) {
                    control.deactivate();
                } else {
                    control.activate();
                }
            };

            var deactivate = function() {
                map.removeInteraction(draw);
                map.removeInteraction(modify);
                measureSource.clear();
                map.removeOverlay(measureOverlay);
                measureOverlay.getElement().innerHTML = '';
                if(angular.isFunction(scope.deactivatedCallback)) {
                    scope.deactivatedCallback();
                }
            };

            var activate = function() {
                map.addInteraction(draw);
                map.addInteraction(modify);
                map.addOverlay(measureOverlay);
                if(angular.isFunction(scope.activatedCallback)) {
                    scope.activatedCallback();
                }
            };

            scope.deactivate = function() {
                control.deactivate();
            };

            scope.activate = function() {
                control.activate();
            };

            LayersService.addSystemLayer(new anol.layer.Layer(layerOptions), 0);

            if(AnolMapController === null || scope.addToMap === false || scope.addToMap === 'false') {
                control = new anol.control.Control({
                    exclusive: true,
                    olControl: null
                });
            } else {
                element.addClass('ol-control');
                element.addClass('anol-measure-' + scope.measureType);
                control = new anol.control.Control({
                    element: element,
                    exclusive: true
                });
            }

            control.onDeactivate(deactivate);
            control.onActivate(activate);
            ControlsService.addControl(control);
        }
    };
}]);
<commit_msg>Return always 0 in calculateLength for non linestrings<commit_after>angular.module('anol.measure')
/**
 * @ngdoc directive
 * @name anol.measure.directive:anolLineMeasure
 *
 * @requires anol.map.MapService
 * @requires anol.map.ControlsSerivce
 * @requries anol.map.LayersService
 *
 * @param {string} anolMeasure Type of measurement. Supported values are *line* and *area*. Default: *line*
 * @param {boolean} geodesic Use geodesic measure method
 * @param {ol.style.Style} style Style for drawed measures
 * @param {string} tooltipPlacement Position of tooltip
 * @param {number} tooltipDelay Time in milisecounds to wait before display tooltip
 * @param {boolean} tooltipEnable Enable tooltips. Default true for non-touch screens, default false for touchscreens
 * @param {string} templateUrl Url to template to use instead of default one
 * @param {boolean} addToMap Create control and add to map when placed inside map. Default: true
 * @param {function} activate Pass name of function to activate control from outer scope
 * @param {function} decativate Pass name of function to deactivate control from outer scope
 * @param {function} measureResultCallback Given function is called when measure result is available
 * @param {function} activatedCallback Given function is called when control is activated
 * @param {function} deactivatedCallback Given function is called when control is deactivated
 *
 * @description
 * Point, Line or area measurement
 */
.directive('anolMeasure', ['$timeout', 'ControlsService', 'LayersService', 'MapService', function($timeout, ControlsService, LayersService, MapService) {
    // create a sphere whose radius is equal to the semi-major axis of the WGS84 ellipsoid
    var wgs84Sphere = new ol.Sphere(6378137);
    var measureStyle = new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.5)',
            lineDash: [10, 10],
            width: 2,
            opacity: 0.5
        }),
        image: new ol.style.Circle({
            radius: 5,
            stroke: new ol.style.Stroke({
                color: 'rgba(0, 0, 0, 0.7)'
            })
        })
    });

    var calculateCoordinate = function(geometry, projection, geodesic) {
        return geometry.getCoordinates();
    };

    var calculateLength = function(geometry, projection, geodesic) {
        if(geometry.getType() !== 'LineString') {
            return 0;
        }
        var length;
        if (geodesic) {
            var coordinates = geometry.getCoordinates();
            length = 0;
            for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
                var c1 = ol.proj.transform(coordinates[i], projection, 'EPSG:4326');
                var c2 = ol.proj.transform(coordinates[i + 1], projection, 'EPSG:4326');
                length += wgs84Sphere.haversineDistance(c1, c2);
            }
        } else {
            length = Math.round(geometry.getLength() * 100) / 100;
        }
        return length;
    };

    var calculateArea = function(geometry, projection, geodesic) {
        if(geometry.getType() !== 'Polygon') {
            return 0.0;
        }
        var area;
        if (geodesic) {
            var geom = /** @type {ol.geom.Polygon} */(geometry.clone().transform(
                projection, 'EPSG:4326'));
            var coordinates = geom.getLinearRing(0).getCoordinates();
            area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
        } else {
            area = geometry.getArea();
        }
        return area;
    };

    var formatCoordinateResult = function(geometry, projection, geodesic) {
        var coord = ol.proj.transform(geometry.getCoordinates(),
                                     projection,
                                     'EPSG:4326');
        var output = '';
        output += coord[0] + ' lat | ';
        output += coord[1] + ' lon';
        return output;
    };

    var formatLineResult = function(geometry, projection, geodesic) {
        var length = calculateLength(geometry, projection, geodesic);
        var output;
        if (length > 100) {
            output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km';
        } else {
            output = (Math.round(length * 100) / 100) + ' ' + 'm';
        }
        return output;
    };

    var formatAreaResult = function(geometry, projection, geodesic) {
        var area = calculateArea(geometry, projection, geodesic);
        var output;
        if (area > 10000) {
            output = (Math.round(area / 10000 * 100) / 100) +
                     ' ' + 'ha';
        } else {
            output = Math.round(area) +
                     ' ' + 'm2';
      }
      return output;
    };

    var handlePointMeasure = function(geometry, coordinate) {
        return new ol.geom.Point(coordinate);
    };

    var handleLineMeasure = function(geometry, coordinate) {
        switch(geometry.getType()) {
            case 'Point':
                return new ol.geom.LineString([
                    geometry.getCoordinates(),
                    coordinate
                ]);
            case 'LineString':
                var coords = geometry.getCoordinates();
                coords.push(coordinate);
                return new ol.geom.LineString(coords);
        }
    };

    var handleAreaMeasure = function(geometry, coordinate) {
        var coords;
        switch(geometry.getType()) {
            case 'Point':
                return new ol.geom.LineString([
                    geometry.getCoordinates(),
                    coordinate
                ]);
            case 'LineString':
                coords = geometry.getCoordinates();
                coords.push(coordinate);
                coords.push(coords[0]);
                return new ol.geom.Polygon([coords]);
            case 'Polygon':
                coords = geometry.getCoordinates()[0];
                coords.splice(coords.length - 1, 0, coordinate);
                return new ol.geom.Polygon([coords]);
        }
    };

    var createMeasureOverlay = function() {
        var element = angular.element('

');
        element.addClass('anol-overlay');
        element.addClass('anol-measure-overlay');
        var overlay = new ol.Overlay({
            element: element[0],
            offset: [0, -15],
            positioning: 'bottom-center'
        });
        return overlay;
    };

    var createModifyInteraction = function(measureSource, measureType, measureOverlay, measureResultCallback, projection, geodesic) {
        var modify = new ol.interaction.Modify({
            features: measureSource.getFeaturesCollection()
        });
        modify.on('modifyend', function(evt) {
            var resultFormatter, resultCalculator;
            switch(measureType) {
                case 'point':
                    resultCalculator = calculateCoordinate;
                    resultFormatter = formatCoordinateResult;
                    break;
                case 'line':
                    resultCalculator = calculateLength;
                    resultFormatter = formatLineResult;
                    break;
                case 'area':
                    resultCalculator = calculateArea;
                    resultFormatter = formatAreaResult;
                    break;
            }
            var geometry = measureSource.getFeatures()[0].getGeometry();

            if(angular.isFunction(measureResultCallback)) {
                measureResultCallback({
                    type: measureType,
                    value: resultCalculator(geometry, projection, geodesic)
                });
                return;
            }

            measureOverlay.getElement().innerHTML = resultFormatter(geometry, projection, geodesic);
            measureOverlay.setPosition(geometry.getLastCoordinate());
        });
        return modify;
    };

    var createDrawInteraction = function(measureSource, measureType, measureOverlay, measureResultCallback, projection, geodesic) {
        var draw = new ol.interaction.Draw({
            type: 'Point',
            style: new ol.style.Style({})
        });

        draw.on('drawstart',
            function(evt) {
                var sketch = evt.feature;

                /** @type {ol.Coordinate|undefined} */
                var coord = evt.coordinate;
                measureOverlay.setPosition(coord);

                var geometryCreator;
                var resultCalculator;
                var resultFormatter;
                switch(measureType) {
                    case 'point':
                        geometryCreator = handlePointMeasure;
                        resultCalculator = calculateCoordinate;
                        resultFormatter = formatCoordinateResult;
                        break;
                    case 'line':
                        geometryCreator = handleLineMeasure;
                        resultCalculator = calculateLength;
                        resultFormatter = formatLineResult;
                        break;
                    case 'area':
                        geometryCreator = handleAreaMeasure;
                        resultCalculator = calculateArea;
                        resultFormatter = formatAreaResult;
                        break;
                }

                var features = measureSource.getFeatures();
                if(features.length === 0) {
                    measureSource.addFeature(sketch);
                    if(angular.isFunction(measureResultCallback)) {
                        measureResultCallback({
                            type: measureType,
                            value: resultCalculator(sketch.getGeometry(), projection, geodesic)
                        });
                    }
                    return;
                }

                var newGeometry = geometryCreator(features[0].getGeometry(),
                                                  sketch.getGeometry().getCoordinates());
                features[0].setGeometry(newGeometry);

                if(angular.isFunction(measureResultCallback)) {
                    measureResultCallback({
                        type: measureType,
                        value: resultCalculator(newGeometry, projection, geodesic)
                    });
                    return;
                }

                measureOverlay.getElement().innerHTML = resultFormatter(newGeometry, projection, geodesic);
                measureOverlay.setPosition(newGeometry.getLastCoordinate());
            }, this
        );
        return draw;
    };

    return {
        restrict: 'A',
        require: '?^anolMap',
        replace: true,
        scope: {
            measureType: '@anolMeasure',
            geodesic: '@',
            style: '=?',
            tooltipPlacement: '@',
            tooltipDelay: '@',
            tooltipEnable: '@',
            addToMap: '@?',
            activate: '=?',
            deactivate: '=?',
            measureResultCallback: '=?',
            activatedCallback: '=?',
            deactivatedCallback: '=?'
        },
        templateUrl: function(tElement, tAttrs) {
            var defaultUrl = 'src/modules/measure/templates/measure.html';
            return tAttrs.templateUrl || defaultUrl;
        },
        link: function(scope, element, attrs, AnolMapController) {
            //attribute defaults
            scope.tooltipPlacement = angular.isDefined(scope.tooltipPlacement) ?
                scope.tooltipPlacement : 'right';
            scope.tooltipDelay = angular.isDefined(scope.tooltipDelay) ?
                scope.tooltipDelay : 500;
            scope.tooltipEnable = angular.isDefined(scope.tooltipEnable) ?
                scope.tooltipEnable : !ol.has.TOUCH;
            scope.geodesic = scope.geodesic === true || scope.geodesic === 'true';
            var control;

            // create layer to draw in
            var measureSource = new ol.source.Vector({
                useSpatialIndex: false
            });
            var _measureLayer = new ol.layer.Vector({
                source: measureSource,
                style: scope.style || measureStyle
            });

            var layerOptions = {
                title: 'lineMeasureLayer',
                name: 'lineMeasureLayer',
                displayInLayerswitcher: false,
                olLayer: _measureLayer
            };

            var map = MapService.getMap();

            var measureOverlay = createMeasureOverlay();

            var draw = createDrawInteraction(measureSource,
                                             scope.measureType,
                                             measureOverlay,
                                             scope.measureResultCallback,
                                             map.getView().getProjection(),
                                             scope.geodesic);

            var modify = createModifyInteraction(measureSource,
                                                 scope.measureType,
                                                 measureOverlay,
                                                 scope.measureResultCallback,
                                                 map.getView().getProjection(),
                                                 scope.geodesic);

            scope.measure = function() {
                if(control.active) {
                    control.deactivate();
                } else {
                    control.activate();
                }
            };

            var deactivate = function() {
                map.removeInteraction(draw);
                map.removeInteraction(modify);
                measureSource.clear();
                map.removeOverlay(measureOverlay);
                measureOverlay.getElement().innerHTML = '';
                if(angular.isFunction(scope.deactivatedCallback)) {
                    scope.deactivatedCallback();
                }
            };

            var activate = function() {
                map.addInteraction(draw);
                map.addInteraction(modify);
                map.addOverlay(measureOverlay);
                if(angular.isFunction(scope.activatedCallback)) {
                    scope.activatedCallback();
                }
            };

            scope.deactivate = function() {
                control.deactivate();
            };

            scope.activate = function() {
                control.activate();
            };

            LayersService.addSystemLayer(new anol.layer.Layer(layerOptions), 0);

            if(AnolMapController === null || scope.addToMap === false || scope.addToMap === 'false') {
                control = new anol.control.Control({
                    exclusive: true,
                    olControl: null
                });
            } else {
                element.addClass('ol-control');
                element.addClass('anol-measure-' + scope.measureType);
                control = new anol.control.Control({
                    element: element,
                    exclusive: true
                });
            }

            control.onDeactivate(deactivate);
            control.onActivate(activate);
            ControlsService.addControl(control);
        }
    };
}]);
<|endoftext|>


<commit_before>/*
  Copyright 2018 Google LLC

  Use of this source code is governed by an MIT-style
  license that can be found in the LICENSE file or at
  https://opensource.org/licenses/MIT.
*/

const gulp = require('gulp');

const getNpmCmd = require('./utils/get-npm-cmd');
const spawn = require('./utils/spawn-promise-wrapper');

gulp.task('publish-lerna', () => {
  return spawn(getNpmCmd(), [
    'run', 'local-lerna',
    '--',
    'publish',

    // The following flags can be used if publishing non-stable versions
    // '--cd-version=prerelease',
    // '--preid=beta',
    // '--npm-tag', 'beta',
  ]);
});
<commit_msg>Use npm-tag=alpha (#1693)<commit_after>/*
  Copyright 2018 Google LLC

  Use of this source code is governed by an MIT-style
  license that can be found in the LICENSE file or at
  https://opensource.org/licenses/MIT.
*/

const gulp = require('gulp');

const getNpmCmd = require('./utils/get-npm-cmd');
const spawn = require('./utils/spawn-promise-wrapper');

gulp.task('publish-lerna', () => {
  return spawn(getNpmCmd(), [
    'run', 'local-lerna',
    '--',
    'publish',

    // The following flags can be used if publishing non-stable versions
    '--cd-version=prerelease',
    '--preid=alpha',
    '--npm-tag', 'alpha',
  ]);
});
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _reactVirtualized = require('react-virtualized');

require('react-virtualized/styles.css');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var List = function (_React$Component) {
  _inherits(List, _React$Component);

  function List() {
    _classCallCheck(this, List);

    return _possibleConstructorReturn(this, Object.getPrototypeOf(List).apply(this, arguments));
  }

  _createClass(List, [{
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(nextProps) {
      var currentData = this.props.data;
      var newData = nextProps.data;

      if (currentData.length === newData.length) {
        if (!_lodash2.default.isEqual(currentData, newData)) {
          this._virtualScroll.recomputeRowHeights();
        }
      }
    }
  }, {
    key: 'groupDataAndAddHeaders',
    value: function groupDataAndAddHeaders(data, groupBy) {
      var groupedDataObject = _lodash2.default.groupBy(data, groupBy);
      var groupedDataObjectKeys = Object.keys(groupedDataObject);

      var groupedData2DArrayWithHeaders = groupedDataObjectKeys.map(function (key) {
        var array = groupedDataObject[key];
        var header = { type: 'header', title: key };

        return _lodash2.default.concat([header], array);
      });

      return _lodash2.default.flatten(groupedData2DArrayWithHeaders);
    }
  }, {
    key: 'sortData',
    value: function sortData(data, sortBy) {
      return _lodash2.default.sortBy(data, sortBy);
    }
  }, {
    key: 'checkTypesAndReturnMatchingItemType',
    value: function checkTypesAndReturnMatchingItemType(index, data) {
      var itemTypes = this.props.itemTypes;

      var dataItem = data[index];

      if (_lodash2.default.isArray(itemTypes)) {
        var typesToMatch = itemTypes.map(function (item) {
          return item.type;
        });

        if (typesToMatch.includes(dataItem.type)) {
          var itemType = _lodash2.default.find(itemTypes, { type: dataItem.type });

          return itemType;
        }

        throw new Error('Invalid prop `data` supplied to `List`. An object of `data` has a type property' + ' that does not match a passed in type from `itemTypes`.');
      }

      return itemTypes;
    }
  }, {
    key: 'checkForModificationsAndReturnModifiedData',
    value: function checkForModificationsAndReturnModifiedData(data) {
      var _props = this.props;
      var groupBy = _props.groupBy;
      var sortBy = _props.sortBy;

      var modifiableData = data;

      if (sortBy) {
        modifiableData = this.sortData(modifiableData, sortBy);
      }

      if (groupBy) {
        modifiableData = this.groupDataAndAddHeaders(modifiableData, groupBy);
      }

      return modifiableData;
    }
  }, {
    key: 'rowRenderer',
    value: function rowRenderer(index, data) {
      var itemType = this.checkTypesAndReturnMatchingItemType(index, data);
      var ListItemComponent = itemType.component;

      return _react2.default.createElement(ListItemComponent, { data: data, index: index });
    }
  }, {
    key: 'rowHeight',
    value: function rowHeight(index, data) {
      var itemType = this.checkTypesAndReturnMatchingItemType(index, data);

      return itemType.height;
    }
  }, {
    key: 'render',
    value: function render() {
      var _this2 = this;

      var _props2 = this.props;
      var className = _props2.className;
      var thresholdRows = _props2.thresholdRows;

      var data = this.checkForModificationsAndReturnModifiedData(this.props.data);

      return _react2.default.createElement(
        _reactVirtualized.AutoSizer,
        null,
        function (_ref) {
          var height = _ref.height;
          var width = _ref.width;
          return _react2.default.createElement(_reactVirtualized.VirtualScroll, {
            className: className,
            height: height,
            overscanRows: thresholdRows,
            ref: function ref(_ref2) {
              _this2._virtualScroll = _ref2;
            },
            rowsCount: data.length,
            rowHeight: function rowHeight(index) {
              return _this2.rowHeight(index, data);
            },
            rowRenderer: function rowRenderer(index) {
              return _this2.rowRenderer(index, data);
            },
            width: width
          });
        }
      );
    }
  }]);

  return List;
}(_react2.default.Component);

List.propTypes = {
  className: _react.PropTypes.string,
  data: function data(props, propName, componentName) {
    var data = props.data;

    if (!data) {
      return new Error('Required prop `' + propName + '` was not specified in `' + componentName + '`.');
    }

    if (!_lodash2.default.isArray(data)) {
      return new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` to be an array.'));
    }

    if (_lodash2.default.isArray(props.itemTypes)) {
      data.forEach(function (dataItem) {
        if (!_lodash2.default.isObject(dataItem)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` to be an array of objects.'));
        } else if (!dataItem.type) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. An object of ' + ('`' + propName + '` is missing the required property `type`.'));
        } else if (!_lodash2.default.isString(dataItem.type)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. An object of ' + ('`' + propName + '` has a TypeError for the required property `type`.'));
        }
      });
    }

    return null;
  },
  groupBy: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.func, _react2.default.PropTypes.string]),
  itemTypes: function itemTypes(props, propName, componentName) {
    var itemTypes = props.itemTypes;

    if (!itemTypes) {
      return new Error('Required prop `' + propName + '` was not specified in `' + componentName + '`.');
    }

    if (_lodash2.default.isArray(itemTypes)) {
      itemTypes.forEach(function (item) {
        if (!item.type || !item.component || !item.height) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have required type, component,') + ' and height properties.');
        } else if (!_lodash2.default.isString(item.type)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a type property of type String.'));
        } else if (!_lodash2.default.isNumber(item.height)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a height property of type Number.'));
        } else if (!_lodash2.default.isFunction(item.component)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a component property of type Function.'));
        }
      });
    } else if (_lodash2.default.isObject(itemTypes)) {
      if (!itemTypes.component || !itemTypes.height) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have required component and height properties.'));
      } else if (!_lodash2.default.isNumber(itemTypes.height)) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a height property of type Number.'));
      } else if (!_lodash2.default.isFunction(itemTypes.component)) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a component property of type Function.'));
      }
    } else {
      throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` to be an object or an array of objects.'));
    }

    return null;
  },
  sortBy: _react2.default.PropTypes.node,
  thresholdRows: _react2.default.PropTypes.number
};

exports.default = List;<commit_msg>build list<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _reactVirtualized = require('react-virtualized');

require('react-virtualized/styles.css');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var List = function (_React$Component) {
  _inherits(List, _React$Component);

  function List() {
    _classCallCheck(this, List);

    return _possibleConstructorReturn(this, Object.getPrototypeOf(List).apply(this, arguments));
  }

  _createClass(List, [{
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(nextProps) {
      var currentData = this.props.data;
      var newData = nextProps.data;

      if (currentData.length === newData.length) {
        if (!_lodash2.default.isEqual(currentData, newData)) {
          this._virtualScroll.recomputeRowHeights();
        }
      }
    }
  }, {
    key: 'groupDataAndAddHeaders',
    value: function groupDataAndAddHeaders(data, groupBy) {
      var groupedDataObject = _lodash2.default.groupBy(data, groupBy);
      var groupedDataObjectKeys = Object.keys(groupedDataObject);

      var groupedData2DArrayWithHeaders = groupedDataObjectKeys.map(function (key) {
        var array = groupedDataObject[key];
        var header = { type: 'header', title: key };

        return _lodash2.default.concat([header], array);
      });

      return _lodash2.default.flatten(groupedData2DArrayWithHeaders);
    }
  }, {
    key: 'sortData',
    value: function sortData(data, sortBy) {
      return _lodash2.default.sortBy(data, sortBy);
    }
  }, {
    key: 'checkTypesAndReturnMatchingItemType',
    value: function checkTypesAndReturnMatchingItemType(index, data) {
      var itemTypes = this.props.itemTypes;

      var dataItem = data[index];

      if (_lodash2.default.isArray(itemTypes)) {
        var typesToMatch = itemTypes.map(function (item) {
          return item.type;
        });

        if (typesToMatch.includes(dataItem.type)) {
          var itemType = _lodash2.default.find(itemTypes, { type: dataItem.type });

          return itemType;
        }

        throw new Error('Invalid prop `data` supplied to `List`. An object of `data` has a type property' + ' that does not match a passed in type from `itemTypes`.');
      }

      return itemTypes;
    }
  }, {
    key: 'checkForModificationsAndReturnModifiedData',
    value: function checkForModificationsAndReturnModifiedData(data) {
      var _props = this.props;
      var groupBy = _props.groupBy;
      var sortBy = _props.sortBy;

      var modifiableData = data;

      if (sortBy) {
        modifiableData = this.sortData(modifiableData, sortBy);
      }

      if (groupBy) {
        modifiableData = this.groupDataAndAddHeaders(modifiableData, groupBy);
      }

      return modifiableData;
    }
  }, {
    key: 'rowRenderer',
    value: function rowRenderer(index, data) {
      var itemType = this.checkTypesAndReturnMatchingItemType(index, data);
      var ListItemComponent = itemType.component;
      var props = _extends({ index: index, data: data }, itemType.componentProps);

      return _react2.default.createElement(ListItemComponent, props);
    }
  }, {
    key: 'rowHeight',
    value: function rowHeight(index, data) {
      var itemType = this.checkTypesAndReturnMatchingItemType(index, data);

      return itemType.height;
    }
  }, {
    key: 'render',
    value: function render() {
      var _this2 = this;

      var _props2 = this.props;
      var className = _props2.className;
      var thresholdRows = _props2.thresholdRows;

      var data = this.checkForModificationsAndReturnModifiedData(this.props.data);

      return _react2.default.createElement(
        _reactVirtualized.AutoSizer,
        null,
        function (_ref) {
          var height = _ref.height;
          var width = _ref.width;
          return _react2.default.createElement(_reactVirtualized.VirtualScroll, {
            className: className,
            height: height,
            overscanRowsCount: thresholdRows,
            ref: function ref(_ref2) {
              _this2._virtualScroll = _ref2;
            },
            rowsCount: data.length,
            rowHeight: function rowHeight(index) {
              return _this2.rowHeight(index, data);
            },
            rowRenderer: function rowRenderer(index) {
              return _this2.rowRenderer(index, data);
            },
            width: width
          });
        }
      );
    }
  }]);

  return List;
}(_react2.default.Component);

List.propTypes = {
  className: _react.PropTypes.string,
  data: function data(props, propName, componentName) {
    var data = props.data;

    if (!data) {
      return new Error('Required prop `' + propName + '` was not specified in `' + componentName + '`.');
    }

    if (!_lodash2.default.isArray(data)) {
      return new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` to be an array.'));
    }

    if (_lodash2.default.isArray(props.itemTypes)) {
      data.forEach(function (dataItem) {
        if (!_lodash2.default.isObject(dataItem)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` to be an array of objects.'));
        } else if (!dataItem.type) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. An object of ' + ('`' + propName + '` is missing the required property `type`.'));
        } else if (!_lodash2.default.isString(dataItem.type)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. An object of ' + ('`' + propName + '` has a TypeError for the required property `type`.'));
        }
      });
    }

    return null;
  },
  groupBy: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.func, _react2.default.PropTypes.string]),
  itemTypes: function itemTypes(props, propName, componentName) {
    var itemTypes = props.itemTypes;

    if (!itemTypes) {
      return new Error('Required prop `' + propName + '` was not specified in `' + componentName + '`.');
    }

    if (_lodash2.default.isArray(itemTypes)) {
      itemTypes.forEach(function (item) {
        if (!item.type || !item.component || !item.height) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have required type, component,') + ' and height properties.');
        } else if (!_lodash2.default.isString(item.type)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a type property of type String.'));
        } else if (!_lodash2.default.isNumber(item.height)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a height property of type Number.'));
        } else if (!_lodash2.default.isFunction(item.component)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a component property of type Function.'));
        } else if (item.componentProps && !_lodash2.default.isObject(item.componentProps)) {
          throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a componentProps property of type Object.'));
        }
      });
    } else if (_lodash2.default.isObject(itemTypes)) {
      if (!itemTypes.component || !itemTypes.height) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have required component and height properties.'));
      } else if (!_lodash2.default.isNumber(itemTypes.height)) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a height property of type Number.'));
      } else if (!_lodash2.default.isFunction(itemTypes.component)) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a component property of type Function.'));
      } else if (itemTypes.componentProps && !_lodash2.default.isObject(itemTypes.componentProps)) {
        throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` object to have a componentProps property of type Object.'));
      }
    } else {
      throw new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. ' + ('Expected `' + propName + '` to be an object or an array of objects.'));
    }

    return null;
  },
  sortBy: _react2.default.PropTypes.node,
  thresholdRows: _react2.default.PropTypes.number
};

exports.default = List;<|endoftext|>