http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/Main.cpp
----------------------------------------------------------------------
diff --git a/contrib/pdxautoserializer/src/impl/Main.cpp 
b/contrib/pdxautoserializer/src/impl/Main.cpp
new file mode 100644
index 0000000..42e651f
--- /dev/null
+++ b/contrib/pdxautoserializer/src/impl/Main.cpp
@@ -0,0 +1,462 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../base_types.hpp"
+#include "../InputParserFactory.hpp"
+#include "../CodeGeneratorFactory.hpp"
+#include "../CodeGenerator.hpp"
+#include "Log.hpp"
+#include "Helper.hpp"
+#include <iostream>
+
+/**
+* @namespace apache::geode::client::pdx_auto_serializer The namespace 
containing
+* the
+*                                     auto-serializer classes.
+*/
+using namespace apache::geode::client::pdx_auto_serializer;
+
+/** The name used for invocation of the program on command-line. */
+std::string progName;
+/** The parser factory object. */
+InputParserFactory parserFactory;
+/** The code generator factory object. */
+CodeGeneratorFactory generatorFactory;
+/** The parser returned by the parser factory. */
+InputParser* parser = NULL;
+/** The list of classes given by the parser. */
+ASClassVector classes;
+/** The <code>CodeGenerator</code> object returned by the factory. */
+CodeGenerator* codeGenerator = NULL;
+/**
+* The options with their usage for the tool with current parser and
+* code generator.
+*/
+OptionMap toolOptions;
+
+/** Name of this module. */
+static std::string ModuleName = "PdxAutoSerializer";
+
+/**
+* The option used to specify the language of the code to be auto-serialized.
+*/
+static const std::string LanguageOption = "language";
+
+/**
+* The option used to specify the language in which the auto-serialized code
+* is to be generated.
+*/
+static const std::string GeneratorOption = "generator";
+
+/** The option name for class name. */
+static const std::string ClassNameOption = "className";
+
+/** The option name for class name String */
+static const std::string getClassNameOption = "classNameStr";
+
+/** The option used to obtain usage information. */
+static const std::string UsageOption = "usage";
+
+/** The option for help -- gives same output as usage for now. */
+static const std::string HelpOption = "help";
+
+/** the option for directory to generate auto-generated files */
+static const std::string outDirectoryOption = "outDir";
+
+/** Fill in the default top-level options required for the tool. */
+void addMainOptions();
+
+/**
+* Parse the command-line and get the resource names and the properties.
+*
+* @param argc The number of command-line arguments.
+* @param argv The string array containing the command-line arguments.
+* @param resources The names of the resources.
+* @param properties Output parameter containing the properties as a map.
+*/
+void parseCommandLine(int argc, char** argv, StringVector& resources,
+                      PropertyMap& properties);
+
+/**
+* Show the program usage. If any language/generator has been selected then
+* its options are also shown.
+*/
+void showUsage();
+
+/** Cleanly destroy all the global objects. */
+void cleanupObjects();
+
+/** Cleanup any files or other artifacts in case of abnormal exit. */
+void cleanup();
+
+/**
+* The main entry point of the tool.
+*
+* @param argc The number of command-line arguments.
+* @param argv The string array containing the command-line arguments.
+*/
+
+static void Tokenize(const std::string& str, std::vector<std::string>& tokens,
+                     const std::string& delimiters = " ") {
+  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+  std::string::size_type pos = str.find_first_of(delimiters, lastPos);
+  while (std::string::npos != pos || std::string::npos != lastPos) {
+    tokens.push_back(str.substr(lastPos, pos - lastPos));
+    lastPos = str.find_first_not_of(delimiters, pos);
+    pos = str.find_first_of(delimiters, lastPos);
+  }
+}
+int main(int argc, char** argv) {
+  bool success = false;
+  struct CleanUp {
+   private:
+    bool& m_success;
+
+   public:
+    explicit CleanUp(bool& success) : m_success(success) {}
+    ~CleanUp() {
+      if (m_success) {
+        cleanupObjects();
+      } else {
+        cleanup();
+      }
+    }
+  } cleanOnExit(success);
+
+  try {
+    StringVector resources;
+    PropertyMap properties;
+    const std::string languageString = "C++";
+    const std::string generatorString = "C++";
+    StringVector classNames;
+
+    progName = argv[0];
+    std::string::size_type baseIndex = progName.find_last_of("/\\");
+    if (baseIndex != std::string::npos) {
+      progName = progName.substr(baseIndex + 1);
+    }
+    addMainOptions();
+    parseCommandLine(argc, argv, resources, properties);
+    std::map<std::string, std::string> classNameStringMap;
+
+    try {
+      if (languageString.length() > 0 &&
+          (parser = parserFactory.getInstance(languageString)) == NULL) {
+        throw std::invalid_argument("No such language: " + languageString);
+      }
+
+      if (generatorString.length() > 0 &&
+          (codeGenerator = generatorFactory.getInstance(generatorString)) ==
+              NULL) {
+        throw std::invalid_argument("No such code generator: " +
+                                    generatorString);
+      }
+
+      if (parser != NULL) {
+        parser->getOptions(toolOptions);
+      }
+      if (codeGenerator != NULL) {
+        codeGenerator->getOptions(toolOptions);
+      }
+
+      std::string usageString;
+      if (Helper::getSingleProperty(properties, UsageOption, usageString) ||
+          Helper::getSingleProperty(properties, HelpOption, usageString)) {
+        showUsage();
+        return 0;
+      }
+
+      if (parser == NULL) {
+        throw std::invalid_argument("No input language specified.");
+      }
+      if (codeGenerator == NULL) {
+        throw std::invalid_argument("No output language specified.");
+      }
+      if (resources.size() == 0) {
+        throw std::invalid_argument("No input resources specified.");
+      }
+
+      if (!Helper::getMultiProperty(properties, ClassNameOption, classNames) ||
+          classNames.size() == 0) {
+        Log::warn(ModuleName,
+                  "No class name specified; "
+                  "will serialize all classes.");
+      }
+
+      std::string classNameString;
+
+      std::vector<std::string> classNameStringVector;
+
+      Helper::getMultiProperty(properties, getClassNameOption,
+                               classNameStringVector);
+      for (std::vector<std::string>::iterator itr =
+               classNameStringVector.begin();
+           itr != classNameStringVector.end(); ++itr) {
+        std::vector<std::string> eachClassNameVector;
+        Tokenize(*itr, eachClassNameVector, ":");
+        if (eachClassNameVector.size() == 2) {
+          classNameStringMap.insert(std::pair<std::string, std::string>(
+              eachClassNameVector[0], eachClassNameVector[1]));
+        } else {
+          throw std::invalid_argument("No input class name string specified.");
+        }
+      }
+
+      parser->init(properties);
+      parser->selectClasses(resources, classNames);
+      parser->getSelectedClasses(classes);
+
+      codeGenerator->init(properties);
+
+    } catch (const std::exception& ex) {
+      std::cerr << Helper::typeName(ex) << ": " << ex.what() << std::endl;
+      std::cerr << "Use --help or --usage option for help" << std::endl;
+      return 1;
+    }
+
+    if (properties.size() > 0) {
+      showUsage();
+      return 1;
+    }
+
+    Log::info(ModuleName, "Classes being serialized:");
+    for (ASClassVector::const_iterator classIterator = classes.begin();
+         classIterator != classes.end(); ++classIterator) {
+      Log::info(ModuleName, '\t' + (*classIterator)->getName());
+    }
+
+    for (ASClassVector::const_iterator classIterator = classes.begin();
+         classIterator != classes.end(); ++classIterator) {
+      ReferenceVector references;
+      TypeInfo classInfo;
+      VariableVector members;
+      std::string varName = "__var";
+
+      const ClassInfo* currentClass = *classIterator;
+
+      try {
+        currentClass->getTypeInfo(classInfo);
+        codeGenerator->initClass(classInfo);
+      } catch (const std::exception& ex) {
+        std::cerr << Helper::typeName(ex) << ": " << ex.what() << std::endl;
+        std::cerr << "Use --help or --usage option for help" << std::endl;
+        return 1;
+      }
+
+      currentClass->getReferences(references);
+      currentClass->getMembers(members);
+
+      codeGenerator->addFileHeader(argc, argv);
+      codeGenerator->addReferences(references);
+      codeGenerator->startClass(members);
+
+      std::vector<CodeGenerator::Method::Type> methods;
+      methods.push_back(CodeGenerator::Method::TODATA);
+      methods.push_back(CodeGenerator::Method::FROMDATA);
+      for (size_t index = 0; index < methods.size(); ++index) {
+        CodeGenerator::Method::Type method = methods[index];
+        codeGenerator->startMethod(method, varName,
+                                   currentClass->getMethodPrefix());
+        // Adding try block
+        // Ticket #905 Changes starts here
+        codeGenerator->addTryBlockStart(method);
+        // Ticket #905 Changes ends here
+        for (VariableVectorIterator memberIterator = members.begin();
+             memberIterator != members.end(); ++memberIterator) {
+          codeGenerator->genMethod(method, varName, *memberIterator);
+        }
+        // Finish try block
+        // Ticket #905 Changes starts here
+        codeGenerator->finishTryBlock(method);
+        // Ticket #905 Changes ends here
+        codeGenerator->endMethod(method, varName);
+      }
+      codeGenerator->genClassNameMethod(classNameStringMap,
+                                        currentClass->getMethodPrefix());
+      codeGenerator->genCreateDeserializable(currentClass->getMethodPrefix());
+      codeGenerator->genTypeId(currentClass->getMethodPrefix());
+      codeGenerator->endClass();
+    }
+  } catch (const std::invalid_argument& ex) {
+    std::cerr << "Use --help or --usage option for help" << std::endl;
+    return 1;
+  } catch (const std::exception& ex) {
+    std::cerr << Helper::typeName(ex) << ": " << ex.what() << std::endl;
+    return 1;
+  } catch (...) {
+    std::cerr << "Caught an unknown exception." << std::endl;
+    return 1;
+  }
+  success = true;
+  return 0;
+}
+
+void addMainOptions() {
+  std::pair<bool, std::string> optionPair;
+  // std::string languageStr;
+  // StringVector languages = parserFactory.getParsers();
+  // assert(languages.size() > 0);
+  // StringVectorIterator languageIterator = languages.begin();
+  // languageStr = *languageIterator;
+  // while (++languageIterator != languages.end()) {
+  //    languageStr += ',' + *languageIterator;
+  //}
+  // optionPair.first = true;
+  ///*optionPair.second = "Generate code for the given language "
+  //    "-- one of " + languageStr + " (SINGLE)";
+  // toolOptions[LanguageOption] = optionPair;*/
+
+  // std::string generatorStr;
+  // StringVector generators = generatorFactory.getGenerators();
+  // assert(generators.size() > 0);
+  // StringVectorIterator generatorIterator = generators.begin();
+  // generatorStr = *generatorIterator;
+  // while (++generatorIterator != generators.end()) {
+  //    generatorStr += ',' + *generatorIterator;
+  //}
+  /*optionPair.second = "Generate code in the given generator "
+  "-- one of " + generatorStr + " (SINGLE)";
+  toolOptions[GeneratorOption] = optionPair;*/
+
+  optionPair.first = true;
+  optionPair.second =
+      "Name of the class for which to generate "
+      "auto-serialization code (MULTIPLE,OPTIONAL)";
+  toolOptions[ClassNameOption] = optionPair;
+
+  optionPair.first = false;
+  optionPair.second = (std::string) "\t\tThis usage message.";
+  toolOptions[UsageOption] = optionPair;
+
+  optionPair.first = false;
+  optionPair.second = (std::string) "\t\tThis help message.";
+  toolOptions[HelpOption] = optionPair;
+
+  optionPair.first = true;
+  optionPair.second = (std::string) "Name of the class in string 
representation"
+    "(MULTIPLE,OPTIONAL)";
+  toolOptions[getClassNameOption] = optionPair;
+
+  optionPair.first = false;
+  optionPair.second = (std::string) "\tName of the directory where 
auto-generated"
+    "files will be written, default is current working directory";
+  toolOptions[outDirectoryOption] = optionPair;
+}
+
+void parseCommandLine(int argc, char** argv, StringVector& resources,
+                      PropertyMap& properties) {
+  if (argc < 2) {
+    throw std::invalid_argument("");
+  }
+  for (int propertyIndex = 1; propertyIndex < argc; propertyIndex++) {
+    char* arg = argv[propertyIndex];
+    if (arg[0] == '-' && arg[1] == '-') {
+      // Is a property value option.
+      std::string prop = arg + 2;
+      std::string propertyName;
+      std::string propertyValue;
+      std::string::size_type valPos;
+      if ((valPos = prop.find('=')) != std::string::npos) {
+        propertyName = prop.substr(0, valPos);
+        propertyValue = prop.substr(valPos + 1);
+      } else {
+        propertyName = prop;
+      }
+      PropertyMap::iterator propertyFind = properties.find(propertyName);
+      if (propertyFind == properties.end()) {
+        StringVector propertyValues;
+        if (propertyValue.length() > 0) {
+          propertyValues.push_back(propertyValue);
+        }
+        properties[propertyName] = propertyValues;
+      } else if (propertyValue.length() > 0) {
+        propertyFind->second.push_back(propertyValue);
+      }
+    } else {
+      resources.push_back(arg);
+    }
+  }
+}
+
+void showUsage() {
+  std::cout << "Usage: " << progName << " [OPTIONS] <resources e.g. "
+                                        "header> ...\n\n";
+
+  std::cout << "Resource name should be the path to the header "
+               "containing the classes to be auto-serialized.\n\n";
+  std::cout
+      << "Options may be one of those given below.\nSINGLE denotes "
+         "that the option should be specified only once.\nMULTIPLE denotes "
+         "that the "
+         "option can be specified more than once.\nOPTIONAL denotes that the "
+         "option may be skipped in which case the default for that shall be "
+         "chosen.";
+  std::cout << '\n' << std::endl;
+  for (OptionMap::const_iterator optionIterator = toolOptions.begin();
+       optionIterator != toolOptions.end(); ++optionIterator) {
+    std::cout << "--" << optionIterator->first;
+    if (optionIterator->second.first) {
+      std::cout << "=VALUE";
+    }
+    std::cout << '\t' << optionIterator->second.second << '\n';
+  }
+  std::cout << std::endl;
+
+  std::cout << "Examples:" << std::endl;
+  std::cout << "\t pdxautoserializer -outDir=<DIR NAME> <RESOURCE>"
+            << std::endl;
+  std::cout
+      << "\t pdxautoserializer -outDir=<DIR NAME> --className=<CLASSNAME1> ";
+  std::cout << "--className=<CLASSNAME2> <RESOURCE>" << std::endl;
+  std::cout << "\t pdxautoserializer -outDir=<DIR NAME> "
+               "--classNameStr=<CLASSNAME1:User defined String> ";
+  std::cout << "--classNameStr=<CLASSNAME:User defined String> <RESOURCE>"
+            << std::endl
+            << std::endl;
+  std::cout << "Helper Macros to be defined in Input Header File : "
+            << std::endl;
+  std::cout << "GFINCLUDE\t for including a specific member for serialization"
+            << std::endl;
+  std::cout << "GFEXCLUDE\t for excluding a specific member for serialization"
+            << std::endl;
+  std::cout << "GFID\t\t for considering a member as Identify Field"
+            << std::endl;
+  std::cout << "GFARRAYSIZE\t for specifying a array length member"
+            << std::endl;
+  std::cout << "GFIGNORE\t for ignoring certain keywords" << std::endl;
+  std::cout << "For more details refer to documentation on this utility."
+            << std::endl;
+}
+
+void cleanupObjects() {
+  Helper::deleteASClasses(classes);
+  if (parser != NULL) {
+    delete parser;
+    parser = NULL;
+  }
+  if (codeGenerator != NULL) {
+    delete codeGenerator;
+    codeGenerator = NULL;
+  }
+}
+
+void cleanup() {
+  if (codeGenerator != NULL) {
+    codeGenerator->cleanup();
+  }
+  cleanupObjects();
+}

Reply via email to