Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
616ce6d
Improving column name validation
staudtMarius Nov 8, 2023
0263252
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Nov 8, 2023
065e15b
Some improvements.
staudtMarius Nov 13, 2023
651d9d1
fmt
staudtMarius Nov 13, 2023
fdbe8a8
Some small changes.
staudtMarius Nov 14, 2023
b9153fe
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Nov 16, 2023
c8dc981
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
sebastian-peter Nov 21, 2023
f5319cb
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Nov 24, 2023
ad379c2
Implementing requested changes.
staudtMarius Nov 24, 2023
7ae0a77
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Nov 27, 2023
9890512
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Nov 29, 2023
f37d7b6
Implementing requested changes.
staudtMarius Dec 5, 2023
ed659b4
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Dec 5, 2023
1bc5488
Some improvements.
staudtMarius Dec 5, 2023
f8783fa
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
staudtMarius Dec 14, 2023
3cc295c
Removed unused import
sebastian-peter Jan 4, 2024
779a60b
Merge branch 'dev' into ms/#849-column-name-validation-should-only-ru…
sebastian-peter Jan 4, 2024
1bdc06f
Adapted to changes in dev
sebastian-peter Jan 4, 2024
e50da82
Headline check is now obsolete
sebastian-peter Jan 4, 2024
d210341
Removing unnecessary parameters
sebastian-peter Jan 4, 2024
82249ef
Better JavaDoc
sebastian-peter Jan 4, 2024
cf15f4d
Additional test case
sebastian-peter Jan 4, 2024
18429bc
Renaming method, since "additional fields" already exist with a diffe…
sebastian-peter Jan 4, 2024
84695c8
found fields -> actual fields
sebastian-peter Jan 4, 2024
721bbad
Refactoring validation handling
sebastian-peter Jan 5, 2024
80104d0
Rolling back changes that will be fixed with #981
sebastian-peter Jan 5, 2024
e1d5e51
Removing unused methods from Try again
sebastian-peter Jan 5, 2024
13f034b
Fixing codacy issues
sebastian-peter Jan 5, 2024
440a426
Adapting documentation to changed spelling of cosPhiRated
sebastian-peter Jan 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
package edu.ie3.datamodel.exceptions;

