content.txt
5.63 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
!1 Création d'un nouveau type d'output
!2 Objectif
L'objectif de cette page est de créer un nouveau type de sortie.
Cela permettra de gérer un fichier xml décrivant une requête contenant une balise output du type
{{{
<outputs>
<OutputName>
<param id="density_boxcar" />
...
</OutputName>
</outputs>
}}}
!2 Procédure
* Il faut créer un plugin [[cf. AMDA plugin][.HelpDev.AmdaPlugin]] enregistrant le nouveau '''Output''' *
* Il faut créer au moins une class dérivant de '''!-AMDA::Parameters::ParamOutput-!'''.
* Il faut créer une classe dérivant de '''!-AMDA::XMLConfigurator::NodeGrpCfg-!'''.
* Il faut mettre à jour les schémas XSD permettant de valider les fichier XML de requête
!2 Exemple:
!3 Création d'une nouvelle sortie: '''intervalTrue'''
Cette sortie écrit toutes les valeurs d'un paramètre sur une ligne.
Le fichier xml de requête contiendra la balise output suivante (pamarmName)
{{{
<outputs>
<intervalTrue>
<param id="pamarmName" />
</intervalTrue>
</outputs>
}}}
!4 1 - Suivre la procédure de création de plugin
[[cf. AMDA plugin][.HelpDev.AmdaPlugin]]
!5 La fonction registerPlugin doit contenir les lignes suivantes:
{{{
extern "C" void registerPlugin(AMDA::Plugins::PluginManager & pm) {
AMDA::XMLRequest::XMLRequestParser* lXMLRequestParser = ServicesServer::getInstance()->getService<AMDA::XMLRequest::XMLRequestParser*>();
if (lXMLRequestParser) {
XMLRequestParser->addNodeParser("request/outputs/IntervalTrue",AMDA::XMLConfigurator::NodeCfgSPtr(new OutputIntervalTrueNode));
}
}
}}}
!4 2 - Créer la classe !-OutputIntervalTrueNode-!
Il faut dériver de '''!-AMDA::XMLConfigurator::NodeGrpCfg-!''' et implémenter la méthode:
* !-void process()-! : permet de lire le nœud intervalTrue du fichier de requête.
Ce nœud comporte seulement un noeud param (qui est le paramètre qui sera affiché), il peut en comporter d'autre si besoin.
{{{
OutputIntervalTrueNode::OutputIntervalTrueNode() : NodeGrpCfg() {
getChildList()["param"]=NodeCfgSPtr(new ParamNode<ParamOutputIntervalTrueFile>());
}
void OutputIntervalTrueNode::proceed(xmlNodePtr pNode,
const AMDA::Parameters::CfgContext& pContext) {
LOG4CXX_DEBUG(gLogger,
"OutputIntervalTrueNode::proceed: '" << pNode->name << "' node")
ParameterManager* lParameterManager = pContext.get<ParameterManager*>();
CfgContext lContext;
ParamOutput* lParamOutputIntervalTrueFile = new ParamOutputIntervalTrueFile(
*lParameterManager);
ParamOutputSPtr lParamOutput(lParamOutputIntervalTrueFile);
lContext.push<ParamOutputIntervalTrueFile*>(dynamic_cast<ParamOutputIntervalTrueFile *>(lParamOutputIntervalTrueFile));
NodeGrpCfg::proceed(pNode, lContext);
lParameterManager->getParamOutputList().push_back(lParamOutput);
}
}}}
!4 3 - Créer la classe !-ParamOutputIntervalTrueFile-!
Il faut dériver de '''!-AMDA::Parameters::ParamOutput-!''' et implémenter au minimum les méthodes:
* '''!-void apply()-!''' : permet de générer la sortie, c'est le cœur du métier d'output, get data avec _parameter->getAsync()
et utilise le design pattern visiteur pour lire les valeur du paramètre.
{{{
void ParamOutputIntervalTrueFile::apply() {
_paramDataIndexInfo = _parameter->getAsync(this).get();
initOutput(); //create file
_printIntervalTrueVisitor->setParamDataIndexInfo(_paramDataIndexInfo);
while ( _paramDataIndexInfo._nbDataToProcess > 0) {
try {
_parameter->getParamData(this)->accept(*_printIntervalTrueVisitor); //visitor pattern
_paramDataIndexInfo = _parameter->getAsync(this).get();
_printIntervalTrueVisitor->setParamDataIndexInfo(_paramDataIndexInfo);
} catch(AMDA::AMDA_exception & e) {
e << AMDA::errno_code(AMDA_PARAM_OUTPUT_ERR);
throw;
}
}
endOutput(); //close file
}
}}}
* '''!-void init()-!''' : permet d'initialiser les paramètres à traiter
{{{
void ParamOutputIntervalTrueFile::init() {
getParameter()->init(this,getStartTime(),getTimeInt());
}
}}}
* '''!-void DataClient::establishConnection()-!''' : permet de calculer des informations static (comme parser la formule de process) et doit ouvrir les connections avec son _parameterInput
{{{
void ParamOutputIntervalTrueFile::establishConnection() {
_parameter = _parameterManager.getSampledParameter(_paramName, _samplingMode, _samplingValue, _gabsThreshold).get();
if(_parameter == NULL) {
LOG4CXX_ERROR(_logger,"ParamOutput::init parameter : \""<< _paramName <<"\" Not Exist" );
BOOST_THROW_EXCEPTION( ParamOutput_exception());
}
getParameter()->openConnection(this);
}
}}}
* '''!-double DataClient::timeOfDataPreserve()-!''' : doit retourner l’intervalle temps nécessaire pour assurer l'intégrité des calculs, ici la taille du boxcar: 1200
!4 4 - Mettre à jour le XSD
* Modifier le fichier request/all.xsd:
Y ajouter une ligne du type: !- <xs:include schemaLocation="intervalTrue.xsd" />-!
* Créer un fichier intervalTrue.xsd (voir nom du fichier référencer dans la ligne ajouté au fichier all.xsd)
{{{
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="request.xsd" />
<xs:element name="intervalTrue" substitutionGroup="OutputElement" >
<xs:complexType>
<xs:sequence>
<xs:element name="param" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="index" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="calibration_info" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
}}}
!contents -R2 -g -p -f -h