-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTraitementBuilder.java
130 lines (114 loc) · 4.26 KB
/
TraitementBuilder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import java.lang.reflect.*;
import java.util.*;
/**
* TraitementBuilder
*
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
*/
public class TraitementBuilder {
/** Retourne un objet de type Class correspondant au nom en paramètre.
* Exemples :
* - int donne int.class
* - Normaliseur donne Normaliseur.class
*/
Class<?> analyserType(String nomType) throws ClassNotFoundException {
if (nomType.equals("int"))
return int.class;
else if (nomType.equals("double"))
return double.class;
return Class.forName(nomType);
}
/** Crée l'objet java qui correspond au type formel en exploitant le « mot » suivant du scanner.
* Exemple : si formel est int.class, le mot suivant doit être un entier et le résulat est l'entier correspondant.
* Ici, on peut se limiter aux types utlisés dans le projet : int, double et String.
*/
static Object decoderEffectif(Class<?> formel, Scanner in) {
// On utilise la locale US pour que les nombres décimaux utilisent des points et non des virgules
if (in.locale() != Locale.US) {
in.useLocale(Locale.US);
}
if (in.hasNextInt() && formel == int.class) {
return in.nextInt();
} else if (in.hasNextDouble() && formel == double.class) {
return in.nextDouble();
} else if (formel == String.class) {
return in.next();
}
// Type non identifié -> erreur
System.out.println("erreur: Type non identifié \"" + in.next() + "\"");
return null;
}
/** Définition de la signature, les paramètres formels, mais aussi les paramètres effectifs. */
static class Signature {
Class<?>[] formels;
Object[] effectifs;
public Signature(Class<?>[] formels, Object[] effectifs) {
this.formels = formels;
this.effectifs = effectifs;
}
}
/** Analyser une signature pour retrouver les paramètres formels et les paramètres effectifs.
* Exemple « 3 double 0.0 java.lang.String xyz int -5 » donne
* - [double.class, String.class, int.class] pour les paramètres formels et
* - [0.0, "xyz", -5] pour les paramètres effectifs.
*/
Signature analyserSignature(Scanner in) throws ClassNotFoundException {
int count = in.nextInt();
Class<?> type = null;
List<Class<?>> formels = new ArrayList<>();
List<Object> effectifs = new ArrayList<>();
while (count-- > 0) {
type = analyserType(in.next());
formels.add(type);
effectifs.add(decoderEffectif(type, in));
}
return new Signature(formels.toArray(new Class<?>[0]), effectifs.toArray());
}
/** Analyser la création d'un objet.
* Exemple : « Normaliseur 2 double 0.0 double 100.0 » consiste à charger
* la classe Normaliseur, trouver le constructeur qui prend 2 double, et
* l'appeler en lui fournissant 0.0 et 100.0 comme paramètres effectifs.
*/
Object analyserCreation(Scanner in) throws ClassNotFoundException, InvocationTargetException,
IllegalAccessException, NoSuchMethodException, InstantiationException
{
Class<?> formel = analyserType(in.next());
Signature sign = analyserSignature(in);
return formel.getConstructor(sign.formels).newInstance(sign.effectifs);
}
/** Analyser un traitement.
* Exemples :
* - « Somme 0 0 »
* - « SupprimerPlusGrand 1 double 99.99 0 »
* - « Somme 0 1 Max 0 0 »
* - « Somme 0 2 Max 0 0 SupprimerPlusGrand 1 double 20.0 0 »
* - « Somme 0 2 Max 0 0 SupprimerPlusGrand 1 double 20.0 1 Positions 0 0 »
* @param in le scanner à utiliser
* @param env l'environnement où enregistrer les nouveaux traitements
*/
Traitement analyserTraitement(Scanner in, Map<String, Traitement> env) throws ClassNotFoundException,
InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException,
CycleException
{
int nbNextTraits = 0;
Traitement result = (Traitement) analyserCreation(in);
nbNextTraits = in.nextInt();
while (nbNextTraits-- > 0) {
result.ajouterSuivants(analyserTraitement(in, env));
}
return (result);
}
/** Analyser un traitement.
* @param in le scanner à utiliser
* @param env l'environnement où enregistrer les nouveaux traitements
*/
public Traitement traitement(Scanner in, Map<String, Traitement> env)
{
try {
return analyserTraitement(in, env);
} catch (Exception e) {
throw new RuntimeException("Erreur sur l'analyse du traitement, "
+ "voir la cause ci-dessous", e);
}
}
}