package com.temenos.interaction.sdk; /* * #%L * interaction-sdk * %% * Copyright (C) 2012 - 2013 Temenos Holdings N.V. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Test; import com.temenos.interaction.core.entity.EntityMetadata; import com.temenos.interaction.core.entity.Metadata; import com.temenos.interaction.core.entity.MetadataParser; import com.temenos.interaction.core.entity.vocabulary.Vocabulary; import com.temenos.interaction.core.entity.vocabulary.terms.TermIdField; import com.temenos.interaction.core.entity.vocabulary.terms.TermValueType; import com.temenos.interaction.sdk.adapter.edmx.EDMXAdapter; import com.temenos.interaction.sdk.interaction.IMResourceStateMachine; import com.temenos.interaction.sdk.interaction.InteractionModel; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; /** * Unit test for {@link JPAResponderGen}. */ public class TestJPAResponderGen { public final static String METADATA_AIRLINE_XML_FILE = "AirlinesMetadata.xml"; public final static String EDMX_AIRLINE_FILE = "airlines.edmx"; private final static String RIM_LINE_SEP = System.getProperty("line.separator"); //Mock out methods that write contents to files class MockGenerator extends JPAResponderGen { List<String> generatedClasses = new ArrayList<String>(); String generatedPersistenceXML; String generatedSpringXML; String generatedSpringResourceManagerXML; String generateResponderDML; String generatedRimDsl; String generatedMetadata; @Override protected boolean writeClass(String path, String classFileName, String generatedClass) { this.generatedClasses.add(generatedClass); return true; } @Override protected boolean writeJPAConfiguration(File sourceDir, String generatedPersistenceXML) { this.generatedPersistenceXML = generatedPersistenceXML; return true; } @Override protected boolean writeSpringConfiguration(File sourceDir, String filename, String generatedSpringXML) { if (filename.equals(JPAResponderGen.SPRING_CONFIG_FILE)) { this.generatedSpringXML = generatedSpringXML; } else if (filename.equals(JPAResponderGen.SPRING_RESOURCEMANAGER_FILE)) { this.generatedSpringResourceManagerXML = generatedSpringXML; } return true; } @Override protected boolean writeResponderDML(File sourceDir, String generateResponderDML) { this.generateResponderDML = generateResponderDML; return true; } @Override protected boolean writeRimDsl(File sourceDir, String rimDslFilename, String generatedRimDsl) { this.generatedRimDsl = generatedRimDsl; return true; } @Override protected boolean writeMetadata(File sourceDir, String generatedMetadata) { this.generatedMetadata = generatedMetadata; return true; } }; @Test public void testEntityInfo() { JPAResponderGen rg = new JPAResponderGen(); EntityMetadata mdEntity = new EntityMetadata("Flight"); Vocabulary voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER)); voc.setTerm(new TermIdField(true)); mdEntity.setPropertyVocabulary("ID", voc); EntityInfo p = rg.createEntityInfoFromEntityMetadata("AirlineModel", mdEntity); assertEquals("Flight", p.getClazz()); assertEquals("AirlineModel", p.getPackage()); assertEquals("AirlineModel.Flight", p.getFQTypeName()); } @Test public void testJPAEntityKeyInfo() { JPAResponderGen rg = new JPAResponderGen(); EntityMetadata mdEntity = new EntityMetadata("Flight"); Vocabulary voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER)); voc.setTerm(new TermIdField(true)); mdEntity.setPropertyVocabulary("flightID", voc); EntityInfo p = rg.createEntityInfoFromEntityMetadata("AirlineModel", mdEntity); assertEquals("flightID", p.getKeyInfo().getName()); assertEquals("Long", p.getKeyInfo().getType()); assertEquals(0, p.getFieldInfos().size()); } @Test public void testJPAEntityFieldInfo() { JPAResponderGen rg = new JPAResponderGen(); EntityMetadata mdEntity = new EntityMetadata("Flight"); Vocabulary voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER)); voc.setTerm(new TermIdField(true)); mdEntity.setPropertyVocabulary("ID", voc); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER)); mdEntity.setPropertyVocabulary("flightID", voc); mdEntity.setPropertyVocabulary("number", new Vocabulary()); mdEntity.setPropertyVocabulary("runway", new Vocabulary()); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.TIMESTAMP)); mdEntity.setPropertyVocabulary("departureDT", voc); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.DATE)); mdEntity.setPropertyVocabulary("departureDate", voc); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.TIME)); mdEntity.setPropertyVocabulary("departureTime", voc); EntityInfo p = rg.createEntityInfoFromEntityMetadata("AirlineModel", mdEntity); assertEquals(6, p.getFieldInfos().size()); assertTrue(p.getFieldInfos().contains(new FieldInfo("flightID", "Long", null))); assertTrue(p.getFieldInfos().contains(new FieldInfo("number", "String", null))); assertTrue(p.getFieldInfos().contains(new FieldInfo("runway", "String", null))); assertTrue(p.getFieldInfos().contains(new FieldInfo("departureDT", "java.util.Date", null))); assertTrue(p.getFieldInfos().contains(new FieldInfo("departureDate", "java.util.Date", null))); assertTrue(p.getFieldInfos().contains(new FieldInfo("departureTime", "java.util.Date", null))); } @Test public void testJPAEntityFieldInfoAnnotations() { JPAResponderGen rg = new JPAResponderGen(); EntityMetadata mdEntity = new EntityMetadata("Flight"); Vocabulary voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER)); voc.setTerm(new TermIdField(true)); mdEntity.setPropertyVocabulary("ID", voc); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.TIMESTAMP)); mdEntity.setPropertyVocabulary("departureDT", voc); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.DATE)); mdEntity.setPropertyVocabulary("departureDate", voc); voc = new Vocabulary(); voc.setTerm(new TermValueType(TermValueType.TIME)); mdEntity.setPropertyVocabulary("departureTime", voc); EntityInfo p = rg.createEntityInfoFromEntityMetadata("AirlineModel", mdEntity); // Annotations for (FieldInfo fi : p.getFieldInfos()) { if ("departureDate".equals(fi.getName())) { assertEquals(1, fi.getAnnotations().size()); assertEquals("@Temporal(TemporalType.DATE)", fi.getAnnotations().get(0)); } else if ("departureTime".equals(fi.getName())) { assertEquals(1, fi.getAnnotations().size()); assertEquals("@Temporal(TemporalType.TIME)", fi.getAnnotations().get(0)); } else if ("departureDT".equals(fi.getName())) { assertEquals(1, fi.getAnnotations().size()); assertEquals("@Temporal(TemporalType.TIMESTAMP)", fi.getAnnotations().get(0)); } } } @Test(expected = AssertionError.class) public void testGenJPAEntityNull() { JPAResponderGen rg = new JPAResponderGen(); assertNull(rg.generateJPAEntityClass(null)); } @Test public void testGenJPAEntity() { JPAResponderGen rg = new JPAResponderGen(); FieldInfo keyInfo = new FieldInfo("flightID", "Long", null); List<FieldInfo> properties = new ArrayList<FieldInfo>(); properties.add(new FieldInfo("number", "String", null)); properties.add(new FieldInfo("fitHostiesName", "String", null)); properties.add(new FieldInfo("runway", "String", null)); properties.add(new FieldInfo("passengers", "Integer", null)); List<String> annotations = new ArrayList<String>(); annotations.add("@Temporal(TemporalType.TIMESTAMP)"); properties.add(new FieldInfo("departureDT", "java.util.Date", annotations)); properties.add(new FieldInfo("dinnerServed", "java.sql.Timestamp", null)); EntityInfo jpaEntity = new EntityInfo("Flight", "AirlineModel.model", keyInfo, properties); String generatedClass = rg.generateJPAEntityClass(jpaEntity); assertTrue(generatedClass.contains("package AirlineModel.model;")); assertTrue(generatedClass.contains("import javax.persistence.Entity;")); assertTrue(generatedClass.contains("@Entity")); assertTrue(generatedClass.contains("public class Flight {")); assertTrue(generatedClass.contains("@Id")); assertTrue(generatedClass.contains("@Basic(optional = false)")); assertTrue(generatedClass.contains("private Long flightID;")); assertTrue(generatedClass.contains("private String number;")); assertTrue(generatedClass.contains("private String fitHostiesName;")); assertTrue(generatedClass.contains("private String runway;")); assertTrue(generatedClass.contains("private Integer passengers;")); // date handling needs some special support assertTrue(generatedClass.contains("@Temporal(TemporalType.TIMESTAMP)")); assertTrue(generatedClass.contains("private java.util.Date departureDT;")); assertTrue(generatedClass.contains("private java.sql.Timestamp dinnerServed;")); assertTrue(generatedClass.contains("public Flight() {")); } @Test public void testGenJPAEntitySimpleJoin() { JPAResponderGen rg = new JPAResponderGen(); FieldInfo keyInfo = new FieldInfo("flightID", "Long", null); List<FieldInfo> properties = new ArrayList<FieldInfo>(); properties.add(new FieldInfo("number", "String", null)); List<String> annotations = new ArrayList<String>(); annotations.add("@Temporal(TemporalType.TIMESTAMP)"); properties.add(new FieldInfo("departureDT", "java.util.Date", annotations)); List<JoinInfo> joins = new ArrayList<JoinInfo>(); List<String> joinAnnotations = new ArrayList<String>(); joinAnnotations.add("@ManyToMany(mappedBy=\"Flight\")"); joins.add(new JoinInfo("passengers", "Person", joinAnnotations)); EntityInfo jpaEntity = new EntityInfo("Flight", "AirlineModel.model", keyInfo, properties, joins, true); String generatedClass = rg.generateJPAEntityClass(jpaEntity); assertTrue(generatedClass.contains("package AirlineModel.model;")); assertTrue(generatedClass.contains("import javax.persistence.Entity;")); assertTrue(generatedClass.contains("@Entity")); assertTrue(generatedClass.contains("public class Flight {")); assertTrue(generatedClass.contains("@Id")); assertTrue(generatedClass.contains("@Basic(optional = false)")); assertTrue(generatedClass.contains("private Long flightID;")); assertTrue(generatedClass.contains("private String number;")); assertTrue(generatedClass.contains("@Temporal(TemporalType.TIMESTAMP)")); assertTrue(generatedClass.contains("private java.util.Date departureDT;")); assertTrue(generatedClass.contains("@ManyToMany(mappedBy=\"Flight\")")); assertTrue(generatedClass.contains("private Collection<Person> passengers;")); assertTrue(generatedClass.contains("public Flight() {")); } @Test public void testGenJPAConfiguration() { JPAResponderGen rg = new JPAResponderGen(); List<EntityInfo> entitiesInfo = new ArrayList<EntityInfo>(); entitiesInfo.add(new EntityInfo("Flight", "AirlineModel", null, null)); entitiesInfo.add(new EntityInfo("Airport", "AirlineModel", null, null)); entitiesInfo.add(new EntityInfo("FlightSchedule", "AirlineModel", null, null)); String generatedPersistenceConfig = rg.generateJPAConfiguration(entitiesInfo); assertTrue(generatedPersistenceConfig.contains("<!-- Generated JPA configuration for IRIS MockResponder -->")); assertTrue(generatedPersistenceConfig.contains("<class>AirlineModel.Flight</class>")); assertTrue(generatedPersistenceConfig.contains("<class>AirlineModel.Airport</class>")); assertTrue(generatedPersistenceConfig.contains("<class>AirlineModel.FlightSchedule</class>")); } @Test public void testGenResponderDML() { JPAResponderGen rg = new JPAResponderGen(); List<EntityInfo> entitiesInfo = new ArrayList<EntityInfo>(); List<FieldInfo> properties = new ArrayList<FieldInfo>(); properties.add(new FieldInfo("number", "Long", null)); properties.add(new FieldInfo("fitHostiesName", "String", null)); properties.add(new FieldInfo("runway", "String", null)); entitiesInfo.add(new EntityInfo("Flight", "AirlineModel", null, properties)); entitiesInfo.add(new EntityInfo("Airport", "AirlineModel", null, null)); entitiesInfo.add(new EntityInfo("FlightSchedule", "AirlineModel", null, null)); String generatedResponderDML = rg.generateResponderDML(entitiesInfo); assertTrue(generatedResponderDML.contains("INSERT INTO `Flight`(`number` , `fitHostiesName` , `runway`) VALUES('1' , 'abc' , 'abc');")); assertTrue(generatedResponderDML.contains("INSERT INTO `Airport`() VALUES();")); assertTrue(generatedResponderDML.contains("INSERT INTO `FlightSchedule`() VALUES();")); } @Test public void testGenResponderDMLWithNavProperties() { JPAResponderGen rg = new JPAResponderGen(); List<EntityInfo> entitiesInfo = new ArrayList<EntityInfo>(); List<FieldInfo> properties = new ArrayList<FieldInfo>(); List<String> annotations = new ArrayList<String>(); annotations.add("@ManyToOne(optional = false)"); properties.add(new FieldInfo("number", "Long", null)); properties.add(new FieldInfo("fitHostiesName", "String", annotations)); properties.add(new FieldInfo("runway", "String", null)); entitiesInfo.add(new EntityInfo("Flight", "AirlineModel", null, properties)); entitiesInfo.add(new EntityInfo("Airport", "AirlineModel", null, null)); entitiesInfo.add(new EntityInfo("FlightSchedule", "AirlineModel", null, null)); String generatedResponderDML = rg.generateResponderDML(entitiesInfo); assertTrue(generatedResponderDML.contains("INSERT INTO `Flight`(`number` , `runway`) VALUES('1' , 'abc');")); assertTrue(generatedResponderDML.contains("INSERT INTO `Airport`() VALUES();")); assertTrue(generatedResponderDML.contains("INSERT INTO `FlightSchedule`() VALUES();")); } @Test public void testFormClassFilename() { assertEquals("/tmp/blah/com/some/package/SomeClass.java", JPAResponderGen.formClassFilename("/tmp/blah/com/some/package", new EntityInfo("SomeClass", "com.some.package", null, null))); } @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); boolean foundFlight = false; boolean foundAirport = false; boolean foundFlightSchedule = false; boolean foundPassenger = false; for (String clazz : generator.generatedClasses) { if (clazz.contains("public class Flight")) { foundFlight = true; } if (clazz.contains("public class Airport")) { foundAirport = true; } if (clazz.contains("public class FlightSchedule")) { foundFlightSchedule = true; } if (clazz.contains("public class Passenger")) { foundPassenger = true; } } assertTrue(foundFlight); assertTrue(foundAirport); assertTrue(foundFlightSchedule); assertTrue(foundPassenger); 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 String generatedRimDsl = stripEmptyLinesAndTrim(generator.generatedRimDsl); assertTrue(generatedRimDsl.contains("initial resource ServiceDocument")); assertTrue(generatedRimDsl.contains("GET -> FlightSchedules")); assertTrue(generatedRimDsl.contains("resource FlightSchedules")); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET *-> flightschedule {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET *-> flightschedule_departureAirport {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains("resource flightschedule_departureAirport")); assertTrue(generatedRimDsl.contains("path: \"/FlightSchedules({id})/departureAirport\"")); assertTrue(generatedRimDsl.contains("GET -> Passengers")); assertTrue(generatedRimDsl.contains("resource Passengers")); } @Test public void testGeneratedArtifactsFromEdmx() { //Parse the test metadata InputStream isEdmx = getClass().getResourceAsStream("/" + EDMX_AIRLINE_FILE); //Run the generator MockGenerator generator = new MockGenerator(); boolean status = generator.generateArtifacts(new EDMXAdapter(isEdmx), 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 FlightSchedule")); assertTrue(generator.generatedClasses.get(1).contains("public class Airport")); assertTrue(generator.generatedClasses.get(2).contains("public class Flight")); 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 String generatedRimDsl = stripEmptyLinesAndTrim(generator.generatedRimDsl); assertTrue(generatedRimDsl.contains("initial resource ServiceDocument")); assertTrue(generatedRimDsl.contains("GET -> FlightSchedules")); assertTrue(generatedRimDsl.contains("resource FlightSchedules")); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET *-> flightschedule {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET *-> flightschedule_departureAirport {" + RIM_LINE_SEP + "\t\ttitle: \"departureAirport\"" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains("resource flightschedule_departureAirport")); assertTrue(generatedRimDsl.contains("path: \"/FlightSchedules({id})/departureAirport\"")); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> airport_arrivals {" + RIM_LINE_SEP + "\t\ttitle: \"arrivals\"" + RIM_LINE_SEP + "\t\tparameters [ id=\"{code}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> airport_departures {" + RIM_LINE_SEP + "\t\ttitle: \"departures\"" + RIM_LINE_SEP + "\t\tparameters [ id=\"{code}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains("GET -> Passengers")); assertTrue(generatedRimDsl.contains("resource Passengers")); } @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 String generatedRimDsl = stripEmptyLinesAndTrim(generator.generatedRimDsl); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET *-> flightschedule_departureAirport {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> flightschedule_departureAirport {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET *-> flightschedule_arrivalAirport {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> flightschedule_arrivalAirport {" + RIM_LINE_SEP + "\t\tparameters [ id=\"{flightScheduleID}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> airport_arrivals {" + RIM_LINE_SEP + "\t\ttitle: \"arrivals\"" + RIM_LINE_SEP + "\t\tparameters [ id=\"{code}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> airport_departures {" + RIM_LINE_SEP + "\t\ttitle: \"departures\"" + RIM_LINE_SEP + "\t\tparameters [ id=\"{code}\" ]" + RIM_LINE_SEP + "\t}"))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("GET -> passenger_flight {" + RIM_LINE_SEP + "\t\ttitle: \"flight\"" + RIM_LINE_SEP + "\t\tparameters [ id=\"{passengerNo}\" ]" + RIM_LINE_SEP + "\t}"))); } /* * 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 String generatedRimDsl = stripEmptyLinesAndTrim(generator.generatedRimDsl); assertTrue(generatedRimDsl.contains("POST -> Airports_created")); assertTrue(generatedRimDsl.contains("PUT *-> airport_updated")); assertTrue(generatedRimDsl.contains("PUT -> airport_updated")); assertTrue(generatedRimDsl.contains("DELETE *-> airport_deleted")); assertTrue(generatedRimDsl.contains("DELETE -> airport_deleted")); assertTrue(generatedRimDsl.contains("resource Airports_created")); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("resource Airports_created {" + RIM_LINE_SEP + "\ttype: item" + RIM_LINE_SEP + "\tentity: Airport" + RIM_LINE_SEP + "\tactions [ CreateEntity ]" + RIM_LINE_SEP + "\tpath: \"/Airports()\""))); assertTrue(generatedRimDsl.contains(stripEmptyLinesAndTrim("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(generatedRimDsl.contains(stripEmptyLinesAndTrim("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(generatedRimDsl.contains(stripEmptyLinesAndTrim("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}"))); } private String stripEmptyLinesAndTrim(String source) { StringBuilder lines = new StringBuilder(); BufferedReader reader = new BufferedReader(new StringReader(source)); String line; try { while ((line = reader.readLine()) != null) { line = line.trim(); if (!line.equals("")) { lines.append(line).append('\n'); } } } catch (IOException ex) { // can not really happen in StringReader } try { reader.close(); } catch (IOException ex) { // ignored on purpose } return lines.toString(); } }