/** Is thrown, when an something went wrong during entity creation process in a EntityFactory */
/** Is thrown, when something went wrong during entity creation process in a EntityFactory */
public class FactoryException extends RuntimeException {
public FactoryException(final String message, final Throwable cause) {
super(message, cause);
Expand Down
83 changes: 67 additions & 16 deletions src/main/java/edu/ie3/datamodel/io/factory/Factory.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
package edu.ie3.datamodel.io.factory;

import edu.ie3.datamodel.exceptions.FactoryException;
import edu.ie3.datamodel.io.source.SourceValidator;
import edu.ie3.datamodel.utils.Try;
import edu.ie3.datamodel.utils.Try.*;
import edu.ie3.util.StringUtils;
import java.util.*;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -23,7 +24,7 @@
* @param <R> Type of the intended return type (might differ slightly from target class (cf. {@link
* edu.ie3.datamodel.io.factory.timeseries.TimeBasedValueFactory})).
*/
public abstract class Factory<C, D extends FactoryData, R> {
public abstract class Factory<C, D extends FactoryData, R> implements SourceValidator {
public static final Logger log = LoggerFactory.getLogger(Factory.class);

private final List<Class<? extends C>> supportedClasses;
Expand All @@ -48,15 +49,10 @@ public List<Class<? extends C>> getSupportedClasses() {
public Try<R, FactoryException> get(D data) {
isSupportedClass(data.getTargetClass());

// magic: case-insensitive get/set calls on set strings
final List<Set<String>> allFields = getFields(data);

try {
validateParameters(data, allFields.toArray((IntFunction<Set<String>[]>) Set[]::new));

// build the model
return Success.of(buildModel(data));
} catch (FactoryException e) {
} catch (Exception e) {
return Failure.of(
new FactoryException(
"An error occurred when creating instance of "
Expand Down Expand Up @@ -108,10 +104,47 @@ private void isSupportedClass(Class<?> desiredClass) {
* Returns list of sets of attribute names that the entity requires to be built. At least one of
* these sets needs to be delivered for entity creation to be successful.
*
* @param data EntityData (or subclass) containing the data
* @return list of possible attribute sets
*/
protected abstract List<Set<String>> getFields(D data);
protected abstract List<Set<String>> getFields(Class<?> entityClass);

/**
* Method for validating the found fields.
*
* @param foundFields that were found
* @param entityClass of the build data
*/
public void validate(Set<String> foundFields, Class<?> entityClass) {
List<Set<String>> fieldSets =
getFields(entityClass).stream().map(Factory::toSnakeCase).toList();
Set<String> harmonizedFoundFields = toSnakeCase(foundFields);

// comparing the found fields to a list of possible fields (allows additional fields)
// if not all fields were found in a set, this set is filtered out
// all other fields are saved as a list
// allows snake, camel and mixed cases
List<Set<String>> validFieldSets =
fieldSets.stream()
.filter(s -> foundFields.containsAll(s) || harmonizedFoundFields.containsAll(s))
.toList();

if (validFieldSets.isEmpty()) {
// build the exception string with extensive debug information
String providedKeysString = "[" + String.join(", ", foundFields) + "]";

String possibleOptions = getFieldsString(fieldSets).toString();

throw new FactoryException(
"The provided fields "
+ providedKeysString
+ " are invalid for instance of "
+ entityClass.getSimpleName()
+ ". \nThe following fields (without complex objects e.g. nodes, operators, ...) to be passed to a constructor of '"
+ entityClass.getSimpleName()
+ "' are possible (NOT case-sensitive!):\n"
+ possibleOptions);
}
}

/**
* Validates the factory specific constructor parameters in two ways. 1) the biggest set of the
Expand Down Expand Up @@ -148,7 +181,7 @@ protected int validateParameters(D data, Set<String>... fieldSets) {

String providedKeysString = "[" + String.join(", ", fieldsToValues.keySet()) + "]";

String possibleOptions = getFieldsString(fieldSets).toString();
String possibleOptions = getFieldsString(List.of(fieldSets)).toString();

throw new FactoryException(
"The provided fields "
Expand All @@ -165,19 +198,25 @@ protected int validateParameters(D data, Set<String>... fieldSets) {
}
}

protected static StringBuilder getFieldsString(Set<String>... fieldSets) {
protected static StringBuilder getFieldsString(List<Set<String>> fieldSets) {
StringBuilder possibleOptions = new StringBuilder();
for (int i = 0; i < fieldSets.length; i++) {
Set<String> fieldSet = fieldSets[i];
String option = i + ": [" + String.join(", ", fieldSet) + "]\n";
for (int i = 0; i < fieldSets.size(); i++) {
Set<String> fieldSet = fieldSets.get(i);
String option =
i
+ ": ["
+ String.join(", ", fieldSet)
+ "] or ["
+ String.join(", ", toCamelCase(fieldSet))
+ "]\n";
possibleOptions.append(option);
}
return possibleOptions;
}

/**
* Creates a new set of attribute names from given list of attributes. This method should always
* be used when returning attribute sets, i.e. through {@link #getFields(FactoryData)}.
* be used when returning attribute sets, i.e. through {@link #getFields(Class)}.
*
* @param attributes attribute names
* @return new set exactly containing attribute names
Expand All @@ -203,4 +242,16 @@ protected TreeSet<String> expandSet(Set<String> attributeSet, String... more) {
newSet.addAll(Arrays.asList(more));
return newSet;
}

private static Set<String> toSnakeCase(Set<String> set) {
TreeSet<String> newSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
newSet.addAll(set.stream().map(StringUtils::camelCaseToSnakeCase).toList());
return newSet;
}

private static Set<String> toCamelCase(Set<String> set) {
TreeSet<String> newSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
newSet.addAll(set.stream().map(StringUtils::snakeCaseToCamelCase).toList());
return newSet;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public abstract class AssetInputEntityFactory<T extends AssetInput, D extends As
extends EntityFactory<T, D> {

private static final String UUID = "uuid";
private static final String OPERATES_FROM = "operatesfrom";
private static final String OPERATES_UNTIL = "operatesuntil";
private static final String OPERATES_FROM = "operatesFrom";
private static final String OPERATES_UNTIL = "operatesUntil";
private static final String ID = "id";

protected AssetInputEntityFactory(Class<? extends T>... allowedClasses) {
Expand All @@ -39,11 +39,11 @@ protected AssetInputEntityFactory(Class<? extends T>... allowedClasses) {
* <p>The mandatory attributes required to create an {@link AssetInput} are enhanced with custom
* attribute names that each subclass factory determines in {@link #getAdditionalFields()}.
*
* @param data EntityData (or subclass) containing the data
* @param entityClass class of the entity
* @return list of possible attribute sets
*/
@Override
protected List<Set<String>> getFields(D data) {
protected List<Set<String>> getFields(Class<?> entityClass) {
Set<String> constructorParamsMin = newSet(UUID, ID);
Set<String> constructorParamsFrom = expandSet(constructorParamsMin, OPERATES_FROM);
Set<String> constructorParamsUntil = expandSet(constructorParamsMin, OPERATES_UNTIL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ abstract class ConnectorInputEntityFactory<
* ConnectorInput}s. Thus, this attribute name declaration can be used in subclasses of {@link
* ConnectorInputEntityFactory}
*/
protected static final String PARALLEL_DEVICES = "paralleldevices";
protected static final String PARALLEL_DEVICES = "parallelDevices";

protected ConnectorInputEntityFactory(Class<? extends T>... allowedClasses) {
super(allowedClasses);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

public class CylindricalStorageInputFactory
extends AssetInputEntityFactory<CylindricalStorageInput, ThermalUnitInputEntityData> {
private static final String STORAGE_VOLUME_LVL = "storagevolumelvl";
private static final String STORAGE_VOLUME_LVL_MIN = "storagevolumelvlmin";
private static final String INLET_TEMP = "inlettemp";
private static final String RETURN_TEMP = "returntemp";
private static final String STORAGE_VOLUME_LVL = "storageVolumeLvl";
private static final String STORAGE_VOLUME_LVL_MIN = "storageVolumeLvlMin";
private static final String INLET_TEMP = "inletTemp";
private static final String RETURN_TEMP = "returnTemp";
private static final String C = "c";

public CylindricalStorageInputFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
public class LineInputFactory
extends ConnectorInputEntityFactory<LineInput, TypedConnectorInputEntityData<LineTypeInput>> {
private static final String LENGTH = "length";
private static final String GEO_POSITION = "geoposition";
private static final String OLM_CHARACTERISTIC = "olmcharacteristic";
private static final String GEO_POSITION = "geoPosition";
private static final String OLM_CHARACTERISTIC = "olmCharacteristic";

public LineInputFactory() {
super(LineInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

public class MeasurementUnitInputFactory
extends AssetInputEntityFactory<MeasurementUnitInput, NodeAssetInputEntityData> {
private static final String V_MAG = "vmag";
private static final String V_ANG = "vang";
private static final String V_MAG = "vMag";
private static final String V_ANG = "vAng";
private static final String P = "p";
private static final String Q = "q";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
import tech.units.indriya.ComparableQuantity;

public class NodeInputFactory extends AssetInputEntityFactory<NodeInput, AssetInputEntityData> {
private static final String V_TARGET = "vtarget";
private static final String V_TARGET = "vTarget";
public static final String V_RATED = "vRated";
private static final String SLACK = "slack";
private static final String GEO_POSITION = "geoposition";
private static final String GEO_POSITION = "geoPosition";
public static final String VOLT_LVL = "voltLvl";
private static final String SUBNET = "subnet";

Expand All @@ -29,9 +29,7 @@ public NodeInputFactory() {

@Override
protected String[] getAdditionalFields() {
return new String[] {
V_TARGET, V_RATED.toLowerCase(), SLACK, GEO_POSITION, VOLT_LVL.toLowerCase(), SUBNET
};
return new String[] {V_TARGET, V_RATED, SLACK, GEO_POSITION, VOLT_LVL, SUBNET};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public OperatorInputFactory() {
}

@Override
protected List<Set<String>> getFields(SimpleEntityData data) {
protected List<Set<String>> getFields(Class<?> entityClass) {
Set<String> constructorParams = newSet(ENTITY_UUID, ENTITY_ID);
return Collections.singletonList(constructorParams);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

public class ThermalHouseInputFactory
extends AssetInputEntityFactory<ThermalHouseInput, ThermalUnitInputEntityData> {
private static final String ETH_LOSSES = "ethlosses";
private static final String ETH_CAPA = "ethcapa";
private static final String ETH_LOSSES = "ethLosses";
private static final String ETH_CAPA = "ethCapa";
private static final String TARGET_TEMPERATURE = "targetTemperature";
private static final String UPPER_TEMPERATURE_LIMIT = "upperTemperatureLimit";
private static final String LOWER_TEMPERATURE_LIMIT = "lowerTemperatureLimit";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public class Transformer2WInputFactory
extends ConnectorInputEntityFactory<
Transformer2WInput, TypedConnectorInputEntityData<Transformer2WTypeInput>> {

private static final String TAP_POS = "tappos";
private static final String AUTO_TAP = "autotap";
private static final String TAP_POS = "tapPos";
private static final String AUTO_TAP = "autoTap";

public Transformer2WInputFactory() {
super(Transformer2WInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
public class Transformer3WInputFactory
extends ConnectorInputEntityFactory<Transformer3WInput, Transformer3WInputEntityData> {

private static final String TAP_POS = "tappos";
private static final String AUTO_TAP = "autotap";
private static final String TAP_POS = "tapPos";
private static final String AUTO_TAP = "autoTap";

public Transformer3WInputFactory() {
super(Transformer3WInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public abstract class GraphicInputFactory<T extends GraphicInput, D extends Enti
extends EntityFactory<T, D> {

private static final String UUID = "uuid";
private static final String GRAPHIC_LAYER = "graphiclayer";
private static final String GRAPHIC_LAYER = "graphicLayer";
private static final String PATH_LINE_STRING = "path";

protected GraphicInputFactory(Class<? extends T>... allowedClasses) {
Expand All @@ -36,11 +36,11 @@ protected GraphicInputFactory(Class<? extends T>... allowedClasses) {
* <p>The mandatory attributes required to create an {@link GraphicInput} are enhanced with custom
* attribute names that each subclass factory determines in {@link #getAdditionalFields()}.
*
* @param data EntityData (or subclass) containing the data
* @param entityClass class of the entity
* @return list of possible attribute sets
*/
@Override
protected List<Set<String>> getFields(D data) {
protected List<Set<String>> getFields(Class<?> entityClass) {
Set<String> constructorParamsMin = newSet(UUID, GRAPHIC_LAYER, PATH_LINE_STRING);
final String[] additionalFields = getAdditionalFields();
constructorParamsMin = expandSet(constructorParamsMin, additionalFields);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
public class BmInputFactory
extends SystemParticipantInputEntityFactory<
BmInput, SystemParticipantTypedEntityData<BmTypeInput>> {
private static final String MARKET_REACTION = "marketreaction";
private static final String COST_CONTROLLED = "costcontrolled";
private static final String FEED_IN_TARIFF = "feedintariff";
private static final String MARKET_REACTION = "marketReaction";
private static final String COST_CONTROLLED = "costControlled";
private static final String FEED_IN_TARIFF = "feedInTariff";

public BmInputFactory() {
super(BmInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

public class ChpInputFactory
extends SystemParticipantInputEntityFactory<ChpInput, ChpInputEntityData> {
private static final String MARKET_REACTION = "marketreaction";
private static final String MARKET_REACTION = "marketReaction";

public ChpInputFactory() {
super(ChpInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public class EmInputFactory
extends SystemParticipantInputEntityFactory<EmInput, NodeAssetInputEntityData> {
private static final Logger logger = LoggerFactory.getLogger(EmInputFactory.class);

private static final String CONNECTED_ASSETS = "connectedassets";
private static final String CONNECTED_ASSETS = "connectedAssets";

private static final String CONTROL_STRATEGY = "controlstrategy";
private static final String CONTROL_STRATEGY = "controlStrategy";

public EmInputFactory() {
super(EmInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public class EvcsInputFactory
extends SystemParticipantInputEntityFactory<EvcsInput, NodeAssetInputEntityData> {

private static final String TYPE = "type";
private static final String CHARGING_POINTS = "chargingpoints";
private static final String COS_PHI_RATED = "cosphirated";
private static final String LOCATION_TYPE = "locationtype";
private static final String V2G_SUPPORT = "v2gsupport";
private static final String CHARGING_POINTS = "chargingPoints";
private static final String COS_PHI_RATED = "cosPhiRated";
private static final String LOCATION_TYPE = "locationType";
private static final String V2G_SUPPORT = "v2gSupport";

public EvcsInputFactory() {
super(EvcsInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
public class FixedFeedInInputFactory
extends SystemParticipantInputEntityFactory<FixedFeedInInput, NodeAssetInputEntityData> {

private static final String S_RATED = "srated";
private static final String COSPHI_RATED = "cosphirated";
private static final String S_RATED = "sRated";
private static final String COSPHI_RATED = "cosPhiRated";

public FixedFeedInInputFactory() {
super(FixedFeedInInput.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ public class LoadInputFactory
extends SystemParticipantInputEntityFactory<LoadInput, NodeAssetInputEntityData> {
private static final Logger logger = LoggerFactory.getLogger(LoadInputFactory.class);

private static final String LOAD_PROFILE = "loadprofile";
private static final String LOAD_PROFILE = "loadProfile";
private static final String DSM = "dsm";
private static final String E_CONS_ANNUAL = "econsannual";
private static final String S_RATED = "srated";
private static final String COS_PHI = "cosphirated";
private static final String E_CONS_ANNUAL = "eConsAnnual";
private static final String S_RATED = "sRated";
private static final String COS_PHI = "cosPhiRated";

public LoadInputFactory() {
super(LoadInput.class);
Expand Down
Loading