예제 #1
0
 /*
  * Add transition properties to entity info
  */
 public static void addNavPropertiesToEntityInfo(
     EntityInfo entityInfo, InteractionModel interactionModel) {
   IMResourceStateMachine rsm = interactionModel.findResourceStateMachine(entityInfo.getClazz());
   if (rsm != null) {
     for (IMTransition transition : rsm.getEntityStateTransitions()) {
       List<FieldInfo> properties = entityInfo.getAllFieldInfos();
       List<String> annotations = new ArrayList<String>();
       if (transition instanceof IMCollectionStateTransition) {
         // Transition to collection state
         // TODO fix reciprocal links
         // annotations.add("@OneToMany(cascade = CascadeType.ALL, mappedBy = \"" +
         // transition.getTargetStateName() + "\")");
         // properties.add(new FieldInfo(transition.getTargetStateName(), "Collection<" +
         // transition.getTargetEntityName() + ">", annotations));
       } else if (transition instanceof IMEntityStateTransition) {
         // Transition to entity state
         IMEntityStateTransition t = (IMEntityStateTransition) transition;
         annotations.add(
             "@JoinColumn(name = \""
                 + t.getLinkProperty()
                 + "\", referencedColumnName = \""
                 + t.getTargetResourceStateMachine().getMappedEntityProperty()
                 + "\", insertable = false, updatable = false)");
         annotations.add("@ManyToOne(optional = false)");
         properties.add(
             new FieldInfo(
                 t.getTargetState().getName(),
                 t.getTargetResourceStateMachine().getEntityName(),
                 annotations));
       }
     }
   }
 }
예제 #2
0
  /**
   * Generate project artefacts from conceptual interaction and metadata models.
   *
   * @param metadata metadata model
   * @param interactionModel Conceptual interaction model
   * @param commands Commands
   * @param srcOutputPath Path to output directory
   * @param configOutputPath Path to configuration files directory
   * @param generateMockResponder Indicates whether to generate artifacts for a mock responder
   * @return true if successful, false otherwise
   */
  public boolean generateArtifacts(
      Metadata metadata,
      InteractionModel interactionModel,
      Commands commands,
      File srcOutputPath,
      File configOutputPath,
      boolean generateMockResponder) {
    // Create the entity model
    String modelName = metadata.getModelName();
    EntityModel entityModel = createEntityModelFromMetadata(modelName, metadata);

    // Add error entities
    for (IMState state : interactionModel.getErrorHandlerStates()) {
      EMEntity emEntity = new EMEntity(state.getName());
      EMProperty empErrorMvGroup = new EMProperty("ErrorsMvGroup");
      empErrorMvGroup.addVocabularyTerm(new EMTerm(TermIdField.TERM_NAME, "true"));
      empErrorMvGroup.addVocabularyTerm(new EMTerm(TermListType.TERM_NAME, "true"));
      empErrorMvGroup.addVocabularyTerm(new EMTerm(TermComplexType.TERM_NAME, "true"));
      emEntity.addProperty(empErrorMvGroup);
      EMProperty empCode = new EMProperty("Code");
      empCode.addVocabularyTerm(new EMTerm(TermComplexGroup.TERM_NAME, "ErrorsMvGroup"));
      emEntity.addProperty(empCode);
      EMProperty empInfo = new EMProperty("Info");
      empInfo.addVocabularyTerm(new EMTerm(TermComplexGroup.TERM_NAME, "ErrorsMvGroup"));
      emEntity.addProperty(empInfo);
      EMProperty empText = new EMProperty("Text");
      empText.addVocabularyTerm(new EMTerm(TermComplexGroup.TERM_NAME, "ErrorsMvGroup"));
      emEntity.addProperty(empText);
      EMProperty empType = new EMProperty("Type");
      empType.addVocabularyTerm(new EMTerm(TermComplexGroup.TERM_NAME, "ErrorsMvGroup"));
      emEntity.addProperty(empType);
      entityModel.addEntity(emEntity);
    }

    // Obtain resource information
    String namespace = modelName + Metadata.MODEL_SUFFIX;
    List<EntityInfo> entitiesInfo = new ArrayList<EntityInfo>();
    for (EntityMetadata entityMetadata : metadata.getEntitiesMetadata().values()) {
      EntityInfo entityInfo = createEntityInfoFromEntityMetadata(namespace, entityMetadata);
      addNavPropertiesToEntityInfo(entityInfo, interactionModel);
      entitiesInfo.add(entityInfo);
    }

    return generateArtifacts(
        entityModel,
        interactionModel,
        commands,
        entitiesInfo,
        srcOutputPath,
        configOutputPath,
        generateMockResponder);
  }
