From fdbc4c9cfb51158844f57891136022ba39b8f1bc Mon Sep 17 00:00:00 2001
From: tobias <tobias.ullerich@icloud.com>
Date: Thu, 28 Jul 2016 15:17:15 +0200
Subject: [PATCH] Implement XMLHandler for mapping

---
 .../src/de/tobias/playpad/VersionUpdater.java |  8 ++-
 .../playpad/action/ActionSerializer.java      | 51 ++++++++++++++
 .../playpad/action/MapperSerializer.java      | 36 ++++++++++
 .../src/de/tobias/playpad/action/Mapping.java | 66 +------------------
 .../de/tobias/playpad/action/MappingList.java | 40 +++++------
 .../playpad/action/MappingSerializer.java     | 55 ++++++++++++++++
 .../src/de/tobias/playpad/xml/XMLHandler.java |  2 +-
 7 files changed, 170 insertions(+), 88 deletions(-)
 create mode 100644 PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java
 create mode 100644 PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java
 create mode 100644 PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java

diff --git a/PlayWall/src/de/tobias/playpad/VersionUpdater.java b/PlayWall/src/de/tobias/playpad/VersionUpdater.java
index 66a4ce97..045a3e7e 100644
--- a/PlayWall/src/de/tobias/playpad/VersionUpdater.java
+++ b/PlayWall/src/de/tobias/playpad/VersionUpdater.java
@@ -19,6 +19,7 @@ import org.dom4j.io.SAXReader;
 import org.dom4j.io.XMLWriter;
 
 import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.MappingSerializer;
 import de.tobias.playpad.action.cartaction.CartAction;
 import de.tobias.playpad.action.cartaction.CartAction.ControlMode;
 import de.tobias.playpad.action.feedback.DoubleSimpleFeedback;
@@ -188,7 +189,9 @@ public class VersionUpdater implements UpdateService {
 
 		for (Mapping mapping : mappings) {
 			Element mappingElement = rootElement.addElement("Mapping");
-			mapping.save(mappingElement);
+
+			MappingSerializer mappingSerializer = new MappingSerializer();
+			mappingSerializer.saveElement(mappingElement, mapping);
 		}
 
 		XMLWriter writer = new XMLWriter(Files.newOutputStream(configPath.resolve("Mapping.xml")), OutputFormat.createPrettyPrint());
@@ -223,7 +226,8 @@ public class VersionUpdater implements UpdateService {
 				newSettingsElement.addElement("Loop").addText(oldPadElement.element("Loop").getStringValue());
 				if (oldPadElement.element("TimeMode") != null)
 					newSettingsElement.addElement("TimeMode").addText(oldPadElement.element("TimeMode").getStringValue());
-			} catch (Exception e) {}
+			} catch (Exception e) {
+			}
 		}
 
 		XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
