瀏覽代碼

Made implementation classes configurable from the respective properties file

This way implementation classes for EV/SE side controllers could be
replaced without touching the mainline code. I believe this will
simplify forking and extending the project.
Nagy Attila Gabor 6 年之前
父節點
當前提交
339cc722ac

+ 7 - 0
RISE-V2G-EVCC/EVCCConfig.properties

@@ -83,6 +83,13 @@ authentication.mode =
 # - DC_unique
 energy.transfermode.requested = AC_three_phase_core
 
+#
+# Implementation classes
+#---------------------------------------------
+# If you want to replace the implementations the set the following attributes
+# to the name of your classes
+# When omitted default dummy implementations will be used
+implementation.evcc.controller = com.v2gclarity.risev2g.evcc.evController.DummyEVController
 
 # XML representation of messages
 #-------------------------------

+ 50 - 0
RISE-V2G-EVCC/src/main/java/com/v2gclarity/risev2g/evcc/misc/EVCCImplementationFactory.java

@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * The MIT License (MIT)
+ *
+ * Copyright 2017 Dr.-Ing. Marc Mültin (V2G Clarity)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *******************************************************************************/
+package com.v2gclarity.risev2g.evcc.misc;
+
+import com.v2gclarity.risev2g.evcc.evController.DummyEVController;
+import com.v2gclarity.risev2g.evcc.evController.IEVController;
+import com.v2gclarity.risev2g.evcc.session.V2GCommunicationSessionEVCC;
+import com.v2gclarity.risev2g.shared.misc.V2GImplementationFactory;
+
+/**
+ * Implementation factory for the EVCC controller
+ *
+ */
+public class EVCCImplementationFactory extends V2GImplementationFactory {
+
+	/**
+	 * Creates the controller for the EVCC application
+	 * @param commSessionContext the session the backend will be connected to 
+	 * @return
+	 */
+	public static IEVController createEVController(V2GCommunicationSessionEVCC commSessionContext) {
+		IEVController instance = buildFromProperties("implementation.evcc.controller", IEVController.class, commSessionContext);
+		if (instance == null) {
+			return new DummyEVController(commSessionContext);
+		} else {
+			return instance;
+		}
+	}
+}

+ 2 - 2
RISE-V2G-EVCC/src/main/java/com/v2gclarity/risev2g/evcc/session/V2GCommunicationSessionEVCC.java

@@ -28,8 +28,8 @@ import java.util.List;
 import java.util.Observable;
 import java.util.Observer;
 
-import com.v2gclarity.risev2g.evcc.evController.DummyEVController;
 import com.v2gclarity.risev2g.evcc.evController.IEVController;
+import com.v2gclarity.risev2g.evcc.misc.EVCCImplementationFactory;
 import com.v2gclarity.risev2g.evcc.states.WaitForAuthorizationRes;
 import com.v2gclarity.risev2g.evcc.states.WaitForCableCheckRes;
 import com.v2gclarity.risev2g.evcc.states.WaitForCertificateInstallationRes;
@@ -137,7 +137,7 @@ public class V2GCommunicationSessionEVCC extends V2GCommunicationSession impleme
 		
 		// configure which EV controller implementation to use
 		// TODO the EV controller needs to run as a separate Thread (to receive notifications from the EV and to avoid blocking calls to the controller)
-		setEvController(new DummyEVController(this));
+		setEvController(EVCCImplementationFactory.createEVController(this));
 		
 		/*
 		 * Is needed for measuring the time span between transition to state B (plug-in) and receipt 

+ 9 - 0
RISE-V2G-SECC/SECCConfig.properties

@@ -76,6 +76,15 @@ authentication.modes.supported = Contract, ExternalPayment
 # - false
 environment.private = false
 
+#
+# Implementation classes
+#---------------------------------------------
+# If you want to replace the implementations the set the following attributes
+# to the name of your classes
+# When omitted default dummy implementations will be used
+implementation.secc.backend = com.v2gclarity.risev2g.secc.backend.DummyBackendInterface
+implementation.secc.acevsecontroller = com.v2gclarity.risev2g.secc.evseController.DummyACEVSEController
+implementation.secc.dcevsecontroller = com.v2gclarity.risev2g.secc.evseController.DummyDCEVSEController
 
 # XML representation of messages
 #-------------------------------

+ 84 - 0
RISE-V2G-SECC/src/main/java/com/v2gclarity/risev2g/secc/misc/SECCImplementationFactory.java

@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * The MIT License (MIT)
+ *
+ * Copyright 2017 Dr.-Ing. Marc Mültin (V2G Clarity)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *******************************************************************************/
+package com.v2gclarity.risev2g.secc.misc;
+
+import com.v2gclarity.risev2g.secc.backend.DummyBackendInterface;
+import com.v2gclarity.risev2g.secc.backend.IBackendInterface;
+import com.v2gclarity.risev2g.secc.evseController.DummyACEVSEController;
+import com.v2gclarity.risev2g.secc.evseController.DummyDCEVSEController;
+import com.v2gclarity.risev2g.secc.evseController.IACEVSEController;
+import com.v2gclarity.risev2g.secc.evseController.IDCEVSEController;
+import com.v2gclarity.risev2g.secc.session.V2GCommunicationSessionSECC;
+import com.v2gclarity.risev2g.shared.misc.V2GImplementationFactory;
+
+/**
+ * Implementation factory for the SECC controllers and for the backend interface
+ *
+ */
+public class SECCImplementationFactory extends V2GImplementationFactory {
+
+	
+	/**
+	 * Creates the backend interface for the SECC application
+	 * @param commSessionContext the session the backend will be connected to 
+	 * @return
+	 */
+	public static IBackendInterface createBackendInterface(V2GCommunicationSessionSECC commSessionContext) {
+		IBackendInterface instance = buildFromProperties("implementation.secc.backend", IBackendInterface.class, commSessionContext);
+		if (instance == null) {
+			return new DummyBackendInterface(commSessionContext);
+		} else {
+			return instance;
+		}
+	}
+	
+	/**
+	 * Creates the AC EVSE controller for the SECC application
+	 * @param commSessionContext the session the backend will be connected to 
+	 * @return
+	 */
+	public static IACEVSEController createACEVSEController(V2GCommunicationSessionSECC commSessionContext) {
+		IACEVSEController instance = buildFromProperties("implementation.secc.acevsecontroller", IACEVSEController.class, commSessionContext);
+		if (instance == null) {
+			return new DummyACEVSEController(commSessionContext);
+		} else {
+			return instance;
+		}
+	}
+	
+	/**
+	 * Creates the DC EVSE controller for the SECC application
+	 * @param commSessionContext the session the backend will be connected to 
+	 * @return
+	 */
+	public static IDCEVSEController createDCEVSEController(V2GCommunicationSessionSECC commSessionContext) {
+		IDCEVSEController instance = buildFromProperties("implementation.secc.dcevsecontroller", IDCEVSEController.class, commSessionContext);
+		if (instance == null) {
+			return new DummyDCEVSEController(commSessionContext);
+		} else {
+			return instance;
+		}
+	}
+	
+}

