From 634d3d728cf7c010c732a068c25c19826cb6e746 Mon Sep 17 00:00:00 2001 From: Dominique Marcadet <Dominique.Marcadet@centralesupelec.fr> Date: Sun, 27 Jan 2019 15:51:01 +0100 Subject: [PATCH] Structure for NSD based validation in place --- .../META-INF/MANIFEST.MF | 5 +- .../build.properties | 2 +- .../plugin.properties | 4 +- .../scl/validator/NSDEObjectValidator.java | 61 ++++++++++ .../scl/validator/NSDModelLoader.java | 70 +++++++++++ .../iec61850/scl/validator/NSDValidator.java | 112 ++++++++++++++++++ .../scl/validator/RiseClipseValidatorSCL.java | 88 +++++++++----- 7 files changed, 308 insertions(+), 34 deletions(-) create mode 100644 fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDEObjectValidator.java create mode 100644 fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDModelLoader.java create mode 100644 fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDValidator.java diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/META-INF/MANIFEST.MF b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/META-INF/MANIFEST.MF index 2c083c5..2057aad 100644 --- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/META-INF/MANIFEST.MF +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: RiseClipse IEC61850 SCL Tools +Bundle-Name: RiseClipse IEC61850 SCL Validator Bundle-Vendor: CentraleSupélec & EDF Bundle-SymbolicName: fr.centralesupelec.edf.riseclipse.iec61850.scl.validator Bundle-Version: 1.0.0.qualifier @@ -18,4 +18,5 @@ Require-Bundle: org.eclipse.core.runtime, fr.centralesupelec.edf.riseclipse.iec61850.scl, fr.centralesupelec.edf.riseclipse.iec61850.scl.edit, fr.centralesupelec.edf.riseclipse.validation.ocl, - fr.centralesupelec.edf.riseclipse.iec61850.nsd + fr.centralesupelec.edf.riseclipse.iec61850.nsd, + fr.centralesupelec.edf.riseclipse.iec61850.nsd.edit diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/build.properties b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/build.properties index 4acfb6b..0941c29 100644 --- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/build.properties +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/build.properties @@ -1,4 +1,4 @@ -# Copyright (c) 2018 CentraleSup�lec & EDF. +# 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 diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/plugin.properties b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/plugin.properties index 4e2644c..c48ed2d 100644 --- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/plugin.properties +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/plugin.properties @@ -1,4 +1,4 @@ -# Copyright (c) 2018 CentraleSup�lec & EDF. +# 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 @@ -15,5 +15,5 @@ # Web site: # http://wdi.supelec.fr/software/RiseClipse/ -pluginName = RiseClipse IEC 61850 SCL Tools +pluginName = RiseClipse IEC 61850 SCL Validator providerName = CentraleSup�lec & EDF diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDEObjectValidator.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDEObjectValidator.java new file mode 100644 index 0000000..1839451 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDEObjectValidator.java @@ -0,0 +1,61 @@ +/** + * 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; + +import java.util.Map; + +import org.eclipse.emf.common.util.DiagnosticChain; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.resource.Resource; + +import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole; + +public class NSDEObjectValidator implements EValidator { + + private Resource nsdResource; + + public NSDEObjectValidator( Resource nsdResource ) { + this.nsdResource = nsdResource; + } + + @Override + public boolean validate( EObject eObject, DiagnosticChain diagnostics, Map< Object, Object > context ) { + return validate( eObject.eClass(), eObject, diagnostics, context ); + } + + @Override + public boolean validate( EClass eClass, EObject eObject, DiagnosticChain diagnostics, + Map< Object, Object > context ) { + AbstractRiseClipseConsole.getConsole().info( "NSDEObjectValidator.validate( EClass ): " + eClass.getName() ); + // TODO: use nsdResource to validate eObject + return true; + } + + @Override + public boolean validate( EDataType eDataType, Object value, DiagnosticChain diagnostics, + Map< Object, Object > context ) { + AbstractRiseClipseConsole.getConsole().info( "NSDEObjectValidator.validate( EDataType ): " + eDataType.getName() ); + // TODO: use nsdResource to validate value + return true; + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDModelLoader.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDModelLoader.java new file mode 100644 index 0000000..0839ba2 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDModelLoader.java @@ -0,0 +1,70 @@ +/** + * 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; + +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.resource.Resource; + +import fr.centralesupelec.edf.riseclipse.iec61850.nsd.NsdPackage; +import fr.centralesupelec.edf.riseclipse.iec61850.nsd.util.NsdResourceFactoryImpl; +import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole; +import fr.centralesupelec.edf.riseclipse.util.RiseClipseModelLoader; +import fr.centralesupelec.edf.riseclipse.util.TextRiseClipseConsole; + +public class NSDModelLoader extends RiseClipseModelLoader { + + public NSDModelLoader( IRiseClipseConsole console ) { + super( console ); + } + + @Override + public void reset() { + super.reset(); + + // Register the appropriate resource factory to handle all file + // extensions. + getResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap() + .put( Resource.Factory.Registry.DEFAULT_EXTENSION, new NsdResourceFactoryImpl() ); + + // Register the package to ensure it is available during loading. + getResourceSet().getPackageRegistry().put( NsdPackage.eNS_URI, NsdPackage.eINSTANCE ); + } + + public Resource loadWithoutValidation( String name ) { + Object eValidator = EValidator.Registry.INSTANCE.remove( NsdPackage.eINSTANCE ); + + Resource resource = load( name ); + + if( eValidator != null ) { + EValidator.Registry.INSTANCE.put( NsdPackage.eINSTANCE, eValidator ); + } + return resource; + } + + public static void main( String[] args ) { + IRiseClipseConsole console = new TextRiseClipseConsole(); + SCLModelLoader loader = new SCLModelLoader( console ); + + for( int i = 0; i < args.length; ++i ) { + @SuppressWarnings( "unused" ) + Resource resource = loader.load( args[i] ); + } + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDValidator.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDValidator.java new file mode 100644 index 0000000..0bffb46 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NSDValidator.java @@ -0,0 +1,112 @@ +/** + * 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; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.EValidator.SubstitutionLabelProvider; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.Diagnostician; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.ocl.pivot.validation.ComposedEValidator; + +import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole; + +public class NSDValidator { + + private @NonNull EPackage modelPackage; + private ComposedEValidator validator; + + public NSDValidator( @NonNull EPackage modelPackage ) { + this.modelPackage = modelPackage; + validator = ComposedEValidator.install( modelPackage ); + } + + public boolean addNSDDocument( Resource resource, IRiseClipseConsole console ) { + NSDEObjectValidator nsdObjectValidator = new NSDEObjectValidator( resource ); + validator.addChild( nsdObjectValidator ); + return true; + } + + public void validate( Resource resource, final AdapterFactory adapter, IRiseClipseConsole console ) { + Map<Object, Object> context = new HashMap< Object, Object >(); + SubstitutionLabelProvider substitutionLabelProvider = new EValidator.SubstitutionLabelProvider() { + + @Override + public String getValueLabel( EDataType eDataType, Object value ) { + return Diagnostician.INSTANCE.getValueLabel( eDataType, value ); + } + + @Override + public String getObjectLabel( EObject eObject ) { + IItemLabelProvider labelProvider = ( IItemLabelProvider ) adapter.adapt( eObject, IItemLabelProvider.class ); + return labelProvider.getText( eObject ); + } + + @Override + public String getFeatureLabel( EStructuralFeature eStructuralFeature ) { + return Diagnostician.INSTANCE.getFeatureLabel( eStructuralFeature ); + } + }; + context.put(EValidator.SubstitutionLabelProvider.class, substitutionLabelProvider ); + + for( int n = 0; n < resource.getContents().size(); ++n ) { + Diagnostic diagnostic = Diagnostician.INSTANCE.validate( resource.getContents().get( n ), context ); + + if( diagnostic.getSeverity() == Diagnostic.ERROR || diagnostic.getSeverity() == Diagnostic.WARNING ) { + //EObject root = ( EObject ) diagnostic.getData().get( 0 ); + //URI uri = root.eResource().getURI(); + //console.error( "in file " + uri.lastSegment() ); + for( Iterator< Diagnostic > i = diagnostic.getChildren().iterator(); i.hasNext(); ) { + Diagnostic childDiagnostic = i.next(); + switch( childDiagnostic.getSeverity() ) { + case Diagnostic.ERROR: + case Diagnostic.WARNING: + List< ? > data = childDiagnostic.getData(); + EObject object = ( EObject ) data.get( 0 ); + if( data.size() == 1 ) { + console.error( "\t" + childDiagnostic.getMessage() ); + } + else if( data.get( 1 ) instanceof EAttribute ) { + EAttribute attribute = ( EAttribute ) data.get( 1 ); + if( attribute == null ) continue; + console.error( "\tAttribute " + attribute.getName() + " of " + substitutionLabelProvider.getObjectLabel( object ) + " : " + childDiagnostic.getChildren().get( 0 ).getMessage() ); + } + else { + console.error( "\t" + childDiagnostic.getMessage() ); + } + } + } + } + } + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java index 46bbee2..acfe5d5 100644 --- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java +++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018 CentraleSupélec & EDF. + * 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 @@ -21,6 +21,7 @@ package fr.centralesupelec.edf.riseclipse.iec61850.scl.validator; import java.io.File; import java.util.ArrayList; +import fr.centralesupelec.edf.riseclipse.iec61850.nsd.provider.NsdItemProviderAdapterFactory; import fr.centralesupelec.edf.riseclipse.iec61850.scl.SclPackage; import fr.centralesupelec.edf.riseclipse.iec61850.scl.provider.SclItemProviderAdapterFactory; import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole; @@ -32,14 +33,20 @@ import org.eclipse.emf.ecore.resource.Resource; public class RiseClipseValidatorSCL { - private static OCLValidator ocl; - private static SclItemProviderAdapterFactory adapter; - private static SCLModelLoader loader; + private static OCLValidator oclValidator; + private static SclItemProviderAdapterFactory sclAdapter; + private static SCLModelLoader sclLoader; + private static NSDValidator nsdValidator; + private static boolean oclValidation = false; + private static boolean nsdValidation = false; + private static NsdItemProviderAdapterFactory nsdAdapter; public static void usage( IRiseClipseConsole console ) { console.setLevel( IRiseClipseConsole.INFO_LEVEL ); - console.info( "java -jar RiseClipseValidatorSCL.jar [--verbose] [--make-explicit-links] [<oclFile> | <sclFile>]*" ); - console.info( "Files ending with \".ocl\" are considered OCL files, all others are considered SCL files" ); + console.info( "java -jar RiseClipseValidatorSCL.jar [--verbose] [--make-explicit-links] [<oclFile> | <nsdFile> | <sclFile>]*" ); + console.info( "Files ending with \".ocl\" are considered OCL files, " + + "files ending with \\\".nsd\\\" are considered NSD files, " + + "all others are considered SCL files" ); System.exit( -1 ); } @@ -74,24 +81,30 @@ public class RiseClipseValidatorSCL { } ArrayList< File > oclFiles = new ArrayList<>(); + ArrayList< String > nsdFiles = new ArrayList<>(); ArrayList< String > sclFiles = new ArrayList<>(); for( int i = posFiles; i < args.length; ++i ) { if( args[i].endsWith( ".ocl" )) { oclFiles.add( new File( args[i] )); + oclValidation = true; + } + else if( args[i].endsWith( ".nsd" )) { + nsdFiles.add( args[i] ); + nsdValidation = true; } else { sclFiles.add( args[i] ); } } - prepare( console, oclFiles ); + prepare( console, oclFiles, nsdFiles ); for( int i = 0; i < sclFiles.size(); ++i ) { run( console, make_explicit_links, sclFiles.get( i )); } } public static void displayLegal( IRiseClipseConsole console ) { - console.info( "Copyright (c) 2018 CentraleSupélec & EDF." ); + console.info( "Copyright (c) 2019 CentraleSupélec & EDF." ); console.info( "All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0" ); console.info( "which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html" ); console.info( "" ); @@ -105,39 +118,56 @@ public class RiseClipseValidatorSCL { console.info( "Web site:" ); console.info( " http://wdi.supelec.fr/software/RiseClipse/" ); console.info( "" ); - console.info( "RiseClipseSCLValidator version: 1.0.1 (6 June 2018)" ); + console.info( "RiseClipseValidatorSCL version: 1.0.0 (28 January 2019)" ); console.info( "" ); } - public static void prepare( IRiseClipseConsole console, ArrayList< File > oclFiles ) { - SclPackage sclPg = SclPackage.eINSTANCE; - ocl = new OCLValidator( sclPg, true ); - - for( int i = 0; i < oclFiles.size(); ++i ) { - console.info( "Loading ocl: " + oclFiles.get( i )); - // workaround for bug 486872 -// File file = new File( oclFiles.get( i )); -// URI uri = file.isFile() ? URI.createFileURI( file.getAbsolutePath() ) : URI.createURI( oclFiles.get( i )); -// oclFiles.add( uri ); -// ocl.addOCLDocument( uri, console ); - ocl.addOCLDocument( oclFiles.get( i ), console ); + public static void prepare( IRiseClipseConsole console, ArrayList< File > oclFiles, ArrayList< String > nsdFiles ) { + if( oclValidation ) { + oclValidator = new OCLValidator( SclPackage.eINSTANCE, true ); + + for( int i = 0; i < oclFiles.size(); ++i ) { + console.info( "Loading ocl: " + oclFiles.get( i )); + // workaround for bug 486872 +// File file = new File( oclFiles.get( i )); +// URI uri = file.isFile() ? URI.createFileURI( file.getAbsolutePath() ) : URI.createURI( oclFiles.get( i )); +// oclFiles.add( uri ); +// ocl.addOCLDocument( uri, console ); + oclValidator.addOCLDocument( oclFiles.get( i ), console ); + } + } + + if( nsdValidation ) { + nsdValidator = new NSDValidator( SclPackage.eINSTANCE ); + NSDModelLoader nsdLoader = new NSDModelLoader( console ); + for( int i = 0; i < nsdFiles.size(); ++i ) { + console.info( "Loading nsd: " + nsdFiles.get( i )); + nsdValidator.addNSDDocument( nsdLoader.load( nsdFiles.get( i )), console ); + } + nsdAdapter = new NsdItemProviderAdapterFactory(); } - loader = new SCLModelLoader( console ); - adapter = new SclItemProviderAdapterFactory(); + sclLoader = new SCLModelLoader( console ); + sclAdapter = new SclItemProviderAdapterFactory(); } public static void run( IRiseClipseConsole console, boolean make_explicit_links, String sclFile ) { - loader.reset(); - Resource resource = loader.loadWithoutValidation( sclFile ); + sclLoader.reset(); + Resource resource = sclLoader.loadWithoutValidation( sclFile ); if( make_explicit_links ) { console.info( "Making explicit links for file: " + sclFile ); - loader.finalizeLoad(); + sclLoader.finalizeLoad(); } if( resource != null ) { - console.info( "Validating file: " + sclFile ); - ocl.validate( resource, adapter, console ); - } + if( oclValidation ) { + console.info( "Validating file: " + sclFile + " with OCL" ); + oclValidator.validate( resource, sclAdapter, console ); + } + if( nsdValidation ) { + console.info( "Validating file: " + sclFile + " with NSD" ); + nsdValidator.validate( resource, nsdAdapter, console ); + } + } } } -- GitLab