/* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ import XMLUtils from '../util/XMLUtils' import PydioApi from '../http/PydioApi' import User from './User' import Logger from '../lang/Logger' import ResourcesManager from '../http/ResourcesManager' export default class Registry{ constructor(pydioObject){ this._registry = null; this._extensionsRegistry = {"editor":[], "uploader":[]}; this._resourcesRegistry = {}; this._pydioObject = pydioObject; this._xPathLoading = false; this._globalLoading = false; } /** * Parse XML String directly * @param s */ loadFromString(s){ this._registry = XMLUtils.parseXml(s).documentElement; } /** * Load registry from server * @param xPath * @param completeFunc * @param repositoryId */ load(xPath = null, completeFunc = null, repositoryId = null){ if( (xPath === null && this._globalLoading) || (xPath && this._xPathLoading === xPath) ){ return; } if(xPath) this._xPathLoading = xPath; else this._globalLoading = true; const onComplete = function(transport){ if(xPath) this._xPathLoading = false else this._globalLoading = false; if(transport.responseXML == null || transport.responseXML.documentElement == null) return; if(transport.responseXML.documentElement.nodeName == "ajxp_registry"){ this._registry = transport.responseXML.documentElement; if(!completeFunc) { this._pydioObject.fire("registry_loaded", this._registry); } }else if(transport.responseXML.documentElement.nodeName == "ajxp_registry_part"){ this.refreshXmlRegistryPart(transport.responseXML.documentElement); } if(completeFunc) completeFunc(this._registry); }.bind(this); let params = {get_action: 'get_xml_registry'}; if(xPath){ params['xPath'] = xPath; } if(repositoryId){ params['ws_id'] = repositoryId; // for caching only } PydioApi.getClient().request(params, onComplete, null, {method:'get'}); } /** * Inserts a document fragment retrieved from server inside the full tree. * The node must contains the xPath attribute to locate it inside the registry. * Event ajaxplorer:registry_part_loaded is triggerd once this is done. * @param documentElement DOMNode */ refreshXmlRegistryPart (documentElement){ const xPath = documentElement.getAttribute("xPath"); const existingNode = XMLUtils.XPathSelectSingleNode(this._registry, xPath); let parentNode; if(existingNode && existingNode.parentNode){ parentNode = existingNode.parentNode; parentNode.removeChild(existingNode); if(documentElement.firstChild){ parentNode.appendChild(documentElement.firstChild.cloneNode(true)); } }else if(xPath.indexOf("/") > -1){ // try selecting parentNode const parentPath = xPath.substring(0, xPath.lastIndexOf("/")); parentNode = XMLUtils.XPathSelectSingleNode(this._registry, parentPath); if(parentNode && documentElement.firstChild){ parentNode.appendChild(documentElement.firstChild.cloneNode(true)); } }else{ if(documentElement.firstChild) this._registry.appendChild(documentElement.firstChild.cloneNode(true)); } this._pydioObject.fire("registry_part_loaded", xPath); } /** * Translate the XML answer to a new User object */ parseUser(){ let user = null, userNode; if(this._registry){ userNode = XMLUtils.XPathSelectSingleNode(this._registry, "user"); } if(userNode){ const userId = userNode.getAttribute('id'); const children = userNode.childNodes; if(userId){ user = new User(userId, children); } } return user; } /** * * @returns {Element|*|null} */ getXML(){ return this._registry; } /** * Find Extension initialisation nodes (activeCondition, onInit, etc), parses * the XML and execute JS. * @param xmlNode {Element} The extension node * @param extensionDefinition Object Information already collected about this extension * @returns Boolean */ initExtension (xmlNode, extensionDefinition){ const activeCondition = XMLUtils.XPathSelectSingleNode(xmlNode, 'processing/activeCondition'); if(activeCondition && activeCondition.firstChild){ try{ const func = new Function(activeCondition.firstChild.nodeValue.trim()); if(func() === false) return false; }catch(e){} } if(xmlNode.nodeName == 'editor'){ Object.assign(extensionDefinition, { openable : (xmlNode.getAttribute("openable") == "true"), modalOnly : (xmlNode.getAttribute("modalOnly") == "true"), previewProvider : (xmlNode.getAttribute("previewProvider") == "true"), order : (xmlNode.getAttribute("order")?parseInt(xmlNode.getAttribute("order")):0), formId : xmlNode.getAttribute("formId") || null, text : this._pydioObject.MessageHash[xmlNode.getAttribute("text")], title : this._pydioObject.MessageHash[xmlNode.getAttribute("title")], icon : xmlNode.getAttribute("icon"), icon_class : xmlNode.getAttribute("iconClass"), editorActions : xmlNode.getAttribute("actions"), editorClass : xmlNode.getAttribute("className"), mimes : xmlNode.getAttribute("mimes").split(","), write : (xmlNode.getAttribute("write") && xmlNode.getAttribute("write")=="true"?true:false), canWrite : (xmlNode.getAttribute("canWrite") && xmlNode.getAttribute("canWrite")=="true"?true:false) }); }else if(xmlNode.nodeName == 'uploader'){ const th = this._pydioObject.Parameters.get('theme'); let clientForm = XMLUtils.XPathSelectSingleNode(xmlNode, 'processing/clientForm[@theme="'+th+'"]'); if(!clientForm){ clientForm = XMLUtils.XPathSelectSingleNode(xmlNode, 'processing/clientForm'); } if(clientForm && clientForm.getAttribute('module')){ extensionDefinition.moduleName = clientForm.getAttribute('module'); } if(xmlNode.getAttribute("order")){ extensionDefinition.order = parseInt(xmlNode.getAttribute("order")); }else{ extensionDefinition.order = 0; } const extensionOnInit = XMLUtils.XPathSelectSingleNode(xmlNode, 'processing/extensionOnInit'); if(extensionOnInit && extensionOnInit.firstChild){ try{ // @TODO: THIS WILL LIKELY TRIGGER PROTOTYPE CODE eval(extensionOnInit.firstChild.nodeValue); }catch(e){ Logger.error("Ignoring Error in extensionOnInit code:"); Logger.error(extensionOnInit.firstChild.nodeValue); Logger.error(e.message); } } const dialogOnOpen = XMLUtils.XPathSelectSingleNode(xmlNode, 'processing/dialogOnOpen'); if(dialogOnOpen && dialogOnOpen.firstChild){ extensionDefinition.dialogOnOpen = dialogOnOpen.firstChild.nodeValue; } const dialogOnComplete = XMLUtils.XPathSelectSingleNode(xmlNode, 'processing/dialogOnComplete'); if(dialogOnComplete && dialogOnComplete.firstChild){ extensionDefinition.dialogOnComplete = dialogOnComplete.firstChild.nodeValue; } } return true; } /** * Refresh the currently active extensions * Extensions are editors and uploaders for the moment. */ refreshExtensionsRegistry (){ this._extensionsRegistry = {"editor":[], "uploader":[]}; let extensions = XMLUtils.XPathSelectNodes(this._registry, "plugins/editor|plugins/uploader"); for(let i=0;i 1){ editors = editors.sort(function(a,b){ return (a.order||0)-(b.order||0); }); } return editors; } /** * Trigger the load method of the resourcesManager. * @param resourcesManager ResourcesManager * @param callback triggered after JS loaded */ loadEditorResources (resourcesManager, callback){ resourcesManager.load(this._resourcesRegistry, false, callback); } /** * * @param pluginQuery * @returns {Map} */ getPluginConfigs (pluginQuery){ let xpath = 'plugins/*[@id="core.'+pluginQuery+'"]/plugin_configs/property | plugins/*[@id="'+pluginQuery+'"]/plugin_configs/property'; if(pluginQuery.indexOf('.') == -1){ xpath = 'plugins/'+pluginQuery+'/plugin_configs/property |' + xpath; } const properties = XMLUtils.XPathSelectNodes(this._registry, xpath); let configs = new Map(); properties.forEach(function(propNode){ configs.set(propNode.getAttribute("name"), JSON.parse(propNode.firstChild.nodeValue)); }); return configs; } /** * * @param pluginId * @param paramName * @returns {string} */ getDefaultImageFromParameters(pluginId, paramName){ const node = XMLUtils.XPathSelectSingleNode(this._registry, "plugins/*[@id='"+pluginId+"']/server_settings/global_param[@name='"+paramName+"']"); if(!node) return ''; return node.getAttribute("defaultImage") || ''; } /** * * @param type * @param name * @returns {bool} */ hasPluginOfType (type, name){ let node; if(name == null){ node = XMLUtils.XPathSelectSingleNode(this._registry, 'plugins/ajxp_plugin[contains(@id, "'+type+'.")] | plugins/' + type + '[@id]'); }else{ node = XMLUtils.XPathSelectSingleNode(this._registry, 'plugins/ajxp_plugin[@id="'+type+'.'+name+'"] | plugins/' + type + '[@id="'+type+'.'+name+'"]'); } return (node != undefined); } }