+ 4 - 6
RISE-V2G-SECC/src/main/java/com/v2gclarity/risev2g/secc/session/V2GCommunicationSessionSECC.java

@@ -29,13 +29,11 @@ import java.util.Arrays;
 import java.util.Observable;
 import java.util.Observer;
 
-import com.v2gclarity.risev2g.secc.backend.DummyBackendInterface;
 import com.v2gclarity.risev2g.secc.backend.IBackendInterface;
-import com.v2gclarity.risev2g.secc.evseController.DummyACEVSEController;
-import com.v2gclarity.risev2g.secc.evseController.DummyDCEVSEController;
 import com.v2gclarity.risev2g.secc.evseController.IACEVSEController;
 import com.v2gclarity.risev2g.secc.evseController.IDCEVSEController;
 import com.v2gclarity.risev2g.secc.evseController.IEVSEController;
+import com.v2gclarity.risev2g.secc.misc.SECCImplementationFactory;
 import com.v2gclarity.risev2g.secc.states.ForkState;
 import com.v2gclarity.risev2g.secc.states.WaitForAuthorizationReq;
 import com.v2gclarity.risev2g.secc.states.WaitForCableCheckReq;
@@ -133,11 +131,11 @@ public class V2GCommunicationSessionSECC extends V2GCommunicationSession impleme
 		setCurrentState(getStartState());
 		
 		// Configure which EVSE controller implementation to use
-		setACEvseController(new DummyACEVSEController(this));
-		setDCEvseController(new DummyDCEVSEController(this));
+		setACEvseController(SECCImplementationFactory.createACEVSEController(this));
+		setDCEvseController(SECCImplementationFactory.createDCEVSEController(this));
 		
 		// Configures which backend interface implementation to use for retrieving SASchedules
-		setBackendInterface(new DummyBackendInterface(this));
+		setBackendInterface(SECCImplementationFactory.createBackendInterface(this));
 
 		// ACEVSE notification
 		setAcEVSEStatus(new ACEVSEStatusType());

+ 73 - 0
RISE-V2G-Shared/src/main/java/com/v2gclarity/risev2g/shared/misc/V2GImplementationFactory.java

@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * The MIT License (MIT)
+ *
+ * Copyright 2017 Dr.-Ing. Marc Mültin (V2G Clarity)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *******************************************************************************/
+package com.v2gclarity.risev2g.shared.misc;
+
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+import com.v2gclarity.risev2g.shared.utils.MiscUtils;
+
+/**
+ * This class serves as the base for implementation factory
+ * classes used in the SE/EV projects
+ * It will look up and instantiate a class based on a
+ * configuration property
+ */
+abstract public class V2GImplementationFactory {
+
+	/**
+	 * Builds an object instance from the configuration properties
+	 * The configuration should hold the class of the instance that
+	 * will be built.
+	 * @param propertyName Name of the property the contains the fully qualified class name
+	 * @param cls Target class of the build instance
+	 * @param params Optional arguments to the constructor
+	 * @return
+	 */
+	protected static <T> T buildFromProperties(String propertyName, Class<T> cls, Object...params) {
+		try {
+			String className = MiscUtils.getV2gEntityConfig().getProperty(propertyName);
+			if (className == null) {
+				return null;
+			}
+			
+			Class<?> clazz = Class.forName(className);
+			
+			Class<?>[] paramClasses = Arrays.stream(params)
+					.map(param -> param.getClass())
+					.toArray(size -> new Class<?>[size]);
+			
+			Constructor<?> constructor = clazz.getConstructor(paramClasses);
+			Object instance = constructor.newInstance(params);
+			if (!cls.isInstance(instance)) {
+				throw new Exception("Instantiated object is not of excepted type");
+			}
+			return cls.cast(instance);
+		} catch (Exception e) {
+			throw new RuntimeException("Could not instantiate implementations class for property " + propertyName, e);
+		}
+	}
+
+	
+}