예제 #3
0
  private boolean writeArtefacts(
      String modelName,
      List<EntityInfo> entitiesInfo,
      Commands commands,
      EntityModel entityModel,
      InteractionModel interactionModel,
      File srcOutputPath,
      File configOutputPath,
      boolean generateMockResponder) {
    boolean ok = true;
    String namespace = modelName + Metadata.MODEL_SUFFIX;
    interactionModel.setDomain(namespace);

    // Create the source directory
    new File(srcOutputPath + "/" + namespace.replace(".", "/")).mkdirs();

    // generate metadata.xml
    if (!writeMetadata(configOutputPath, generateMetadata(entityModel))) {
      ok = false;
    }

    // generate spring configuration files
    if (!writeSpringConfiguration(
        configOutputPath,
        SPRING_CONFIG_FILE,
        generateSpringConfiguration(namespace, modelName, commands))) {
      ok = false;
    }

    // generate the rim DSL
    RimDslGenerator rimDslGenerator = new RimDslGenerator(ve);
    Map<String, String> rims =
        rimDslGenerator.generateRimDslMap(interactionModel, commands, strictOData);
    for (String key : rims.keySet()) {
      String rimDslFilename = key + ".rim";
      if (!writeRimDsl(configOutputPath, rimDslFilename, rims.get(key))) {
        System.out.print("Failed to write " + key);
        ok = false;
        break;
      }
    }

    if (generateMockResponder) {
      // Write JPA classes
      for (EntityInfo entityInfo : entitiesInfo) {
        if (!generateJPAEntity(entityInfo, srcOutputPath)) {
          ok = false;
        }
      }

      // generate persistence.xml
      if (!writeJPAConfiguration(configOutputPath, generateJPAConfiguration(entitiesInfo))) {
        ok = false;
      }

      // generate spring configuration for JPA database
      if (!writeSpringConfiguration(
          configOutputPath,
          SPRING_RESOURCEMANAGER_FILE,
          generateSpringResourceManagerContext(modelName))) {
        ok = false;
      }

      // generate responder insert
      if (!writeResponderDML(configOutputPath, generateResponderDML(entitiesInfo))) {
        ok = false;
      }

      // generate responder settings
      if (!writeResponderSettings(configOutputPath, generateResponderSettings(modelName))) {
        ok = false;
      }
    }

    return ok;
  }
