/******************************************************************************* * Copyright (c) 2011 Subgraph. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Subgraph - initial API and implementation ******************************************************************************/ package com.subgraph.vega.impl.scanner.modules.scripting; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.Scriptable; import com.subgraph.vega.api.scanner.modules.ModuleScriptType; public class ModuleValidator { private final Scriptable moduleScope; private String moduleName; private String categoryName; private ModuleScriptType moduleType; private Function runFunction; private boolean isValidated; private boolean isDisabled; private boolean isDefaultDisabled; public ModuleValidator(Scriptable moduleScope) { this.moduleScope = moduleScope; } public static class ModuleValidationException extends Exception { private static final long serialVersionUID = 1L; ModuleValidationException(String message) { super(message); } } public void validate() throws ModuleValidationException { if(isValidated) return; final Scriptable moduleObject = getModule(); moduleName = getStringFromModuleObject(moduleObject, "name"); moduleType = getScriptType(moduleObject); if(hasStringInModuleObject(moduleObject, "category")) categoryName = getStringFromModuleObject(moduleObject, "category"); else categoryName = moduleType.getVerboseName(); runFunction = getEntryFunction(); isDisabled = getFlagFromModuleObject(moduleObject, "disabled"); isDefaultDisabled = getFlagFromModuleObject(moduleObject, "defaultDisabled"); isValidated = true; } public String getName() { if(!isValidated) throw new IllegalStateException("Cannot get name because module is not validated"); return moduleName; } public String getCategoryName() { if(!isValidated) throw new IllegalStateException("Cannot get category name because module is not validated"); return categoryName; } public boolean isDisabled() { if(!isValidated) throw new IllegalStateException("Cannot get disabled flag because module is not validated"); return isDisabled; } public boolean isDefaultEnabled() { if(!isValidated) throw new IllegalStateException("Cannot get default enabled flag because module is not validated"); return !isDefaultDisabled; } public ModuleScriptType getType() { if(!isValidated) throw new IllegalStateException("Cannot get type because module is not validated"); return moduleType; } public Function getRunFunction() { if(!isValidated) throw new IllegalStateException("Cannot get run function because module is not validated"); return runFunction; } private Scriptable getModule() throws ModuleValidationException { final Object ob = moduleScope.get("module", moduleScope); if(ob == Scriptable.NOT_FOUND) throw new ModuleValidationException("No 'module' object found."); return Context.toObject(ob, moduleScope); } private ModuleScriptType getScriptType(Scriptable module) throws ModuleValidationException { if(!hasStringInModuleObject(module, "type")) return ModuleScriptType.BASIC_MODULE; final String typeName = getStringFromModuleObject(module, "type"); final ModuleScriptType type = ModuleScriptType.lookup(typeName); if(type == null) throw new ModuleValidationException("Unrecognized module type: "+ typeName); else return type; } private boolean hasStringInModuleObject(Scriptable module, String name) { final Object ob = module.get(name, moduleScope); return (ob != Scriptable.NOT_FOUND && (ob instanceof String)); } private String getStringFromModuleObject(Scriptable module, String name) throws ModuleValidationException { final Object ob = module.get(name, moduleScope); if(ob == Scriptable.NOT_FOUND) throw new ModuleValidationException("Could not find module property '"+ name +"'."); if(!(ob instanceof String)) throw new ModuleValidationException("Module property '"+ name +"' is not a string type as expected."); return (String) ob; } private boolean getFlagFromModuleObject(Scriptable module, String name) { final Object ob = module.get(name, moduleScope); return !(ob == Scriptable.NOT_FOUND); } private Function getEntryFunction() throws ModuleValidationException { Function entry = getGlobalFunction("run"); if(entry == null) entry = getGlobalFunction("initialize"); if(entry == null) throw new ModuleValidationException("Could not find global entry function 'run()' or 'initialize()' in module."); return entry; } private Function getGlobalFunction(String name) throws ModuleValidationException { final Object ob = moduleScope.get(name, moduleScope); if(ob == Scriptable.NOT_FOUND) return null; if(!(ob instanceof Function)) throw new ModuleValidationException("Global identifier '"+ name +"' is not a function as expected"); return (Function) ob; } }