This commit is contained in:
2024-10-25 23:35:28 +02:00
parent 23ea8746b1
commit 0b33ac703d
16 changed files with 230 additions and 231 deletions

Binary file not shown.

13
V2/snippet API V2.txt Normal file
View File

@@ -0,0 +1,13 @@
/*
* Changes to the V1 API
*/
public Set<Part> getSelectedParts();
public Optional<Part> getSelectionForCategory(Category category);
and for Part.java :
public interface Part extends PropertyManager {
default String getName() {
return this.getClass().getTypeName();
};
Category getCategory();
PartType getType();
}

View File

@@ -0,0 +1,60 @@
/*
* Snippet to add a basic implementation of PropertyManager
*/
public class PartImpl implements Part {
private PartType type;
private class Property {
public final Supplier<String> getter;
public final Consumer<String> setter;
public final Set<String> possibleValues;
Property(Supplier<String> getter, Consumer<String> setter, Set<String> possibleValues) {
this.getter = getter;
this.setter = setter;
this.possibleValues = possibleValues;
}
}
private Map<String, Property> properties = new HashMap<>();
protected void addProperty(String name, Supplier<String> getter, Consumer<String> setter,
Set<String> possibleValues) {
properties.put(name, new Property(getter, setter, possibleValues));
}
@Override
public Set<String> getPropertyNames() {
return Collections.unmodifiableSet(properties.keySet());
}
@Override
public Optional<String> getProperty(String propertyName) {
Objects.requireNonNull(propertyName);
if (properties.containsKey(propertyName)) {
return Optional.of(properties.get(propertyName).getter.get());
}
return Optional.empty();
}
@Override
public void setProperty(String propertyName, String propertyValue) {
Objects.requireNonNull(propertyName);
Objects.requireNonNull(propertyValue);
if ((properties.containsKey(propertyName)) && (properties.get(propertyName).setter != null)) {
properties.get(propertyName).setter.accept(propertyValue);
} else {
throw new IllegalArgumentException("bad property name or value: " + propertyName);
}
}
@Override
public Set<String> getAvailablePropertyValues(String propertyName) {
if (properties.containsKey(propertyName)) {
return Collections.unmodifiableSet(properties.get(propertyName).possibleValues);
}
return Collections.emptySet();
}

View File

@@ -0,0 +1,24 @@
/*
* Snippet to add to your PartTypeImpl to support
* the V2 API
*/
public class PartTypeImpl implements PartType {
private String name;
private Class<? extends PartImpl> classRef;
private Category category;
public PartTypeImpl(String name, Class<? extends PartImpl> classRef, Category category) {
this.name = name;
this.classRef = classRef;
this.category = category;
}
public PartImpl newInstance() {
Constructor<? extends PartImpl> constructor;
try {
constructor = classRef.getConstructor();
return constructor.newInstance();
} catch (Exception e) {
Logger.getGlobal().log(Level.SEVERE, "constructor call failed", e);
System.exit(-1);
}
return null;
}

View File

@@ -5,10 +5,5 @@ package src.fr.api;
* A public type to organize part types in categories
*/
public interface Category {
/*
* return the name of the cathegory
* @return String, name of the cathegory, non null
*/
String getName();
}

View File

@@ -1,18 +1,6 @@
package src.fr.api;
import java.util.Set;
public interface CompatibilityChecker {
/*
* return the list of the incompatibles PartType of a PartType
* @param reference : the PartType that we want to see the incompatibilities,non null
* @return the Set list of the incompatibles PartType
*/
Set<PartType> getIncompatibilities(PartType reference);
/*
* return the list of the requirements PartType of a PartType
* @param reference : the PartType that we want to see the requirements,non null
* @return the Set list of the requirements PartType
*/
Set<PartType> getRequirements(PartType reference);
}

View File

@@ -1,34 +1,8 @@
package src.fr.api;
import java.util.Set;
public interface CompatibilityManager extends CompatibilityChecker {
/*
* add a incompatibles PartType to a PartType
* @param reference : the PartType that we wish to add incompatibilities
* @param target : Set list of incompatibilities PartType to add
*/
void addIncompatibilities(PartType reference,Set<PartType> target);
/*
* remove a PartType of the incompatibilities of a PartType, warning,
* warning : we must also remove the incompatibility from all the other PartTypes which the @param reference in their incompatibility
* @param reference : the PartType that we wish to remove a incompatible PartType
* @param target : PartType to remove of incompatibility
*/
void removeIncompatibility(PartType reference, PartType target);
/*
* add requirements PartType to a PartType
* @param reference : the PartType that we wish to add requirements
* @param target : Set list of requirement PartType to add
*/
void addRequirements(PartType reference, Set<PartType> target);
/*
* remove a PartType of the incompatibilities of a PartType
* @param reference : the PartType that we wish to remove a requirement PartType
* @param target : PartType to remove of requirement
*/
void removeRequirement(PartType reference, PartType target);
}

View File

@@ -1,18 +1,13 @@
package src.fr.api;
import java.util.Set;
import java.util.Optional;
public interface Configuration {
/*
* @return true if there is no compatibility issue between PartType else false
*/
boolean isValid();
boolean isComplete();
Set<PartType> getSelectedParts();
public Set<Part> getSelectedParts();
public Optional<Part> getSelectionForCategory(Category category);
void selectPart(PartType chosenPart);
PartType getSelectionForCategory(Category category);
void unselectPartType(Category categoryToClear);
void clear();
}

8
src/fr/api/Part.java Normal file
View File

@@ -0,0 +1,8 @@
package src.fr.api;
public interface Part extends PropertyManager {
default String getName() {
return this.getClass().getTypeName();
};
Category getCategory();
PartType getType();
}

View File

@@ -0,0 +1,42 @@
package src.fr.api;
import java.util.Set;
import java.util.Optional;
public interface PropertyManager {
/**
* Returns an immutable set of the property names supported by the property manager.
*
* @return
*/
public Set<String> getPropertyNames();
/**
* Returns the immutable set of discrete string values for a given property.
* For properties that have a non explicit set of possible values (eg double converted to strings),
* or for a non existing property name, returns an empty set.
*
* @param propertyName a non-null string reference
* @return an immutable set (see above)
*/
public Set<String> getAvailablePropertyValues(String propertyName);
/**
* Returns the optional value of a property.
* If the object does not support that property then an empty optional is returned.
* @param propertyName the property to read
* @return
*/
public Optional<String> getProperty(String propertyName);
/**
* Sets the value of a given property.
* If there is not such property, or if it not writable, or if the value is invalid
* then an IllegalArgumentException is thrown.
* @param propertyName
* @param propertyValue
* @throws IllegalArgumentException (see above)
*/
void setProperty(String propertyName, String propertyValue);
}

View File

@@ -1,27 +1,28 @@
package src.fr.impl;
//import java.util.HashMap;
import java.util.HashMap;
import java.util.Set;
import src.fr.api.PartType;
import src.fr.api.CompatibilityManager;
public class CompatibilityCheckerImpl implements src.fr.api.CompatibilityChecker {
private CompatibilityManager compatibilityManager;
public CompatibilityCheckerImpl( CompatibilityManager compatibilityManager){
this.compatibilityManager=compatibilityManager;
private HashMap<PartType, Set<PartType>> incompatibilities;
private HashMap<PartType, Set<PartType>> requirements;
public CompatibilityCheckerImpl( HashMap<PartType, Set<PartType>> incompatibilities, HashMap<PartType, Set<PartType>> requirements){
this.incompatibilities=incompatibilities;
this.requirements= requirements;
}
@Override
public Set<PartType> getIncompatibilities(PartType reference) {
return this.compatibilityManager.getIncompatibilities(reference);
return this.incompatibilities.get(reference);
}
@Override
public Set<PartType> getRequirements(PartType reference) {
return this.compatibilityManager.getRequirements(reference);
return this.requirements.get(reference);
}

View File

@@ -1,7 +1,6 @@
package src.fr.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import java.util.Objects;
@@ -29,7 +28,6 @@ public class CompatibilityManagerImpl implements src.fr.api.CompatibilityManager
if(incompa.isEmpty()){
incompatibilities.put(reference, target);
}else {
for(PartType x: target){
if (incompa.contains(x)){
@@ -41,12 +39,10 @@ public class CompatibilityManagerImpl implements src.fr.api.CompatibilityManager
//Ajout ref à x
incompa.add(x);
System.out.println("Add "+reference.getName() +" incompatible with "+x.getName());
this.incompatibilities.put(reference, incompa);
// Symétrie
//Ajoute x à ref
//this.getIncompatibilities(x).add(reference);
//System.out.println("Add "+x.getName() +" incompatible with "+reference.getName());
this.getIncompatibilities(x).add(reference);
System.out.println("Add "+x.getName() +" incompatible with "+reference.getName());
}
}
}
@@ -65,10 +61,8 @@ public class CompatibilityManagerImpl implements src.fr.api.CompatibilityManager
}else{
if(incompa.contains(target)){
incompa.remove(target);
this.incompatibilities.replace(reference, incompa);
// SyMéTrIe
//Remove target -> ref
//this.getIncompatibilities(target).remove(reference);
this.getIncompatibilities(target).remove(reference);
}else {
System.out.println("This part doesn't exist in incompatibilities list");
}
@@ -96,12 +90,10 @@ public class CompatibilityManagerImpl implements src.fr.api.CompatibilityManager
//Ajout ref à x
require.add(x);
System.out.println("Add "+reference.getName() +" compatible with "+x.getName());
this.requirements.put(reference, require);
//Symétrie
//Ajoute x à ref
//this.getRequirements(x).add(reference);
//System.out.println("Add "+x.getName() +" compatible with "+reference.getName());
this.getRequirements(x).add(reference);
System.out.println("Add "+x.getName() +" compatible with "+reference.getName());
}
}
}
@@ -121,85 +113,25 @@ public class CompatibilityManagerImpl implements src.fr.api.CompatibilityManager
}else{
if(require.contains(target)){
require.remove(target);
this.requirements.replace(reference, require);
// SyMéTrIe
//Remove target -> ref
//this.getRequirements(target).remove(reference);
this.getRequirements(target).remove(reference);
}else {
System.out.println("This part doesn't exist in compatibilities list");
}
}
}
// A -> B -> C -> A, D -> B
//erquirement only
private void Femeture_Transivite(PartType reference, Set<PartType> result, Set<PartType> visited, PartType start){
//Condition de quitter la boucle
if(visited.contains(reference)){
return;
}else {
visited.add(reference);
}
Set<PartType> list = null;
//Get all requirement of A (in example is B)
list = this.requirements.get(reference);
if(list != null){ // list = {B}
for(PartType pt: list){
if(!result.contains(pt)&& pt !=start){
result.add(pt);
}
Femeture_Transivite(pt,result,visited,reference);
}
}
}
@Override
public Set<PartType> getIncompatibilities(PartType reference) {
Set<PartType> result = new HashSet<>();
// Remove the case of result become null
Set<PartType> directIncompa = this.incompatibilities.get(reference);
if(directIncompa!=null){
result.addAll(directIncompa);
}
// Collect the requirements list
Set<PartType> requirements = new HashSet<>();
Femeture_Transivite(reference, requirements,new HashSet<>(),reference);
for(Map.Entry<PartType, Set<PartType>> entry : this.incompatibilities.entrySet()){
// check start
if(entry.getValue().contains(reference)){
result.add(entry.getKey());
}
// check incompatible of A's requirements
for(PartType pt: requirements){
// In Catalog of pt
if(entry.getValue().contains(pt)){
result.add(entry.getKey());
}
// Direct of pt
Set<PartType> direct_pt = this.incompatibilities.get(pt);
if(direct_pt!=null){
result.addAll(direct_pt);
}
}
}
return result;
// Il faut verifier ref est existé dans Hashmap
//return this.incompatibilities.get(reference);
return this.incompatibilities.getOrDefault(reference, new HashSet<PartType>());
}
@Override
public Set<PartType> getRequirements(PartType reference) {
Set<PartType> result = new HashSet<>();
Femeture_Transivite(reference, result,new HashSet<>(),reference);
return result;
//return this.requirements.get(reference);
return this.requirements.getOrDefault(reference, new HashSet<PartType>());
}
}

