From 7785d5fdf183951b15c806397c61e18f999a9523 Mon Sep 17 00:00:00 2001
From: marvin <marvin@marvin-TERRA-MOBILE-1529H>
Date: Wed, 29 Jan 2020 23:38:54 +0100
Subject: [PATCH] gitignore change

---
 .../FeatureModelConfigurator/src/.gitignore   |   5 +
 .../FeatureModelConfigurator/src/Adapter.java | 280 ++++++++++++++++++
 .../src/Configurator.java                     | 160 ++++++++++
 3 files changed, 445 insertions(+)
 create mode 100644 Varianten/FeatureModelConfigurator/src/.gitignore
 create mode 100644 Varianten/FeatureModelConfigurator/src/Adapter.java
 create mode 100644 Varianten/FeatureModelConfigurator/src/Configurator.java

diff --git a/Varianten/FeatureModelConfigurator/src/.gitignore b/Varianten/FeatureModelConfigurator/src/.gitignore
new file mode 100644
index 0000000..7e3573c
--- /dev/null
+++ b/Varianten/FeatureModelConfigurator/src/.gitignore
@@ -0,0 +1,5 @@
+#Woher kommt das??
+#/Adapter.java
+#/Configurator.jak
+#/.gitignore
+#/Configurator.java
diff --git a/Varianten/FeatureModelConfigurator/src/Adapter.java b/Varianten/FeatureModelConfigurator/src/Adapter.java
new file mode 100644
index 0000000..360929d
--- /dev/null
+++ b/Varianten/FeatureModelConfigurator/src/Adapter.java
@@ -0,0 +1,280 @@
+import java.io.*;
+import java.util.*;
+
+import org.jdom2.*;
+import org.jdom2.filter.Filters;
+import org.jdom2.input.SAXBuilder;
+import org.jdom2.output.XMLOutputter;
+import org.jdom2.xpath.*;
+
+
+
+/**
+ * Takes a featuremodel.xml file generated using FeatureModelConfigurator and a given 
+ * ROS/ Gazebo .gazebo.xacro file.
+ * The .gazebo.xacro file is modified to support the features specified in the
+ * featuremodel.xml file.
+ */
+public class Adapter {
+	
+	/**
+	 * Reads an .xml file from file path and returns a JDOM document.
+	 * 
+	 * @param src			The .xml file path
+	 * @return JDOM document
+	 * @throws JDOMException
+	 * @throws IOException
+	 */
+	public static Document readXml(String src) throws JDOMException, IOException {
+		File file = new File(src);
+		SAXBuilder saxBuilder = new SAXBuilder();
+		Document doc = saxBuilder.build(file);
+
+		return doc;
+	}
+	
+	/**
+	 * Saves the given Document as XML to the given path.
+	 * 
+	 * @param oDoc			The JDOM document
+	 * @param sPath			The output path
+	 * @throws IOException
+	 */
+	public static void saveAsXml(Document oDoc, String sPath) throws IOException {
+		FileOutputStream dest = new FileOutputStream(sPath);
+		XMLOutputter xmlOutput = new XMLOutputter();		
+		xmlOutput.output(oDoc, dest);
+	}
+	
+	/**
+	 * Executes given XPath expression for elements with JDOM Document as source.
+	 * 
+	 * @param doc			The JDOM Document
+	 * @param xPath			XPath expression
+	 * @return List with all elements found or empty list if no match found
+	 */
+	public static List<Element> xQueryElements(Document doc, String xPath) {
+		XPathFactory xFactory = XPathFactory.instance();
+		XPathExpression<Element> expr = xFactory.compile(xPath, Filters.element());
+		List<Element> result = expr.evaluate(doc);
+		
+		return result;
+	}
+	
+	/**
+	 * Executes given XPath expression for elements with Element as source.
+	 * 
+	 * @param elem			The Element
+	 * @param xPath			XPath expression
+	 * @return List with all elements found or empty list if no match found
+	 */
+	public static List<Element> xQueryElements(Element elem, String xPath) {
+		XPathFactory xFactory = XPathFactory.instance();
+		XPathExpression<Element> expr = xFactory.compile(xPath, Filters.element());
+		List<Element> result = expr.evaluate(elem);
+		
+		return result;
+	}
+	
+	/**
+	 * Executes given XPath expression for attributes.
+	 * 
+	 * @param doc			The JDOM Document
+	 * @param xPath			XPath expression
+	 * @return List with all attributes found or empty list if no match found
+	 */
+	public static List<Attribute> xQueryAttributes(Document doc, String xPath) {
+		XPathFactory xFactory = XPathFactory.instance();
+		XPathExpression<Attribute> expr = xFactory.compile(xPath, Filters.attribute());
+		List<Attribute> result = expr.evaluate(doc);
+		
+		return result;
+	}
+	
+	/**
+	 * Searches a document for the first occurrence of an xml tag.
+	 * 
+	 * @param doc			The JDOM Document
+	 * @param elementName	Name of the xml tag
+	 * @return First element found or NULL if no match found
+	 */
+	public static Element searchFirstElement(Document doc, String elementName) {
+		//XPath index starts with 1; [] has a higher precedence than //
+		List<Element> query= xQueryElements(doc, "(//"+elementName+")[1]");
+		
+		if(query.isEmpty()) return null;
+		return query.get(0);
+	}
+	
+	/**
+	 * Searches a document for all occurrences of an xml tag.
+	 * 
+	 * @param doc			The JDOM Document
+	 * @param elementName	Name of the xml tag
+	 * @return List with all elements found or empty list if no match found
+	 */
+	public static List<Element> searchAllElements(Document doc, String elementName) {
+		return xQueryElements(doc, "//"+elementName);
+	}
+	
+	/**
+	 * Checks whether two elements have an equal xml tag.
+	 * (Name of the xml tag and all attributes including their order must be equal)
+	 * 
+	 * @param element1		Element1
+	 * @param element2		Element2
+	 * @return true if of equal tag or false if not
+	 */
+	public static boolean equalTag(Element element1, Element element2) {
+		List<Attribute> attributeList1 = element1.getAttributes();
+		List<Attribute> attributeList2 = element2.getAttributes();
+		
+		if(!element1.getName().equals(element2.getName())) return false;
+		if(attributeList1.size()!=attributeList2.size()) return false;
+		for(int i=0; i<attributeList1.size(); i++) {
+			if(!attributeList1.get(i).getName().equals(attributeList2.get(i).getName())) return false;
+			if(!attributeList1.get(i).getValue().equals(attributeList2.get(i).getValue())) return false;
+		}
+		
+		return true;
+	}
+	
+	/**
+	 * Recursive replacement of all text values in destElements with their corresponding 
+	 * new ones from srcElements.
+	 * (srcElements and destElements must be matching tags!)
+	 * 
+	 * TODO maybe add tags that are in srcElements but not yet in destElements
+	 * 
+	 * @param srcElements		Element list with new values
+	 * @param destElements		Element list with values to be replaced
+	 * @return true if reached deepest Element or false if not
+	 */
+	public static boolean replace(List<Element> srcElements, List<Element> destElements) {
+		if(srcElements.isEmpty()&&destElements.isEmpty()) return true;
+		if(srcElements.isEmpty()^destElements.isEmpty()) {
+			System.out.println("Error during value replacement: Sensor xml trees have mismatching deph (maybe tags with no value)");
+			System.exit(-1);
+		}
+		for(Element src : srcElements) {
+			for(Element dest : destElements) {		
+				if(equalTag(src, dest)) {
+					boolean deadEnd = replace(src.getChildren(), dest.getChildren());
+					if(deadEnd) dest.setText(src.getText());
+					break;
+				}
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		try {
+			//TODO##### Input ###############################
+			Document featureModel = readXml("resources/output/featuremodel.xml");
+			Document sensorConfig = readXml("resources/input/sensorconfig.xml");
+			Document gazeboModel = null;
+			
+			//CustomBot not supported for now
+			List<Attribute> botList = xQueryAttributes(featureModel, "//module[@types='TurtleBot']/@name");
+			String botName = "";
+			String fileName = "";
+			
+			switch(botList.size()) {
+				case 0:
+					System.out.println("Invalid input: No bot selected");
+					System.exit(-1);
+					break;
+				case 1:
+					botName = botList.get(0).getValue();
+					break;
+				default:
+					System.out.println("Invalid input: Multiple bots selected");
+					System.exit(-1);
+			}
+			switch(botName) {
+				case "Burger":
+					fileName = "turtlebot3_burger.gazebo.xacro";
+					break;
+				case "Waffle":
+					fileName = "turtlebot3_waffle.gazebo.xacro";
+					break;
+				case "WafflePi":
+					fileName = "turtlebot3_waffle_pi.gazebo.xacro";
+					break;
+				default:
+					System.out.println("Cannot handle \'"+botName+"\': No input file known.");
+					System.exit(-1);
+			}
+			gazeboModel = readXml("resources/input/turtlebot3-master/turtlebot3_description/urdf/"+fileName);
+			//###############################################
+			
+			
+			//TODO##### Operate on .gazebo.xacro ############
+			List<Element> cSensorList = xQueryElements(sensorConfig, "//sensor");	
+			List<Element> gSensorList = xQueryElements(gazeboModel, "//sensor");
+			
+			if(cSensorList.isEmpty()) {
+				System.out.println("No new sensor values in sensorconfig.xml");
+				System.exit(-1);
+			}
+			if(gSensorList.isEmpty()) {
+				System.out.println("No sensors found in "+fileName);
+				System.exit(-1);
+			}
+			
+			for(Element cSensor : cSensorList) {
+				for(Element gSensor : gSensorList) {	
+					if(equalTag(cSensor, gSensor)) {
+						replace(cSensor.getChildren(),gSensor.getChildren());
+					}
+				}
+			}
+			
+			//hard-coded and only for demo purposes
+//			List<Element> cSensorList = xQueryElements(sensorConfig, "//sensor[@type='ray' and @name='lds_lfcd_sensor']");
+//			Element cSensor = cSensorList.get(0);
+//			
+//			List<Element> gSensorList = xQueryElements(gazeboModel, "//sensor[@type='ray' and @name='lds_lfcd_sensor']");
+//			Element gSensor = gSensorList.get(0);
+//
+//			String new_min = cSensor.getChild("range").getChild("min").getText();
+//			String new_max = cSensor.getChild("range").getChild("max").getText();
+//			
+//			gSensor.getChild("ray").getChild("range").getChild("min").setText(new_min);
+//			gSensor.getChild("ray").getChild("range").getChild("max").setText(new_max);
+			//###############################################
+			
+			
+			//######### Output result #######################
+			saveAsXml(gazeboModel, "resources/output/"+fileName);
+			//###############################################
+			
+			
+			//XPathExamples
+//			XPathFactory xFactory = XPathFactory.instance();
+//			XPathExpression<Element> xExpr = xFactory.compile("robot/gazebo/sensor/ray/range/min", Filters.element());
+//			Element test = xExpr.evaluateFirst(gazeboModel);
+//			List<Element> test2 = searchAllElements(gazeboModel, "min");
+//			List<Element> test3 = searchAllElements(gazeboModel, "max");
+//			Element test4 = searchFirstElement(gazeboModel, "plugin");
+//			List<Attribute> test5 = xQueryAttributes(gazeboModel, "(//plugin)[1]/@*");
+//			
+//			if(test != null) xmlOutput.output(test, System.out);
+//			System.out.println("\n");
+//			xmlOutput.output(test2, System.out);
+//			System.out.println("\n");
+//			xmlOutput.output(test3, System.out);
+//			System.out.println("\n");
+//			if(test4 != null) xmlOutput.output(test4, System.out);
+//			System.out.println("\n");
+//			for(Attribute a : test5) System.out.println(a.getName()+"="+a.getValue());
+			
+		} catch (JDOMException | IOException e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/Varianten/FeatureModelConfigurator/src/Configurator.java b/Varianten/FeatureModelConfigurator/src/Configurator.java
new file mode 100644
index 0000000..770a885
--- /dev/null
+++ b/Varianten/FeatureModelConfigurator/src/Configurator.java
@@ -0,0 +1,160 @@
+
+import java.util.List;
+import java.util.ArrayList;
+import java.io.IOException;
+
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+
+
+
+/**
+ * Main class for the car configurator.
+ * Is refined by modules, which add selected components to component list.
+ * This class has to save a file containing the configuration
+ * and launch the test seletion application afterwards.
+ * 
+ * 
+ * Naming conventions: 
+ * m_: Member variable
+ * s: String
+ * n: Integer number (int, long,...)
+ * f: Floating point number (float, double,...)
+ * o: Object
+ * a: Collection (List, Array,...)
+ * 
+ */
+
+abstract class Configurator$$ConfiguratorMain {	
+	//module list
+	private List m_aModuleList;
+	//output path
+	private String m_sOutputPath = "resources/output/featuremodel.xml";
+	//TODO: set this
+	//path for test case selector, which has to be launched from this application
+	private String m_sTestCaseSelectorPath;
+	//path to the feature model xml
+	private String m_sFeatureModelPath = "model.xml";
+	//document representation of the feature model
+	private Document m_oFeatureModelDoc; 
+	//representation of a single module with all of its types
+	class Module {
+		String sModuleName;
+		ArrayList aModuleTypes;
+	}
+	
+	
+	public static void main(String[] args) {
+		new Configurator().save();
+	}
+	
+	public void save() {						
+		//create empty xml
+		Element oStruct = new Element("specification");
+		Document oDoc = new Document(oStruct);
+		
+		//if the module list was initialized
+		if(m_aModuleList!=null) {
+			for(int i=0; i<m_aModuleList.size(); i++) {
+				//Add module and tag to Document
+				Element oModuleElement = new Element("module");
+				//Add name
+				Module oModule = (Module)m_aModuleList.get(i);
+				oModuleElement.setAttribute("name", oModule.sModuleName);
+				//Create type String
+				ArrayList<String> aTypes = oModule.aModuleTypes;	
+				String sTypesString = "";
+				//concat String
+				for(int j=0; j<aTypes.size(); j++) {
+					sTypesString += aTypes.get(j);
+					//add comma if it's not the last Type
+					if(j<aTypes.size()-1)
+						sTypesString += ", ";
+				}
+				oModuleElement.setAttribute("types", sTypesString);
+				oStruct.addContent(oModuleElement);
+			}
+		}
+		
+		//generate xml String and save it to a file
+		try {
+			Adapter.saveAsXml(oDoc, m_sOutputPath);	
+		}
+		catch (Exception oEx) {
+			System.out.println(oEx);
+			return;
+		}
+		
+		//create and launch Adapter
+		new Adapter();
+	}
+	
+	//get all parents of a given module from the Feature Model file
+	private Module GetModuleParents(String sModuleName) throws IOException, JDOMException {
+		Module oModule = new Module();
+		//set name
+		oModule.sModuleName = sModuleName;
+		//init Doc if not done
+		if(m_oFeatureModelDoc==null) {
+			m_oFeatureModelDoc = Adapter.readXml(m_sFeatureModelPath);
+			System.out.println(m_oFeatureModelDoc.toString());
+		}
+		//get element
+		String sQuery = "//*[@name= '"+sModuleName+"']";
+		List<Element> aModules = Adapter.xQueryElements(m_oFeatureModelDoc, sQuery);
+		Element oModuleElement;
+		try {
+			oModuleElement = aModules.get(0);
+		}
+		catch (Exception oEx) {
+			System.out.println(oEx.toString() + "\nList empty for query "+ sQuery);
+			return null;
+		}
+		//get all anchestors
+		Element oParent = oModuleElement.getParentElement();
+		ArrayList<String> aTypes = new ArrayList();
+		//itterate through parents of module
+		while(true) {
+			String sElementName = oParent.getAttribute("name").getValue();
+			//break if we reach the Main class, as there are no types further up
+			if(sElementName.equals("ConfiguratorMain")) {
+				break;
+			}
+			aTypes.add(sElementName);
+			//iterate further trough List
+			oModuleElement = oParent;
+			oParent = oModuleElement.getParentElement();
+		}		
+		oModule.aModuleTypes = aTypes;
+		return oModule;
+	}
+	
+	//add a module name  and module type to the feature list. Init list, if not already done
+	public void addToModuleList(String sModuleName) {
+		//init List, if not already done
+		if(m_aModuleList==null) {
+			m_aModuleList = new ArrayList();
+		}		
+		//get the module types
+		Module oModule;
+		try {
+			oModule = GetModuleParents(sModuleName);		
+		}
+		catch (Exception oEx) {
+			System.out.print(oEx);
+			return;
+		}		
+		m_aModuleList.add(oModule);
+	}
+}
+
+/**
+ * TODO description
+ */
+public class Configurator extends  Configurator$$ConfiguratorMain  {
+	public void save() {
+		super.addToModuleList("Waffle");
+		super.save();
+	}
+}
\ No newline at end of file
-- 
GitLab