예제 #4
0
  @Test
  public void testGetRIM() {
    // Parse the test metadata
    MetadataParser parser = new MetadataParser();
    InputStream is =
        parser.getClass().getClassLoader().getResourceAsStream(METADATA_AIRLINE_XML_FILE);
    Metadata metadata = parser.parse(is);
    Assert.assertNotNull(metadata);

    // Define the interaction model
    InteractionModel interactionModel = new InteractionModel(metadata);

    IMResourceStateMachine rsmFlightSchedule =
        interactionModel.findResourceStateMachine("FlightSchedule");
    IMResourceStateMachine rsmAirport = interactionModel.findResourceStateMachine("Airport");
    IMResourceStateMachine rsmFlight = interactionModel.findResourceStateMachine("Flight");
    IMResourceStateMachine rsmPassenger = interactionModel.findResourceStateMachine("Passenger");
    rsmFlight.addTransitionToEntityState(
        "flight", rsmFlightSchedule, "flightschedule", "flightScheduleNum", null);
    rsmFlightSchedule.addTransitionToEntityState(
        "flightschedule", rsmAirport, "departureAirport", "departureAirportCode", null);
    rsmFlightSchedule.addTransitionToEntityState(
        "flightschedule", rsmAirport, "arrivalAirport", "arrivalAirportCode", null);
    rsmAirport.addTransitionToCollectionState(
        "airport",
        rsmFlightSchedule,
        "departures",
        "departureAirportCode eq '{code}'",
        "departureAirportCode",
        null);
    rsmAirport.addTransitionToCollectionState(
        "airport",
        rsmFlightSchedule,
        "arrivals",
        "arrivalAirportCode eq '{code}'",
        "arrivalAirportCode",
        null);
    rsmPassenger.addTransitionToEntityState("passenger", rsmFlight, "flight", "flightID", null);

    // Run the generator
    JPAResponderGen generator = new JPAResponderGen(true);
    Commands commands = JPAResponderGen.getDefaultCommands();
    String rimDSL = null;
    try {
      InputStream isRimDsl = generator.getRIM(interactionModel, commands);
      assertNotNull(isRimDsl);

      rimDSL = CharStreams.toString(new InputStreamReader(isRimDsl, "UTF-8"));
    } catch (Exception age) {
      fail(age.getMessage());
    }

    // Check the rim dsl
    assertTrue(rimDSL.contains("initial resource ServiceDocument"));
    assertTrue(rimDSL.contains("GET -> FlightSchedules"));
    assertTrue(rimDSL.contains("resource FlightSchedules"));
    assertTrue(
        rimDSL.contains(
            "GET *-> flightschedule {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        rimDSL.contains(
            "GET *-> flightschedule_departureAirport {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(rimDSL.contains("resource flightschedule_departureAirport"));
    assertTrue(rimDSL.contains("path: \"/FlightSchedules({id})/departureAirport\""));
    assertTrue(rimDSL.contains("GET -> Passengers"));
    assertTrue(rimDSL.contains("resource Passengers"));
  }
예제 #5
0
  /*
   * To support resource state transitions (as opposed to application state transitions)
   * we use a pseudo state in our resource interaction model.  A pseudo state does not necessarily
   * have an addressable uri, and always has actions.
   */
  @Test
  public void testIMWithResourcePseudoStates() {
    // Parse the test metadata
    MetadataParser parser = new MetadataParser();
    InputStream is =
        parser.getClass().getClassLoader().getResourceAsStream(METADATA_AIRLINE_XML_FILE);
    Metadata metadata = parser.parse(is);
    Assert.assertNotNull(metadata);

    // Define the interaction model
    InteractionModel interactionModel = new InteractionModel(metadata);

    // Add CRUD pseudo states to an entity/entityset
    IMResourceStateMachine rsmAirport = interactionModel.findResourceStateMachine("Airport");
    rsmAirport.addPseudoStateTransition(
        "Airports", "created", "Airports", "POST", null, "CreateEntity", null, true);
    rsmAirport.addPseudoStateTransition(
        "airport", "updated", "airport", "PUT", null, "UpdateEntity", "edit", false);
    rsmAirport.addPseudoStateTransition(
        "airport", "deleted", "DELETE", null, "DeleteEntity", "edit", false);

    // Run the generator
    MockGenerator generator = new MockGenerator();
    boolean status =
        generator.generateArtifacts(
            metadata,
            interactionModel,
            new File("target/FlightResponder/classes"),
            new File("target/FlightResponder/classes"),
            true);

    // Check results
    assertTrue(status);

    // Test rim dsl
    assertTrue(generator.generatedRimDsl.contains("POST -> Airports_created"));
    assertTrue(generator.generatedRimDsl.contains("PUT *-> airport_updated"));
    assertTrue(generator.generatedRimDsl.contains("PUT -> airport_updated"));
    assertTrue(generator.generatedRimDsl.contains("DELETE *-> airport_deleted"));
    assertTrue(generator.generatedRimDsl.contains("DELETE -> airport_deleted"));
    assertTrue(generator.generatedRimDsl.contains("resource Airports_created"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "resource Airports_created {"
                + RIM_LINE_SEP
                + "\ttype: item"
                + RIM_LINE_SEP
                + "\tentity: Airport"
                + RIM_LINE_SEP
                + "\tactions [ CreateEntity ]"
                + RIM_LINE_SEP
                + "\tpath: \"/Airports()\""));

    assertTrue(
        generator.generatedRimDsl.contains(
            "resource airport_updated {"
                + RIM_LINE_SEP
                + "\ttype: item"
                + RIM_LINE_SEP
                + "\tentity: Airport"
                + RIM_LINE_SEP
                + "\tactions [ UpdateEntity ]"
                + RIM_LINE_SEP
                + "\trelations [ \"edit\" ]"
                + RIM_LINE_SEP
                + "\tpath: \"/Airports('{id}')\""));
    assertTrue(
        generator.generatedRimDsl.contains(
            "resource airport_deleted {"
                + RIM_LINE_SEP
                + "\ttype: item"
                + RIM_LINE_SEP
                + "\tentity: Airport"
                + RIM_LINE_SEP
                + "\tactions [ DeleteEntity ]"
                + RIM_LINE_SEP
                + "\trelations [ \"edit\" ]"
                + RIM_LINE_SEP
                + "\tpath: \"/Airports('{id}')/deleted\""));
    assertTrue(
        generator.generatedRimDsl.contains(
            "resource airport {"
                + RIM_LINE_SEP
                + "\ttype: item"
                + RIM_LINE_SEP
                + "\tentity: Airport"
                + RIM_LINE_SEP
                + "\tview: GETEntity"
                + RIM_LINE_SEP
                + "\tpath: \"/Airports('{id}')\""
                + RIM_LINE_SEP
                + "\tPUT -> airport_updated {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{code}\" ]"
                + RIM_LINE_SEP
                + "\t}"
                + RIM_LINE_SEP
                + "\tDELETE -> airport_deleted {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{code}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
  }
예제 #6
0
  @Test
  public void testRIMWithoutReciprocalLinks() {
    // Parse the test metadata
    MetadataParser parser = new MetadataParser();
    InputStream is =
        parser.getClass().getClassLoader().getResourceAsStream(METADATA_AIRLINE_XML_FILE);
    Metadata metadata = parser.parse(is);
    Assert.assertNotNull(metadata);

    // Define the interaction model
    InteractionModel interactionModel = new InteractionModel(metadata);

    // Do not specify a reciprocal link
    IMResourceStateMachine rsmFlightSchedule =
        interactionModel.findResourceStateMachine("FlightSchedule");
    IMResourceStateMachine rsmAirport = interactionModel.findResourceStateMachine("Airport");
    IMResourceStateMachine rsmFlight = interactionModel.findResourceStateMachine("Flight");
    IMResourceStateMachine rsmPassenger = interactionModel.findResourceStateMachine("Passenger");
    rsmFlight.addTransitionToEntityState(
        "flight", rsmFlightSchedule, "flightschedule", "flightScheduleNum", null);
    rsmFlightSchedule.addTransitionToEntityState(
        "flightschedule", rsmAirport, "departureAirport", "departureAirportCode", null);
    rsmFlightSchedule.addTransitionToEntityState(
        "flightschedule", rsmAirport, "arrivalAirport", "arrivalAirportCode", null);
    rsmAirport.addTransitionToCollectionState(
        "airport",
        rsmFlightSchedule,
        "departures",
        "departureAirportCode eq '{code}'",
        "departureAirportCode",
        "departures");
    rsmAirport.addTransitionToCollectionState(
        "airport",
        rsmFlightSchedule,
        "arrivals",
        "arrivalAirportCode eq '{code}'",
        "arrivalAirportCode",
        "arrivals");
    rsmPassenger.addTransitionToEntityState("passenger", rsmFlight, "flight", "flightID", "flight");

    // Run the generator
    MockGenerator generator = new MockGenerator();
    boolean status =
        generator.generateArtifacts(
            metadata,
            interactionModel,
            new File("target/FlightResponder/classes"),
            new File("target/FlightResponder/classes"),
            true);

    // Check results
    assertTrue(status);

    // Test rim dsl
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET *-> flightschedule_departureAirport {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET -> flightschedule_departureAirport {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET *-> flightschedule_arrivalAirport {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET -> flightschedule_arrivalAirport {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET -> airport_arrivals {"
                + RIM_LINE_SEP
                + "\t\ttitle: \"arrivals\""
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{code}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET -> airport_departures {"
                + RIM_LINE_SEP
                + "\t\ttitle: \"departures\""
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{code}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET -> passenger_flight {"
                + RIM_LINE_SEP
                + "\t\ttitle: \"flight\""
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{passengerNo}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
  }
예제 #7
0
  @Test
  public void testGeneratedArtifactsFromConceptualModels() {
    // Parse the test metadata
    MetadataParser parser = new MetadataParser();
    InputStream is =
        parser.getClass().getClassLoader().getResourceAsStream(METADATA_AIRLINE_XML_FILE);
    Metadata metadata = parser.parse(is);
    Assert.assertNotNull(metadata);

    // Define the interaction model
    InteractionModel interactionModel = new InteractionModel(metadata);

    IMResourceStateMachine rsmFlightSchedule =
        interactionModel.findResourceStateMachine("FlightSchedule");
    IMResourceStateMachine rsmAirport = interactionModel.findResourceStateMachine("Airport");
    IMResourceStateMachine rsmFlight = interactionModel.findResourceStateMachine("Flight");
    IMResourceStateMachine rsmPassenger = interactionModel.findResourceStateMachine("Passenger");
    rsmFlight.addTransitionToEntityState(
        "flight", rsmFlightSchedule, "flightschedule", "flightScheduleNum", null);
    rsmFlightSchedule.addTransitionToEntityState(
        "flightschedule", rsmAirport, "departureAirport", "departureAirportCode", null);
    rsmFlightSchedule.addTransitionToEntityState(
        "flightschedule", rsmAirport, "arrivalAirport", "arrivalAirportCode", null);
    rsmAirport.addTransitionToCollectionState(
        "airport",
        rsmFlightSchedule,
        "departures",
        "departureAirportCode eq '{code}'",
        "departureAirportCode",
        null);
    rsmAirport.addTransitionToCollectionState(
        "airport",
        rsmFlightSchedule,
        "arrivals",
        "arrivalAirportCode eq '{code}'",
        "arrivalAirportCode",
        null);
    rsmPassenger.addTransitionToEntityState("passenger", rsmFlight, "flight", "flightID", null);

    // Run the generator
    MockGenerator generator = new MockGenerator();
    boolean status =
        generator.generateArtifacts(
            metadata,
            interactionModel,
            new File("target/FlightResponder/classes"),
            new File("target/FlightResponder/classes"),
            true);

    // Check results
    assertTrue(status);

    assertTrue(generator.generatedClasses.size() == 4);
    assertTrue(generator.generatedClasses.get(0).contains("public class Flight"));
    assertTrue(generator.generatedClasses.get(1).contains("public class Airport"));
    assertTrue(generator.generatedClasses.get(2).contains("public class FlightSchedule"));
    assertTrue(generator.generatedClasses.get(3).contains("public class Passenger"));

    assertTrue(generator.generateResponderDML.contains("INSERT INTO `Flight`("));
    assertTrue(generator.generateResponderDML.contains("INSERT INTO `Airport`("));
    assertTrue(generator.generateResponderDML.contains("INSERT INTO `FlightSchedule`("));
    assertTrue(generator.generateResponderDML.contains("INSERT INTO `Passenger`("));

    assertTrue(
        generator.generatedPersistenceXML.contains("<class>FlightResponderModel.Flight</class>"));
    assertTrue(
        generator.generatedPersistenceXML.contains("<class>FlightResponderModel.Airport</class>"));
    assertTrue(
        generator.generatedPersistenceXML.contains(
            "<class>FlightResponderModel.FlightSchedule</class>"));
    assertTrue(
        generator.generatedPersistenceXML.contains(
            "<class>FlightResponderModel.Passenger</class>"));

    assertTrue(
        generator.generatedSpringXML.contains(
            "<bean id=\"behaviour\" class=\"FlightResponderModel.FlightResponderBehaviour\" />"));

    assertTrue(
        generator.generatedSpringResourceManagerXML.contains(
            "<constructor-arg name=\"namespace\" value=\"FlightResponder\" />"));

    // Test rim dsl
    assertTrue(generator.generatedRimDsl.contains("initial resource ServiceDocument"));
    assertTrue(generator.generatedRimDsl.contains("GET -> FlightSchedules"));
    assertTrue(generator.generatedRimDsl.contains("resource FlightSchedules"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET *-> flightschedule {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(
        generator.generatedRimDsl.contains(
            "GET *-> flightschedule_departureAirport {"
                + RIM_LINE_SEP
                + "\t\tparameters [ id=\"{flightScheduleID}\" ]"
                + RIM_LINE_SEP
                + "\t}"));
    assertTrue(generator.generatedRimDsl.contains("resource flightschedule_departureAirport"));
    assertTrue(
        generator.generatedRimDsl.contains("path: \"/FlightSchedules({id})/departureAirport\""));
    assertTrue(generator.generatedRimDsl.contains("GET -> Passengers"));
    assertTrue(generator.generatedRimDsl.contains("resource Passengers"));
  }