View File

@@ -3,6 +3,7 @@ package src.fr.impl;
import src.fr.api.Category;
import src.fr.api.PartType;
import src.fr.api.CompatibilityManager;
import src.fr.api.Part;
import java.util.Set;
@@ -41,7 +42,7 @@ public class ConfigurationImpl implements src.fr.api.Configuration {
}
@Override
public Set<PartType> getSelectedParts() {
public Set<Part> getSelectedParts() {
return selectedParts;
}

37
src/fr/impl/PartImpl.java Normal file
View File

@@ -0,0 +1,37 @@
package src.fr.impl;
import java.util.Optional;
import java.util.Set;
import src.fr.api.Category;
import src.fr.api.PartType;
public class PartImpl implements src.fr.api.Part {
private PartType type;
public Category getCategory(){
return this.type.getCategory();
}
public PartType getType(){
return this.type;
}
@Override
public Set<String> getPropertyNames() {
return null;
}
@Override
public Set<String> getAvailablePropertyValues(String propertyName) {
return null;
}
@Override
public Optional<String> getProperty(String propertyName) {
return null;
}
@Override
public void setProperty(String propertyName, String propertyValue) {
return;
};
}

View File

@@ -6,6 +6,9 @@ public class PartTypeImpl implements src.fr.api.PartType {
private String name;
private Category category;
//V2 implement
private Class<? extends PartImpl> classRef;
public PartTypeImpl(String name, Category category ) {
this.name = name;
this.category = category;

View File

@@ -44,13 +44,6 @@ public class test {
CompatibilityManager cm = new CompatibilityManagerImpl();
PartType[] list = {EG100,EG133,EG210,ED110,ED180,EH120,TM5,TM6,TA5,TS6,TSF7,TC120,XC,XM,XS,IN,IH,IS};
PartType[] listEn = {EG100,EG133,EG210,ED110,ED180,EH120};
PartType[] listTr = {TM5,TM6,TA5,TS6,TSF7,TC120};
PartType[] listEx = {XC,XM,XS};
PartType[] listIn = {IN,IH,IS};
@Before
public void init(){
@@ -96,15 +89,19 @@ public class test {
cm.addRequirements(XS, XSRequirement);
cm.addIncompatibilities(IS, ISIncompatibilities);
cm.addRequirements(IS, ISRequirement);
}
@Test
public void test_Incompatibilities_Simple_1(){
public void test_1_Incompatibilities_1(){
assertTrue(cm.getIncompatibilities(TA5).contains(EG100));
}
@Test
public void test_multiple_Incompatibilities_Simple_2(){
public void test_multiple_Incompatibilities_2(){
assertTrue(
cm.getIncompatibilities(TSF7).contains(EG100)&&
cm.getIncompatibilities(TSF7).contains(EG133)&&
@@ -113,51 +110,13 @@ public class test {
}
@Test
public void test_Requirements_3(){
public void test_1_Requirements_3(){
assertTrue(cm.getRequirements(EH120).contains(TC120));
}
/*
* A <-> B
* if A -> B then B -> A
*/
@Test
public void test_Incompatibilities_Complex_4(){
System.out.println("size EG100 incompatibilities : "+cm.getIncompatibilities(EG100).size());
assertTrue(cm.getIncompatibilities(EG100).contains(IS));
assertTrue(cm.getIncompatibilities(EG100).contains(XS));
}
/*
* if A require B
* then A is incompatible with all incompatible of B
*/
@Test
public void test_Require_Incompatibilities_Complex_5(){
assertTrue(cm.getIncompatibilities(XS).contains(EG100));
System.out.println("size XS incompatibilities : " + cm.getIncompatibilities(XS).size());
assertTrue(cm.getIncompatibilities(XS).contains(TM5));
}
/*
* Require Require Require
* if A -> B && B -> C then A -> C
*/
@Test
public void test_Incompatibilities_Complex_7(){
cm.addRequirements(TC120, Set.of(XC));
System.out.print(cm.getRequirements(TC120).size());
for(PartType p : cm.getRequirements(TC120)){
System.out.print(p.getName());
}
System.out.println("TC120 requirment size : " + cm.getRequirements(TC120).contains(XC));
assertTrue(cm.getRequirements(TC120).contains(XC));
assertTrue(cm.getRequirements(EH120).contains(XC));
cm.removeRequirement(TC120, XC);
public void test_Empty_Incompatibilities_4(){
assertTrue(cm.getIncompatibilities(EH120).isEmpty());
}
@Test
@@ -166,51 +125,18 @@ public class test {
}
@Test
public void test_Remove_and_restore_Incompatibilities_6(){
public void test_Remove(){
assertTrue(cm.getIncompatibilities(XM).contains(EG100));
cm.removeIncompatibility(XM, EG100);
assertFalse(cm.getIncompatibilities(XM).contains(EG100));
Set<PartType> setEG100 = new HashSet<PartType>();
setEG100.add(EG100);
cm.addIncompatibilities(XM, setEG100);
assertTrue(cm.getIncompatibilities(XM).contains(EG100));
}
cm.addIncompatibilities(EG100, setEG100);
System.out.println(cm.getIncompatibilities(XM) + "//////////");
//assertTrue(cm.getIncompatibilities(XM).contains(EG100));
@Test
public void test_Remove_Empty_7(){
//Wrong test
//assertTrue(cm.getIncompatibilities(EG100).isEmpty());
// je crois on a TA5, TSF7, XM, XS et IS, faut tester
cm.removeIncompatibility(EG100, EG100);
assertFalse(cm.getIncompatibilities(EG100).contains(EG100));
}
@Test
public void test_Remove_and_restore_Requirements_8(){
assertTrue(cm.getRequirements(EH120).contains(TC120));
cm.removeRequirement(EH120, TC120);
assertFalse(cm.getRequirements(EH120).contains(TC120));
Set<PartType> setTC120 = new HashSet<PartType>();
setTC120.add(TC120);
cm.addRequirements(EH120, setTC120);
assertTrue(cm.getRequirements(EH120).contains(TC120));
}
@Test
public void test_Add_and_restore_Incompatibilities_9(){
assertTrue(cm.getIncompatibilities(TSF7).contains(EG100));
assertTrue(cm.getIncompatibilities(TSF7).contains(EG133));
assertTrue(cm.getIncompatibilities(TSF7).contains(ED110));
cm.removeIncompatibility(TSF7, EG100);
assertFalse(cm.getIncompatibilities(TSF7).contains(EG100));
assertTrue(cm.getIncompatibilities(TSF7).contains(EG133));
assertTrue(cm.getIncompatibilities(TSF7).contains(ED110));
Set<PartType> setEG100 = new HashSet<PartType>();
setEG100.add(EG100);
cm.addIncompatibilities(TSF7, setEG100);
assertTrue(cm.getIncompatibilities(TSF7).contains(EG100));
assertTrue(cm.getIncompatibilities(TSF7).contains(EG133));
assertTrue(cm.getIncompatibilities(TSF7).contains(ED110));
}
}