Package synalp.generation.server

Source Code of synalp.generation.server.GeneratorServer

package synalp.generation.server;

import java.io.File;
import java.util.*;

import synalp.commons.grammar.*;
import synalp.commons.input.*;
import synalp.commons.input.javacc.InputReader;
import synalp.commons.output.SyntacticRealization;
import synalp.commons.semantics.Semantics;
import synalp.commons.unification.InstantiationContext;
import synalp.commons.utils.*;
import synalp.commons.utils.ResourceBundle;
import synalp.commons.utils.configuration.ResourcesBundleType;
import synalp.generation.*;
import synalp.generation.jeni.*;
import synalp.generation.jeni.selection.families.*;
import synalp.generation.ranker.NgramRanker;
import synalp.generation.selection.LexicalSelectionResult;

import com.google.gson.*;


/**
* A GeneratorServer is an http server that returns generation results from POST json generation
* requests.
* @author Alexandre Denis
*/
public class GeneratorServer extends SimpleServer
{
  private Generator generator;
  private ResourceBundle bundle;
  private static Gson gson = new Gson();


  /**
   * Run the server with a predefined bundle.
   * @param args
   */
  public static void main(String[] args)
  {
    ResourceBundle bundle = ResourcesBundleType.SEMXTAG2_BUNDLE.getBundle();
    JeniGenerator generator = new JeniGenerator(ResourcesBundleType.SEMXTAG2_BUNDLE.getBundle());
    FamilySemanticsBuilder.setGrammarSemanticsResourcesBundleType.SEMXTAG2_BUNDLE.getBundle().getGrammarFile(),
                          new File("resources/sem-xtag2/semantics.sem"), true);
    generator.setLexicalSelection(FamilyLexicalSelection.newInstancenew File("resources/sem-xtag2/lexicon.sem"),
                                      new File("resources/sem-xtag2/semantics.sem"),
                                      ResourcesBundleType.SEMXTAG2_BUNDLE.getBundle().getGrammar()));

    //Generator generator = new JeniGenerator(bundle);*/

    //ResourceBundle bundle = ResourcesBundleType.MINIMAL_BUNDLE.getBundle();
    //ResourceBundle bundle = ResourcesBundleType.KBGEN_BUNDLE.getBundle();
    //Generator generator = new JeniGenerator(bundle);
    GeneratorServer server = new GeneratorServer(generator, bundle, 2000);
    server.start();
  }


  private void createGenerator()
  {
    JeniGenerator generator = new JeniGenerator(ResourcesBundleType.SEMXTAG2_BUNDLE.getBundle());
    generator.setLexicalSelection(FamilyLexicalSelection.newInstancenew File("resources/sem-xtag2/lexicon.sem"),
                                      new File("resources/sem-xtag2/semantics.sem"),
                                      ResourcesBundleType.SEMXTAG2_BUNDLE.getBundle().getGrammar()));
    this.generator = generator;
    this.bundle = ResourcesBundleType.SEMXTAG2_BUNDLE.getBundle();

    //ResourceBundle bundle = ResourcesBundleType.MINIMAL_BUNDLE.getBundle();
    //ResourceBundle bundle = ResourcesBundleType.KBGEN_BUNDLE.getBundle();
    //generator = new JeniGenerator(bundle, new NgramRanker("resources/ranking/lm-genia-lemma", 2, "jni"));
   
  }


  /**
   * Creates a new GeneratorServer with given generator running on given port.
   * @param generator
   * @param bundle TODO
   * @param port
   */
  public GeneratorServer(Generator generator, ResourceBundle bundle, int port)
  {
    super(port);
    this.bundle = bundle;
    this.generator = generator;
  }


  /**
   * Processes the given String as json and returns the response.
   * @param message
   * @return a json string providing results or info
   */
  @Override
  protected String receivePost(String message)
  {
    if (message == null || message.isEmpty())
      return errorMessage("empty request", message);

    JsonObject object = null;
    try
    {
      object = gson.fromJson(message, JsonObject.class);
    }
    catch (JsonParseException e)
    {
      return errorMessage("parse exception: " + e.getMessage(), message);
    }

    if (!object.has("request"))
      return errorMessage("missing 'request'", message);

    String request = object.get("request").getAsString();
    GeneratorRequestType requestType = GeneratorRequestType.parse(request);
    switch (requestType)
    {
      case UNKNOWN:
        return errorMessage("unknown request '" + request + "'", message);
      case GENERATE_FOR_INPUT:
        return processGenerateForInput(object, message);
      case GENERATE_FOR_TESTS:
        return processGenerateForTests(object, message);
      case REQUEST_TESTS:
        return processRequestTests();
    }

    return errorMessage("unprocessed request", message);
  }


  /**
   * Creates a json error message.
   * @param message
   * @param input
   * @return a json error message
   */
  private String errorMessage(String message, String input)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("error", message);
    ret.addProperty("input", input);
    return gson.toJson(ret);

  }


  /**
   * Processes a request to have all tests identifiers.
   * @return a json string
   */
  private String processRequestTests()
  {
    JsonObject ret = new JsonObject();
    JsonArray tests = new JsonArray();
    for(TestSuiteEntry entry : bundle.getTestSuite())
      tests.add(new JsonPrimitive(formatTestId(entry.getId())));
    ret.add("tests", tests);
    return gson.toJson(ret);
  }


  /**
   * Process GENERATE_FOR_INPUT: { request:"GENERATE_FOR_INPUT", sem:"Semantics" }
   * @param object
   * @param input
   * @return the results
   */
  private String processGenerateForInput(JsonObject object, String input)
  {
    if (!object.has("sem"))
      return errorMessage("input has no \"sem\" key", input);

    Semantics semantics = null;
    try
    {
      semantics = InputReader.readSemantics(object.get("sem").getAsString());
    }
    catch (Exception e)
    {
      return errorMessage("\"sem\" key (" + object.get("sem").getAsString() + ") is not valid semantics", input);
    }

    return generator.generate(semantics).toString();
  }


  /**
   * Process GENERATE_FOR_TESTS: { request:"GENERATE_FOR_TESTS", tests: [ identifiers of tests ] }
   * @param object
   * @param input
   * @return json results
   */
  private String processGenerateForTests(JsonObject object, String input)
  {
    if (!object.has("tests"))
      return errorMessage("input has no \"tests\" key", input);

    JsonArray ret = new JsonArray();
    for(JsonElement element : object.get("tests").getAsJsonArray())
    {
      String testId = element.getAsString();
      TestSuiteEntry entry = getEntryById(testId);
      if (entry == null)
        continue;

      // re-create generator each time, note that it does not solve the Time management issue (it is static)
      createGenerator();
      TestResult result = entry.performTest(generator);
      ret.add(asJson(result));
    }
    return gson.toJson(ret);
  }
 
 
  private TestSuiteEntry getEntryById(String testId)
  {
    for(TestSuiteEntry entry : bundle.getTestSuite())
      if (formatTestId(entry.getId()).equals(testId))
        return entry;
    return null;
  }


  private String formatTestId(String id)
  {
    id = "test-"+id;
    id = id.replaceAll("\\.", "_");
    id = id.replaceAll("'", "_");
    id = id.replaceAll("\\+", "_");
    return id;
  }
 
 
  /**
   * Creates a JsonObject from given TestResult.
   * @param result
   * @return a json object
   */
  private JsonObject asJson(TestResult result)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("id", formatTestId(result.getTest().getId()));
    ret.addProperty("result", result.getType().toString());
    ret.addProperty("message", result.getMessage());
    ret.add("report", asJson(result.getReport(), result));
    return ret;
  }
 

  private JsonObject asJson(GenerationReport report, TestResult result)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("time", Perf.formatTime(report.getTotalTime()));
    ret.addProperty("start", report.getStartTime().toString());
    if (report.getErrorMessage() != null)
      ret.addProperty("error", report.getErrorMessage());
    ret.add("all-items", asJson(report.getAllItems()));
    ret.add("lexical-selection", asJson(report.getLexicalSelection(), result));
    ret.add("realizations", asJson(report.getSyntacticRealizations()));
    return ret;
  }
 
 
  /**
   * Specific to JeniGenerator, see if we can improve!
   * @param items
   * @return
   */
  private JsonArray asJson(JeniChartItems items)
  {
    JsonArray ret = new JsonArray();
    for(JeniChartItem item : items)
      ret.add(asJson(item));
    return ret;
  }


  private JsonObject asJson(JeniChartItem item)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("id", item.getId());
    ret.addProperty("lemmas", Lemma.printLemmas(item.getLemmas(), item.getContext(), false));
    if (item.getParentItemSource()!=null)
      ret.addProperty("source", item.getParentItemSource().getId());
    if (item.getParentItemTarget()!=null)
      ret.addProperty("target", item.getParentItemTarget().getId());
    ret.addProperty("operation", item.getParentOperationType().toString());
    return ret;
  }


  private JsonElement asJson(LexicalSelectionResult lexicalSelection, TestResult result)
  {
    JsonArray ret = new JsonArray();
    for(Semantics key : lexicalSelection.getInputs())
      for(GrammarEntries entries : lexicalSelection.getResults(key))
        ret.add(asJson(key, entries, result));
    return ret;
  }

 
  /**
   * Returns a json object for selection.
   * @param key
   * @param entries
   * @param result TODO
   * @return a json object
   */
  private JsonObject asJson(Semantics key, GrammarEntries entries, TestResult result)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("input", key.toString());
    ret.add("entries", asJson(entries, result));
    return ret;
  }


  /**
   * Creates an array of entry objects. Creates "missing" entries when considering the test id as
   * the lemmas separated by "-". We could do it also for morph.
   * @param entries
   * @param result
   * @return an array of entries including missing entries
   */
  private JsonArray asJson(GrammarEntries entries, TestResult result)
  {
    JsonArray ret = new JsonArray();

    // first append missing entries
    List<String> lemmas = Arrays.asList(result.getTest().getId().split("-"));
    for(String lemma : lemmas)
    {
      boolean found = false;
      for(GrammarEntry entry : entries)
        if (lemma.equals(entry.getLemmasSurface()))
        {
          found = true;
          break;
        }
      if (!found)
        ret.add(asJsonMissingEntry(lemma));
    }

    // then display selected entries
    List<GrammarEntry> sorted = result == null ? new ArrayList<GrammarEntry>(entries) : entries.getEntriesSortedByIndex(lemmas);
    for(GrammarEntry entry : sorted)
      ret.add(asJson(entry));

    return ret;
  }


  private JsonObject asJsonMissingEntry(String lemma)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("name", "Missing");
    ret.addProperty("message", "the lemma '" + lemma + "' from the test id is found in no entry");
    ret.addProperty("lemmas", lemma);
    return ret;
  }


  private JsonObject asJson(GrammarEntry entry)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("name", entry.getName());
    ret.addProperty("lemmas", entry.getLemmasSurface());
    ret.addProperty("sem", entry.getSemantics().toString(entry.getContext()));
    ret.addProperty("tree", formatTreeString(entry.getTree().toString(entry.getContext())));
    return ret;
  }


  private String formatTreeString(String val)
  {
    val = val.replaceAll("\u2717", "_Nadj_");
    val = val.replaceAll("\u2666", "_Anchor_");
    val = val.replaceAll("\u2662", "_Coanchor_");
    val = val.replaceAll("\u2193", "_Subst_");
    val = val.replaceAll("\u272D", "_Foot_");
    return val;
  }


  private JsonArray asJson(List<? extends SyntacticRealization> reals)
  {
    JsonArray ret = new JsonArray();
    for(SyntacticRealization real : reals)
      ret.add(asJson(real));
    return ret;
  }


  private JsonObject asJson(SyntacticRealization realization)
  {
    JsonObject ret = new JsonObject();
    ret.add("lemmas", createJsonLemmas(realization.getLemmas(), realization.getContext()));
    return ret;
  }


  private JsonArray createJsonLemmas(List<Lemma> lemmas, InstantiationContext context)
  {
    JsonArray ret = new JsonArray();
    for(Lemma lemma : lemmas)
      ret.add(createJsonLemma(lemma, context));
    return ret;
  }


  private JsonObject createJsonLemma(Lemma lemma, InstantiationContext context)
  {
    JsonObject ret = new JsonObject();
    ret.addProperty("lemma", lemma.getValue());
    ret.addProperty("lemma-features", lemma.getFs().toString(context));
    return ret;
  }
}
TOP

Related Classes of synalp.generation.server.GeneratorServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.