diff --git a/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java
new file mode 100644
index 00000000..ca46cf05
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java
@@ -0,0 +1,51 @@
+package de.tobias.playpad.action;
+
+import java.util.List;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.xml.XMLDeserializer;
+import de.tobias.playpad.xml.XMLHandler;
+import de.tobias.playpad.xml.XMLSerializer;
+
+public class ActionSerializer implements XMLSerializer<Action>, XMLDeserializer<Action> {
+
+	private static final String ACTION_TYPE = "type";
+	private static final String MAPPER = "Mapper";
+
+	private Mapping mapping;
+
+	public ActionSerializer(Mapping mapping) {
+		this.mapping = mapping;
+	}
+
+	@Override
+	public Action loadElement(Element element) {
+		String tpye = element.attributeValue(ACTION_TYPE);
+
+		Action action = ActionRegistery.getActionConnect(tpye).newInstance();
+		action.load(element);
+
+		boolean added = mapping.addActionIfNotContains(action);
+
+		if (added) {
+			XMLHandler<Mapper> handler = new XMLHandler<>(element);
+			List<Mapper> mappers = handler.loadElements(MAPPER, new MapperSerializer(action));
+			mappers.forEach(action::addMapper);
+		}
+
+		return action;
+	}
+
+	@Override
+	public void saveElement(Element newElement, Action data) {
+		newElement.addAttribute(ACTION_TYPE, data.getType());
+
+		data.save(newElement);
+
+		XMLHandler<Mapper> handler = new XMLHandler<>(newElement);
+		handler.saveElements(MAPPER, data.getMappers(), new MapperSerializer(data));
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java
new file mode 100644
index 00000000..c9b60ef8
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java
@@ -0,0 +1,36 @@
+package de.tobias.playpad.action;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MapperRegistry;
+import de.tobias.playpad.xml.XMLDeserializer;
+import de.tobias.playpad.xml.XMLSerializer;
+
+public class MapperSerializer implements XMLSerializer<Mapper>, XMLDeserializer<Mapper> {
+
+	private static final String MAPPER_TYPE = "type";
+
+	private Action action;
+
+	public MapperSerializer(Action action) {
+		this.action = action;
+	}
+
+	@Override
+	public Mapper loadElement(Element element) {
+		String mapperType = element.attributeValue(MAPPER_TYPE);
+
+		Mapper mapper = MapperRegistry.getMapperConnect(mapperType).createNewMapper();
+		mapper.load(element, action);
+		return mapper;
+	}
+
+	@Override
+	public void saveElement(Element newElement, Mapper data) {
+		newElement.addAttribute(MAPPER_TYPE, data.getType());
+		data.save(newElement, action);
+
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java
index b451611d..ccfe4072 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java
@@ -7,8 +7,6 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
-import org.dom4j.Element;
-
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.action.mapper.Mapper;
 import de.tobias.playpad.action.mapper.MapperConnect;
@@ -160,68 +158,6 @@ public class Mapping implements Cloneable, ActionDisplayable {
 		getActions().forEach(action -> action.clearFeedback());
 	}
 
-	private static final String NAME = "name";
-	private static final String UUID_NAME = "uuid";
-	private static final String ACTION = "Action";
-	private static final String ACTION_TYPE = "type";
-	private static final String MAPPER = "Mapper";
-	private static final String MAPPER_TYPE = "type";
-
-	public void load(Element element, Profile profile) {
-		name = element.attributeValue(NAME);
-		if (element.attributeValue(UUID_NAME) != null)
-			uuid = UUID.fromString(element.attributeValue(UUID_NAME));
-		else
-			uuid = UUID.randomUUID();
-
-		for (Object obj : element.elements(ACTION)) {
-			if (obj instanceof Element) {
-				Element actionElement = (Element) obj;
-				String tpye = actionElement.attributeValue(ACTION_TYPE);
-
-				Action action = ActionRegistery.getActionConnect(tpye).newInstance();
-				action.load(actionElement);
-
-				boolean added = addActionIfNotContains(action);
-
-				if (added) {
-					for (Object mapperObj : actionElement.elements(MAPPER)) {
-						if (mapperObj instanceof Element) {
-							Element mapperElement = (Element) mapperObj;
-							String mapperType = mapperElement.attributeValue(MAPPER_TYPE);
-
-							Mapper mapper = MapperRegistry.getMapperConnect(mapperType).createNewMapper();
-							mapper.load(mapperElement, action);
-							action.addMapper(mapper);
-						}
-					}
-				}
-			}
-		}
-
-		initActionType(profile); // Update Actions, damit alle da sind und keine fehlt (falls eine gelöscht wurde auf der Datei)
-		updateDisplayProperty();
-	}
-
-	public void save(Element element) {
-		element.addAttribute(NAME, name);
-		element.addAttribute(UUID_NAME, uuid.toString());
-
-		for (Action action : mapping.keySet()) {
-			Element actionElement = element.addElement(ACTION);
-			actionElement.addAttribute(ACTION_TYPE, action.getType());
-
-			action.save(actionElement);
-
-			for (Mapper mapper : mapping.get(action)) {
-				Element mapperElement = actionElement.addElement(MAPPER);
-				mapperElement.addAttribute(MAPPER_TYPE, mapper.getType());
-
-				mapper.save(mapperElement, action);
-			}
-		}
-	}
-
 	@Override
 	public Mapping clone() throws CloneNotSupportedException {
 		Mapping clone = (Mapping) super.clone();
@@ -256,7 +192,7 @@ public class Mapping implements Cloneable, ActionDisplayable {
 		return displayProperty;
 	}
 
-	private void updateDisplayProperty() {
+	void updateDisplayProperty() {
 		displayProperty.set(toString());
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/action/MappingList.java b/PlayWallCore/src/de/tobias/playpad/action/MappingList.java
index 05517382..542f990d 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/MappingList.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/MappingList.java
@@ -5,6 +5,7 @@ import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.UUID;
 
 import org.dom4j.Document;
@@ -16,6 +17,7 @@ import org.dom4j.io.SAXReader;
 import org.dom4j.io.XMLWriter;
 
 import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.xml.XMLHandler;
 
 public class MappingList extends ArrayList<Mapping> {
 
@@ -62,16 +64,16 @@ public class MappingList extends ArrayList<Mapping> {
 				mappings.activeMapping = UUID.fromString(rootElement.attributeValue(ACTIVE_ATTR));
 			}
 
-			for (Object mappingObj : rootElement.elements(MAPPING)) {
-				if (mappingObj instanceof Element) {
-					Element mappingElement = (Element) mappingObj;
-
-					Mapping mapping = new Mapping(false, profile);
-					mapping.load(mappingElement, profile);
-
-					mappings.add(mapping);
-				}
-			}
+			// Load Mappings
+			XMLHandler<Mapping> handler = new XMLHandler<>(rootElement);
+			List<Mapping> loadMappings = handler.loadElements(MAPPING, new MappingSerializer(profile));
+			loadMappings.forEach(mapping ->
+			{
+				mapping.initActionType(profile); // Update Actions, damit alle da sind und keine fehlt (falls eine
+													// gelöscht wurde auf der Datei)
+				mapping.updateDisplayProperty();
+				mappings.add(mapping);
+			});
 		}
 
 		// Init mappings, if non exists
@@ -89,14 +91,9 @@ public class MappingList extends ArrayList<Mapping> {
 		if (activeMapping != null)
 			rootElement.addAttribute(ACTIVE_ATTR, activeMapping.toString());
 
-		for (Mapping mapping : this) {
-			Element mappingElement = rootElement.addElement(MAPPING);
-			mapping.save(mappingElement);
-		}
-
-		XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
-		writer.write(document);
-		writer.close();
+		XMLHandler<Mapping> handler = new XMLHandler<>(rootElement);
+		handler.saveElements(MAPPING, this, new MappingSerializer());
+		XMLHandler.save(path, document);
 	}
 
 	public static Mapping importMappingPreset(Path path, Profile profile) throws DocumentException, IOException {
@@ -106,7 +103,8 @@ public class MappingList extends ArrayList<Mapping> {
 		Document document = reader.read(Files.newInputStream(path));
 		Element rootElement = document.getRootElement();
 
-		mapping.load(rootElement, profile);
+		MappingSerializer mappingSerializer = new MappingSerializer(profile);
+		mapping = mappingSerializer.loadElement(rootElement);		
 		mapping.setUuid(UUID.randomUUID());
 
 		return mapping;
@@ -115,7 +113,9 @@ public class MappingList extends ArrayList<Mapping> {
 	public static void exportMidiPreset(Path path, Mapping preset) throws IOException {
 		Document docoment = DocumentHelper.createDocument();
 		Element rootElement = docoment.addElement(MAPPING);
-		preset.save(rootElement);
+
+		MappingSerializer mappingSerializer = new MappingSerializer();
+		mappingSerializer.saveElement(rootElement, preset);
 
 		XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
 		writer.write(docoment);
diff --git a/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java
new file mode 100644
index 00000000..e1885680
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java
@@ -0,0 +1,55 @@
+package de.tobias.playpad.action;
+
+import java.util.UUID;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.xml.XMLDeserializer;
+import de.tobias.playpad.xml.XMLHandler;
+import de.tobias.playpad.xml.XMLSerializer;
+
+public class MappingSerializer implements XMLSerializer<Mapping>, XMLDeserializer<Mapping> {
+
+	private static final String NAME = "name";
+	private static final String UUID_NAME = "uuid";
+	private static final String ACTION = "Action";
+
+	private Profile profile;
+
+	public MappingSerializer() {
+
+	}
+
+	public MappingSerializer(Profile profile) {
+		this.profile = profile;
+	}
+
+	@Override
+	public Mapping loadElement(Element element) {
+		Mapping mapping = new Mapping(false, profile);
+
+		mapping.setName(element.attributeValue(NAME));
+
+		UUID uuid;
+		if (element.attributeValue(UUID_NAME) != null)
+			uuid = UUID.fromString(element.attributeValue(UUID_NAME));
+		else
+			uuid = UUID.randomUUID();
+		mapping.setUuid(uuid);
+
+		XMLHandler<Action> handler = new XMLHandler<>(element);
+		handler.loadElements(ACTION, new ActionSerializer(mapping));
+
+		return mapping;
+	}
+
+	@Override
+	public void saveElement(Element newElement, Mapping data) {
+		newElement.addAttribute(NAME, data.getName());
+		newElement.addAttribute(UUID_NAME, data.getUuid().toString());
+
+		XMLHandler<Action> handler = new XMLHandler<>(newElement);
+		handler.saveElements(ACTION, data.getActions(), new ActionSerializer(data));
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java
index cd847e4f..0ba39178 100644
--- a/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java
+++ b/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java
@@ -89,7 +89,7 @@ public class XMLHandler<T> {
 	 * @param serializer
 	 *            Serializer
 	 */
-	public void saveElements(String listElementTag, List<T> list, XMLSerializer<T> serializer) {
+	public void saveElements(String listElementTag, Iterable<T> list, XMLSerializer<T> serializer) {
 		for (T data : list) {
 			Element element = rootElement.addElement(listElementTag);
 			serializer.saveElement(element, data);
-- 
GitLab