📄 namespaceservice.java
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2005 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/package com.ibm.staf.service.namespace;import com.ibm.staf.*;import com.ibm.staf.service.*;import java.util.Map;import java.util.HashMap;import java.util.List;import java.util.ArrayList;import java.util.TreeMap;import java.util.Iterator;import java.util.StringTokenizer;import java.io.File;import java.util.Date;/** * Represents the Namespace service which is a STAF service whose purpose * is to provide a namespace hierarchy for storing and retrieving a * persistent repository of variables. The Namespace service allows * namespaces to hold a set of key/value pairs (e.g. variables). * Namespaces may inherit variables from another namespace, thus creating * a namespace hierarchy. Variable look-ups will be done within a namespace * scope. If a variable cannot be found in the given namespace, resolution * will be attempted in the parent namespace, and so on up the hierarchy. * <p> * Unlike the VAR service, any variables set will persist across stops and * restarts of STAF with no additional steps required by the user. This is * done by immediately updating the Namespaces XML file when any updates * are made to namespaces. */ public class NamespaceService implements STAFServiceInterfaceLevel30{ // Namespace service version private final String kVersion = "1.0.0"; // Version of STAF (or later) required for this service private final String kRequiredSTAFVersion = "3.0.0"; // Namespace Service Error Codes /** * Error code for when an error occurs writing the Namespaces data to * persistent storage */ public static final int kDataStorageError = 4001; private String fServiceName; private STAFHandle fHandle; private String fLocalMachineName = ""; private String fLineSep; private String fFileSep; private String fDataDir; private String fTempDir; private File fDataFile; // Namespaces.xml file private File fBackupFile; // Namespaces.xml.backup file private NamespaceManager fNamespaceManager = new NamespaceManager(); private StorageManager fStorageManager = null; // STAFCommandParsers for each request private STAFCommandParser fCreateParser; private STAFCommandParser fModifyParser; private STAFCommandParser fDeleteParser; private STAFCommandParser fListParser; private STAFCommandParser fQueryParser; private STAFCommandParser fSetParser; private STAFCommandParser fGetParser; private STAFCommandParser fVersionParser; private STAFCommandParser fHelpParser; // Map Class Definitions used to create marshalled results private static STAFMapClassDefinition fListNamespacesMapClass; private static STAFMapClassDefinition fListVariablesMapClass; private static STAFMapClassDefinition fQueryfNamespaceMapClass; private static STAFMapClassDefinition fQueryTreeMapClass; /** * Creates a new NamespaceService instance */ public NamespaceService() {} /** * This is the STAF Service initialization method that is run when the * service is registered. It performs initialization functions such as: * <ul> * <li>Creates a STAF handle to use to submit requests to STAF services * <li>Resolves any local variables needed by the service * <li>Creates request parsers * <li>Creates map classes uses in list/query results * <li>Creates the data directory for the service (if it doesn't already * exist * <li>Creates the storage manager which loads the namespaces from the * Namespaces xml file, if the file exists. * </ul> * * @param info STAF service initialization information * @return An instance of STAFResult which contains the return code and * result buffer indicating if the service initialized successfully. */ public STAFResult init(STAFServiceInterfaceLevel30.InitInfo info) { try { fServiceName = info.name; fHandle = new STAFHandle("STAF/Service/" + info.name); STAFResult res = new STAFResult(); // Resolve the machine name variable for the local machine res = STAFUtil.resolveInitVar("{STAF/Config/Machine}", fHandle); if (res.rc != STAFResult.Ok) return res; fLocalMachineName = res.result; // Resolve the line separator variable for the local machine res = STAFUtil.resolveInitVar("{STAF/Config/Sep/Line}", fHandle); if (res.rc != STAFResult.Ok) return res; fLineSep = res.result; // Resolve the file separator variable for the local machine res = STAFUtil.resolveInitVar("{STAF/Config/Sep/File}", fHandle); if (res.rc != STAFResult.Ok) return res; fFileSep = res.result; // CREATE parser fCreateParser = new STAFCommandParser(); fCreateParser.addOption( "CREATE", 1, STAFCommandParser.VALUENOTALLOWED); fCreateParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); fCreateParser.addOption( "DESCRIPTION", 1, STAFCommandParser.VALUEREQUIRED); fCreateParser.addOption( "PARENT", 1, STAFCommandParser.VALUEREQUIRED); // if you specify CREATE, the NAMESPACE option is required fCreateParser.addOptionNeed("CREATE", "NAMESPACE"); // if you specify CREATE, the DESCRIPTION option is required fCreateParser.addOptionNeed("CREATE", "DESCRIPTION"); // MODIFY parser fModifyParser = new STAFCommandParser(); fModifyParser.addOption( "MODIFY", 1, STAFCommandParser.VALUENOTALLOWED); fModifyParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); fModifyParser.addOption( "DESCRIPTION", 1, STAFCommandParser.VALUEREQUIRED); fModifyParser.addOption( "PARENT", 1, STAFCommandParser.VALUEREQUIRED); // if you specify MODIFY, the NAMESPACE option is required fModifyParser.addOptionNeed("MODIFY", "NAMESPACE"); // DELETE parser fDeleteParser = new STAFCommandParser(); fDeleteParser.addOption( "DELETE", 1, STAFCommandParser.VALUENOTALLOWED); fDeleteParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); fDeleteParser.addOption( "VAR", 0, STAFCommandParser.VALUEREQUIRED); fDeleteParser.addOption( "CONFIRM", 1, STAFCommandParser.VALUENOTALLOWED); // If you specify DELETE, the NAMESPACE option is required fDeleteParser.addOptionNeed("DELETE", "NAMESPACE"); // If you specify the VAR option, the NAMESPACE option is required fDeleteParser.addOptionNeed("VAR", "NAMESPACE"); // If you specify the CONFIRM option, the NAMESPACE option is // required fDeleteParser.addOptionNeed("CONFIRM", "NAMESPACE"); // You must specify either VAR or CONFIRM, but not both fDeleteParser.addOptionGroup("VAR CONFIRM", 1, 1); // LIST [NAMESPACES] parser fListParser = new STAFCommandParser(); fListParser.addOption( "LIST", 1, STAFCommandParser.VALUENOTALLOWED); fListParser.addOption( "NAMESPACES", 1, STAFCommandParser.VALUENOTALLOWED); fListParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); fListParser.addOption( "ONLY", 1, STAFCommandParser.VALUENOTALLOWED); // You can specify either NAMESPACES or NAMESPACE, but not both fListParser.addOptionGroup("NAMESPACES NAMESPACE", 0, 1); fListParser.addOptionNeed("NAMESPACES", "LIST"); fListParser.addOptionNeed("NAMESPACE", "LIST"); fListParser.addOptionNeed("ONLY", "NAMESPACE"); // QUERY parser fQueryParser = new STAFCommandParser(); fQueryParser.addOption( "QUERY", 1, STAFCommandParser.VALUENOTALLOWED); fQueryParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); fQueryParser.addOption( "TREE", 1, STAFCommandParser.VALUENOTALLOWED); // If you specify QUERY, the NAMESPACE option is required fQueryParser.addOptionNeed("QUERY", "NAMESPACE"); // SET parser fSetParser = new STAFCommandParser(); fSetParser.addOption( "SET", 1, STAFCommandParser.VALUENOTALLOWED); fSetParser.addOption( "VAR", 0, STAFCommandParser.VALUEREQUIRED); fSetParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); // If you specify SET, at least one VAR option is required and // the NAMESPACE option is required fSetParser.addOptionNeed("SET", "VAR"); fSetParser.addOptionNeed("SET", "NAMESPACE"); // GET parser fGetParser = new STAFCommandParser(); fGetParser.addOption( "GET", 1, STAFCommandParser.VALUENOTALLOWED); fGetParser.addOption( "VAR", 1, STAFCommandParser.VALUEREQUIRED); fGetParser.addOption( "NAMESPACE", 1, STAFCommandParser.VALUEREQUIRED); // If you specify GET, the VAR and NAMESPACE options are required fGetParser.addOptionNeed("GET", "VAR"); fGetParser.addOptionNeed("GET", "NAMESPACE"); // VERSION parser fVersionParser = new STAFCommandParser(); fVersionParser.addOption( "VERSION", 1, STAFCommandParser.VALUENOTALLOWED); // HELP parser fHelpParser = new STAFCommandParser(); fHelpParser.addOption( "HELP", 1, STAFCommandParser.VALUENOTALLOWED); // Construct map class for the result from a LIST NAMESPACES request fListNamespacesMapClass = new STAFMapClassDefinition( "STAF/Service/Namespace/NamespaceInfo"); fListNamespacesMapClass.addKey("name", "Name"); fListNamespacesMapClass.addKey("description", "Description"); fListNamespacesMapClass.addKey("parent", "Parent"); // Construct map class for the result from a LIST VARIABLES request fListVariablesMapClass = new STAFMapClassDefinition( "STAF/Service/Namespace/VarInfo"); fListVariablesMapClass.addKey("key", "Key"); fListVariablesMapClass.addKey("value", "Value"); fListVariablesMapClass.addKey("namespace", "Namespace"); // Construct map class for the result from a QUERY request fQueryfNamespaceMapClass = new STAFMapClassDefinition( "STAF/Service/Namespace/Query"); fQueryfNamespaceMapClass.addKey("name", "Name"); fQueryfNamespaceMapClass.addKey("description", "Description"); fQueryfNamespaceMapClass.addKey("parent", "Parent"); fQueryfNamespaceMapClass.addKey("children", "Children"); // Construct map class for the result from a QUERY TREE request fQueryTreeMapClass = new STAFMapClassDefinition( "STAF/Service/Namespace/QueryTree"); fQueryTreeMapClass.addKey("name", "Name"); fQueryTreeMapClass.addKey("children", "Children"); // Register Help Data registerHelpData( kDataStorageError, "Data storage error", "An error occurred saving namespaces data to persistent " + "storage. Additional information about the error is put " + "into the STAF Result."); // Create service data directory if it doesn't already exist: // <STAFDataDir>/service/<service name (lower-case)> fDataDir = info.writeLocation + fFileSep + "service" + fFileSep + fServiceName.toLowerCase(); File dir = new File(fDataDir); if (!dir.exists()) { if (!dir.mkdirs()) { return new STAFResult( STAFResult.ServiceConfigurationError, "Error creating service data directory: " + fDataDir); } } // Create service directory in the STAF temporary data directory, // if it doesn't already exist: // <STAFDataDir>/tmp/service/<Service Name (lower-case)>; fTempDir = info.writeLocation + fFileSep + "tmp" + fFileSep + "service" + fFileSep + fServiceName.toLowerCase(); dir = new File(fTempDir); if (!dir.exists()) { if (!dir.mkdirs()) { return new STAFResult( STAFResult.ServiceConfigurationError, "Error creating service temporary data directory: " + fTempDir); } } // Create the storage manager (which loads the namespaces from // the xml file if it exists) try { fStorageManager = new StorageManager( fDataDir, fNamespaceManager); } catch (Exception e) { // Log to service log and print stack trace to JVM log String errorMsg = "Error loading namespaces from persistent" + " storage. " + fLineSep + e; logMessage("Error", errorMsg, false, null); e.printStackTrace(); return new STAFResult(STAFResult.STAFRegistrationError, e.toString()); } fDataFile = fStorageManager.getFile(); fBackupFile = new File( fDataDir + fFileSep + StorageManager.sXmlFileName + ".backup"); logMessage("Start", "Initialized the " + fServiceName + " service", false, null); // Save a copy of the Namespaces file in a temporary directory copyData("init"); } catch (STAFException e) { return new STAFResult(STAFResult.STAFRegistrationError, e.toString()); } catch (Throwable t) { /* Unexpected Exception. Log to JVM Log */ t.printStackTrace(); return new STAFResult(STAFResult.JavaError, t.getMessage()); } return new STAFResult(STAFResult.Ok); } /** * Gets the instance of the NamespaceManager used by the Namespace service * @return an instance of the NamespaceManager */ public NamespaceManager getNamespaceManager() { return fNamespaceManager; } /** * This is the STAF Service method that accepts requests that are * submitted to this service. Based on the first option specifed in * the request, it calls the appropriate method that handles that request. * @param info STAF Service request information * @return An instance of STAFResult which contains the return code * and result buffer. */ public STAFResult acceptRequest(STAFServiceInterfaceLevel30.RequestInfo info) { String lowerRequest = info.request.toLowerCase(); StringTokenizer requestTokenizer = new StringTokenizer(lowerRequest); String request = requestTokenizer.nextToken(); // Call the appropriate method to handle the command if (request.equals("create")) return handleCreate(info); else if (request.equals("modify")) return handleModify(info); else if (request.equals("delete")) return handleDelete(info); else if (request.equals("list"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -