Skip to content
Snippets Groups Projects
Commit b67cce1d authored by Dominique Marcadet's avatar Dominique Marcadet
Browse files

validation of DataTypeTemplate (first version)

parent dda8b215
No related branches found
No related tags found
1 merge request!11Resolve "complete validation by NSD"
/**
* Copyright (c) 2019 CentraleSupélec & EDF.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* This file is part of the RiseClipse tool
*
* Contributors:
* Computer Science Department, CentraleSupélec
* EDF R&D
* Contacts:
* dominique.marcadet@centralesupelec.fr
* aurelie.dehouck-neveu@edf.fr
* Web site:
* http://wdi.supelec.fr/software/RiseClipse/
*/
package fr.centralesupelec.edf.riseclipse.iec61850.scl.validator.nsd;
import java.util.HashMap;
import java.util.HashSet;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.CDC;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.DataAttribute;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.DA;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.DO;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.validator.RiseClipseValidatorSCL;
import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole;
public class DOValidator {
private String cdc;
private HashMap< String, DataAttribute > daMap;
public DOValidator( CDC cdc ) {
this.cdc = cdc.getName();
this.daMap = new HashMap<>(); // link between DAI (name) and its respective DataAttribute
for( DataAttribute da : cdc.getDataAttribute() ) {
this.daMap.put( da.getName(), da );
}
}
public boolean validateDO( DO do_, DiagnosticChain diagnostics ) {
AbstractRiseClipseConsole.getConsole().verbose( "validateDO( " + do_.getName() + " )" );
boolean res = true;
HashSet< String > checkedDA = new HashSet<>();
if( do_.getRefersToDOType() == null ) {
AbstractRiseClipseConsole.getConsole().warning( "validateDO: DO " + do_.getName() + " has no RefersToDOType" );
}
else {
for( DA da : do_.getRefersToDOType().getDA() ) {
AbstractRiseClipseConsole.getConsole().verbose( "validateDO on DA " + da.getName() + " (line" + da.getLineNumber() + ")" );
// Test if DA is a possible DA in this DO
if( ! daMap.containsKey( da.getName() ) ) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DA " + da.getName() + " (line" + da.getLineNumber() + ") not found in CDC",
new Object[] { do_, cdc } ));
res = false;
continue;
}
// Control of DAI presence in DO
updateCompulsory( da, checkedDA, diagnostics );
}
}
// Verify all necessary DA were present
if( ! daMap.values().stream()
.map( x -> checkCompulsory( do_, x, checkedDA, diagnostics ) )
.reduce( ( a, b ) -> a && b ).get() ) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DO (line " + do_.getLineNumber() + ") does not contain all mandatory DA from CDC ",
new Object[] { do_, cdc } ));
res = false;
}
return res;
}
public boolean checkCompulsory( DO do_, DataAttribute da, HashSet< String > checked, DiagnosticChain diagnostics ) {
switch( da.getPresCond() ) {
case "M":
if( ! checked.contains( da.getName() )) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DA " + da.getName() + " not found in DO (line " + do_.getLineNumber() + ")",
new Object[] { da } ));
return false;
}
break;
default:
AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: DOValidator.checkCompulsory( " + da.getPresCond() + " )" );
break;
}
return true;
}
public boolean updateCompulsory( DA da, HashSet< String > checked, DiagnosticChain diagnostics ) {
switch( daMap.get( da.getName() ).getPresCond() ) {
case "M":
case "O":
if( checked.contains( da.getName() ) ) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DA " + da.getName() + " (line " + da.getLineNumber() + ") cannot appear more than once",
new Object[] { da } ));
return false;
}
else {
checked.add( da.getName() );
break;
}
case "F":
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DA " + da.getName() + " (line " + da.getLineNumber() + ") is forbidden",
new Object[] { da } ));
return false;
default:
AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: DOIValidator.updateCompulsory( " + daMap.get( da.getName() ).getPresCond() + " )" );
break;
}
return true;
}
}
/**
* Copyright (c) 2019 CentraleSupélec & EDF.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* This file is part of the RiseClipse tool
*
* Contributors:
* Computer Science Department, CentraleSupélec
* EDF R&D
* Contacts:
* dominique.marcadet@centralesupelec.fr
* aurelie.dehouck-neveu@edf.fr
* Web site:
* http://wdi.supelec.fr/software/RiseClipse/
*/
package fr.centralesupelec.edf.riseclipse.iec61850.scl.validator.nsd;
import java.util.HashMap;
import java.util.HashSet;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.AbstractLNClass;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.DataObject;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.LNClass;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.AnyLNClass;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.DO;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.LNodeType;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.validator.RiseClipseValidatorSCL;
import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole;
public class LNodeTypeValidator {
private String lnClass;
private HashMap< String, DataObject > doMap;
private HashMap< String, DOValidator > cdcMap;
public LNodeTypeValidator( LNClass lnClass ) {
this.lnClass = lnClass.getName();
this.doMap = new HashMap<>(); // link between DOI (name) and its respective DataObject
this.cdcMap = new HashMap<>(); // link between CDC (name) and its respective DOIValidator
generateValidators( doMap, cdcMap, lnClass );
// LNClass hierarchy taken into account
AbstractLNClass parent = lnClass.getRefersToAbstractLNClass();
while( parent != null ) {
generateValidators( doMap, cdcMap, parent );
parent = parent.getRefersToAbstractLNClass();
}
}
private void generateValidators( HashMap< String, DataObject > doMap, HashMap< String, DOValidator > cdcMap, AnyLNClass lnClass ) {
for( DataObject dObj : lnClass.getDataObject() ) {
doMap.put( dObj.getName(), dObj );
if( dObj.getRefersToCDC() != null ) {
if( ! cdcMap.containsKey( dObj.getRefersToCDC().getName() )) {
cdcMap.put( dObj.getRefersToCDC().getName(), new DOValidator( dObj.getRefersToCDC() ));
}
}
}
}
public boolean validateLNodeType( LNodeType lNodeType, DiagnosticChain diagnostics ) {
boolean res = true;
HashSet< String > checkedDO = new HashSet<>();
for( DO do_ : lNodeType.getDO() ) {
AbstractRiseClipseConsole.getConsole().verbose( "validateDOI( " + do_.getName() + " )" );
// Test if DOI is a possible DOI in this LN
if( ! doMap.containsKey( do_.getName() ) ) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DO " + do_.getName() + " in LN at line " + lNodeType.getLineNumber() + " not found in LNClass " + lNodeType.getLnClass(),
new Object[] { lNodeType } ));
continue;
}
// Control of DOI presence in LN
updateCompulsory( do_, checkedDO, diagnostics );
// Validation of DOI content
if( ! validateDO( do_, diagnostics ) ) {
res = false;
}
}
// Verify all necessary DOI were present
if( ! doMap.values().stream()
.map( x -> checkCompulsory( lNodeType, x, checkedDO, diagnostics ))
.reduce( ( a, b ) -> a && b ).get() ) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"LNodeType at line " + lNodeType.getLineNumber() + " does not contain all mandatory DO from class " + lNodeType.getLnClass(),
new Object[] { lNodeType } ));
res = false;
}
return res;
}
private boolean checkCompulsory( LNodeType lNodeType, DataObject dataObject, HashSet< String > checkedDO, DiagnosticChain diagnostics ) {
switch( dataObject.getPresCond() ) {
case "M":
if( ! checkedDO.contains( dataObject.getName() ) ) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DO " + dataObject.getName() + " is missing in LN at line " + lNodeType.getLineNumber(),
new Object[] { lNodeType } ));
return false;
}
break;
default:
AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: AnyLNValidator.checkCompulsory( " + dataObject.getPresCond() + " )" );
break;
}
return true;
}
private boolean updateCompulsory( DO do_, HashSet< String > checkedDO, DiagnosticChain diagnostics ) {
switch( doMap.get( do_.getName() ).getPresCond() ) {
case "M":
case "O":
if( checkedDO.contains( do_.getName() )) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DO " + do_ + " cannot appear more than once in LN at line " + do_.getParentLNodeType().getLineNumber(),
new Object[] { do_ } ));
return false;
}
checkedDO.add( do_.getName() );
break;
case "F":
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"DO " + do_ + " is forbidden in LN at line " + do_.getParentLNodeType().getLineNumber(),
new Object[] { do_ } ));
return false;
default:
AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: AnyLNValidator.updateCompulsory( " + doMap.get( do_.getName() ).getPresCond() + " )" );
break;
}
return true;
}
private boolean validateDO( DO do_, DiagnosticChain diagnostics ) {
AbstractRiseClipseConsole.getConsole().verbose( "found DO " + do_.getName() + " in LNClass " + lnClass );
// DOIValidator validates DOI content
String cdc = doMap.get( do_.getName() ).getRefersToCDC().getName();
return cdcMap.get( cdc ).validateDO( do_, diagnostics );
}
}
...@@ -31,33 +31,49 @@ import org.eclipse.emf.ecore.EValidator; ...@@ -31,33 +31,49 @@ import org.eclipse.emf.ecore.EValidator;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.LNClass; import fr.centralesupelec.edf.riseclipse.iec61850.nsd.LNClass;
import fr.centralesupelec.edf.riseclipse.iec61850.nsd.util.NsdResourceSetImpl; import fr.centralesupelec.edf.riseclipse.iec61850.nsd.util.NsdResourceSetImpl;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.AnyLN; import fr.centralesupelec.edf.riseclipse.iec61850.scl.AnyLN;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.LNodeType;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.util.SclSwitch;
import fr.centralesupelec.edf.riseclipse.iec61850.scl.validator.RiseClipseValidatorSCL; import fr.centralesupelec.edf.riseclipse.iec61850.scl.validator.RiseClipseValidatorSCL;
import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole; import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole;
public class NsdEObjectValidator implements EValidator { public class NsdEObjectValidator implements EValidator {
private NsdResourceSetImpl nsdResourceSet; private NsdResourceSetImpl nsdResourceSet;
private HashMap< String, AnyLNValidator > lnMap; private HashMap< String, AnyLNValidator > anyLNValidatorMap;
private HashMap<String,LNodeTypeValidator> lNodeTypeValidatorMap;
public NsdEObjectValidator( NsdResourceSetImpl nsdResourceSet ) { public NsdEObjectValidator( NsdResourceSetImpl nsdResourceSet ) {
this.nsdResourceSet = nsdResourceSet; this.nsdResourceSet = nsdResourceSet;
} }
public void initializeValidationData() { public void initializeValidationData() {
this.lnMap = this.nsdResourceSet.getLNClassStream() this.anyLNValidatorMap = this.nsdResourceSet.getLNClassStream()
.map( lnClass -> generateValidators( lnClass ) ) .map( lnClass -> generateAnyLNValidators( lnClass ) )
.reduce( ( a, b ) -> {
a.putAll( b );
return a;
} ).get();
this.lNodeTypeValidatorMap = this.nsdResourceSet.getLNClassStream()
.map( lnClass -> generateLNodeTypeValidators( lnClass ) )
.reduce( ( a, b ) -> { .reduce( ( a, b ) -> {
a.putAll( b ); a.putAll( b );
return a; return a;
} ).get(); } ).get();
} }
private HashMap< String, AnyLNValidator > generateValidators( LNClass lnClass ) { private HashMap< String, AnyLNValidator > generateAnyLNValidators( LNClass lnClass ) {
HashMap< String, AnyLNValidator > lnMap = new HashMap<>(); HashMap< String, AnyLNValidator > lnMap = new HashMap<>();
lnMap.put( lnClass.getName(), new AnyLNValidator( lnClass )); lnMap.put( lnClass.getName(), new AnyLNValidator( lnClass ));
return lnMap; return lnMap;
} }
private HashMap< String, LNodeTypeValidator > generateLNodeTypeValidators( LNClass lnClass ) {
HashMap< String, LNodeTypeValidator > lNodeTypeMap = new HashMap<>();
lNodeTypeMap.put( lnClass.getName(), new LNodeTypeValidator( lnClass ));
return lNodeTypeMap;
}
@Override @Override
public boolean validate( EObject eObject, DiagnosticChain diagnostics, Map< Object, Object > context ) { public boolean validate( EObject eObject, DiagnosticChain diagnostics, Map< Object, Object > context ) {
return validate( eObject.eClass(), eObject, diagnostics, context ); return validate( eObject.eClass(), eObject, diagnostics, context );
...@@ -66,19 +82,31 @@ public class NsdEObjectValidator implements EValidator { ...@@ -66,19 +82,31 @@ public class NsdEObjectValidator implements EValidator {
@Override @Override
public boolean validate( EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map< Object, Object > context ) { public boolean validate( EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map< Object, Object > context ) {
if( this.lnMap == null ) { if( this.anyLNValidatorMap == null ) {
this.initializeValidationData(); this.initializeValidationData();
} }
switch( eClass.getName() ) { SclSwitch< Boolean > sw = new SclSwitch< Boolean >() {
case "LN0":
case "LN": @Override
AnyLN ln = ( AnyLN ) eObject; public Boolean caseAnyLN( AnyLN anyLN ) {
return validateLN( ln, diagnostics ); return validateAnyLN( anyLN, diagnostics );
default: }
AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: NsdEObjectValidator.validate( " + eClass.getName() + " )" );
return false; @Override
} public Boolean caseLNodeType( LNodeType lNodeType ) {
return validateLNodeType( lNodeType, diagnostics );
}
@Override
public Boolean defaultCase( EObject object ) {
AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: NsdEObjectValidator.validate( " + object.eClass().getName() + " )" );
return true;
}
};
return sw.doSwitch( eObject );
} }
@Override @Override
...@@ -90,12 +118,12 @@ public class NsdEObjectValidator implements EValidator { ...@@ -90,12 +118,12 @@ public class NsdEObjectValidator implements EValidator {
return true; return true;
} }
private boolean validateLN( AnyLN ln, DiagnosticChain diagnostics ) { private boolean validateAnyLN( AnyLN ln, DiagnosticChain diagnostics ) {
AbstractRiseClipseConsole.getConsole().verbose( "" ); AbstractRiseClipseConsole.getConsole().verbose( "" );
AbstractRiseClipseConsole.getConsole().verbose( "NsdEObjectValidator.validateLN( " + ln.getLnClass() + " )" ); AbstractRiseClipseConsole.getConsole().verbose( "NsdEObjectValidator.validateLN( " + ln.getLnClass() + " )" );
// Check that LN has valid LNClass // Check that LN has valid LNClass
if( ! this.lnMap.containsKey( ln.getLnClass() )) { if( ! this.anyLNValidatorMap.containsKey( ln.getLnClass() )) {
diagnostics.add( new BasicDiagnostic( diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR, Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE, RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
...@@ -107,7 +135,27 @@ public class NsdEObjectValidator implements EValidator { ...@@ -107,7 +135,27 @@ public class NsdEObjectValidator implements EValidator {
AbstractRiseClipseConsole.getConsole().verbose( "found LNClass " + ln.getLnClass() + " in NSD files for LN at line " + ln.getLineNumber() ); AbstractRiseClipseConsole.getConsole().verbose( "found LNClass " + ln.getLnClass() + " in NSD files for LN at line " + ln.getLineNumber() );
// AnyLNValidator validates LN content // AnyLNValidator validates LN content
return lnMap.get( ln.getLnClass() ).validateLN( ln, diagnostics ); return anyLNValidatorMap.get( ln.getLnClass() ).validateLN( ln, diagnostics );
}
protected Boolean validateLNodeType( LNodeType lNodeType, DiagnosticChain diagnostics ) {
AbstractRiseClipseConsole.getConsole().verbose( "" );
AbstractRiseClipseConsole.getConsole().verbose( "NsdEObjectValidator.validateLNodeType( " + lNodeType.getLnClass() + " )" );
// Check that LN has valid LNClass
if( ! this.anyLNValidatorMap.containsKey( lNodeType.getLnClass() )) {
diagnostics.add( new BasicDiagnostic(
Diagnostic.ERROR,
RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
0,
"LNClass " + lNodeType.getLnClass() + " not found in NSD files for LN at line " + lNodeType.getLineNumber(),
new Object[] { lNodeType } ));
return false;
}
AbstractRiseClipseConsole.getConsole().verbose( "found LNClass " + lNodeType.getLnClass() + " in NSD files for LN at line " + lNodeType.getLineNumber() );
// AnyLNValidator validates LN content
return lNodeTypeValidatorMap.get( lNodeType.getLnClass() ).validateLNodeType( lNodeType, diagnostics );
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment