Commit eae99107 authored by Dominique Marcadet's avatar Dominique Marcadet

redesign of Resource/ResourceSet

version OK for loading NSD in Editor
parent 63a15582
......@@ -98,6 +98,16 @@
</appinfo>
</annotation>
</attribute>
<attribute name="resourceSetFactory" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn="fr.centralesupelec.edf.riseclipse.util.RiseClipseResourceSetFactory:"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
......@@ -158,7 +168,6 @@
aurelie.dehouck-neveu@edf.fr
Web site:
http://wdi.supelec.fr/software/RiseClipse/
</documentation>
</annotation>
......
......@@ -18,10 +18,38 @@
*/
package fr.centralesupelec.edf.riseclipse.util;
public interface IRiseClipseResource {
import org.eclipse.emf.ecore.resource.Resource;
void printStatistics( IRiseClipseConsole console );
/**
* Interface which must be implemented by all Resource of RiseClipse conforming metamodels.
* It specifies minimal needed services.
* Those are defined as default methods so that implementation is not needed.
*
* @author Dominique Marcadet
*
*/
public interface IRiseClipseResource extends Resource {
/**
* Display on given console information about content of this resource.
* Standard information should be displayed at the INFO_LEVEL.
* More detailed information can be displayed at the VERBOSE_LEVEL
*
* @param console the IRiseClipseConsole to use for display
*/
default void printStatistics( IRiseClipseConsole console ) {
// Nothing
}
void finalizeLoad( boolean ignore_unresolved_reference );
/**
* Execute any needed action after the model is loaded in the resource but before
* it is displayed or used.
*
* @param console the IRiseClipseConsole to use for displaying any message
* when running this method
*/
default void finalizeLoad( IRiseClipseConsole console ) {
// Nothing
}
}
/**
* Copyright (c) 2018 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.util;
import org.eclipse.emf.ecore.resource.ResourceSet;
/**
* Interface which must be implemented by all ResourceSet of RiseClipse conforming metamodels.
* It specifies minimal needed services.
* Those are defined as default methods so that implementation is not needed.
*
* @author Dominique Marcadet
*
*/
public interface IRiseClipseResourceSet extends ResourceSet {
/**
* Display on given console information about content of this resourceSet.
* Standard information should be displayed at the INFO_LEVEL.
* More detailed information can be displayed at the VERBOSE_LEVEL
*
* @param console the IRiseClipseConsole to use for display
*/
default void printStatistics( IRiseClipseConsole console ) {
// Nothing
}
/**
* Execute any needed action after the model is loaded in the resourcesnof
* this resourceSet but before it is displayed or used.
*
* @param console the IRiseClipseConsole to use for displaying any message
* when running this method
*/
default void finalizeLoad( IRiseClipseConsole console ) {
// Nothing
}
}
......@@ -27,8 +27,6 @@ import java.util.zip.ZipInputStream;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.IllegalValueException;
import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole;
......@@ -36,7 +34,7 @@ import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole;
public abstract class RiseClipseModelLoader {
protected ResourceSet resourceSet;
protected IRiseClipseResourceSet resourceSet;
protected IRiseClipseConsole console;
protected RiseClipseModelLoader( IRiseClipseConsole console ) {
......@@ -46,14 +44,14 @@ public abstract class RiseClipseModelLoader {
}
public void reset() {
this.resourceSet = new ResourceSetImpl();
this.resourceSet = new RiseClipseResourceSet();
}
public void reset( ResourceSet resourceSet ) {
public void reset( IRiseClipseResourceSet resourceSet ) {
this.resourceSet = resourceSet;
}
public ResourceSet getResourceSet() {
public IRiseClipseResourceSet getResourceSet() {
return resourceSet;
}
......@@ -137,10 +135,7 @@ public abstract class RiseClipseModelLoader {
}
public void finalizeLoad() {
for ( Resource resource : resourceSet.getResources() ) {
// we do not ignore unresolved references
(( IRiseClipseResource ) resource ).finalizeLoad( false );
}
resourceSet.finalizeLoad( console );
}
}
......@@ -18,123 +18,86 @@
*/
package fr.centralesupelec.edf.riseclipse.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Factory;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class RiseClipseResourceSet extends ResourceSetImpl {
private static final String XMLNS_ATTRIBUTE_NAME = "xmlns";
private HashMap< String, Factory > resourceFactories;
private ResourceFactoryFinder factoryFinder;
/**
* Minimal implementation of ResourceSet for RiseClipse conforming metamodels.
* It checks that only IRiseClipseResource are used, and give access to
* contained resources as IRiseClipseResource
*
* @author Dominique Marcadet
*
*/
public class RiseClipseResourceSet extends ResourceSetImpl implements IRiseClipseResourceSet {
public RiseClipseResourceSet( HashMap< String, Resource.Factory > resourceFactories ) {
this.resourceFactories = resourceFactories;
this.factoryFinder = new ResourceFactoryFinder();
@Override
public void printStatistics( IRiseClipseConsole console ) {
for( IRiseClipseResource r : getRiseClipseResources() ) {
r.printStatistics( console );
}
}
@Override
public Resource createResource( URI uri, String contentType ) {
Resource.Factory f = this.factoryFinder.findFactoryFor( uri );
// If we don't find any factory registered as RiseClipse metamodel, use the
// standard mechanism. This is at least needed for OCL documents
if( f != null ) {
Resource result = f.createResource( uri );
getResources().add( result );
return result;
public void finalizeLoad( IRiseClipseConsole console ) {
for( IRiseClipseResource r : getRiseClipseResources() ) {
r.finalizeLoad( console );
}
return super.createResource( uri, contentType );
}
@SuppressWarnings( "serial" )
private static class FactoryFoundException extends SAXException {
private Resource.Factory factory;
public EList< IRiseClipseResource > getRiseClipseResources() {
// The list is copied, but it is expected that the number of resources is low,
// so this should not be a problem.
EList< IRiseClipseResource > res = new BasicEList<>();
for( Resource r : super.getResources() ) {
if( ! ( r instanceof IRiseClipseResource )) {
throw new RiseClipseFatalException( "RiseClipseResourceSet.getRiseClipseResources(): not an IRiseClipseResource", null );
}
res.add(( IRiseClipseResource ) r );
}
return res;
}
public FactoryFoundException( Resource.Factory factory ) {
this.factory = factory;
/* (non-Javadoc)
* @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getResource(org.eclipse.emf.common.util.URI, boolean)
*/
@Override
public IRiseClipseResource getResource( URI uri, boolean loadOnDemand ) {
Resource res = super.getResource( uri, loadOnDemand );
if(( res != null ) && ( ! ( res instanceof IRiseClipseResource ))) {
throw new RiseClipseFatalException( "RiseClipseResourceSet.getResource(): not an IRiseClipseResource", null );
}
return ( IRiseClipseResource ) res;
}
public Resource.Factory getFactory() {
return factory;
/* (non-Javadoc)
* @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#createResource(org.eclipse.emf.common.util.URI)
*/
@Override
public IRiseClipseResource createResource( URI uri ) {
Resource res = super.createResource( uri );
if(( res != null ) && ( ! ( res instanceof IRiseClipseResource ))) {
throw new RiseClipseFatalException( "RiseClipseResourceSet.createResource(): not an IRiseClipseResource", null );
}
return ( IRiseClipseResource ) res;
}
protected class ResourceFactoryFinder {
private SAXParser saxParser;
public ResourceFactoryFinder() {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
try {
saxParser = saxParserFactory.newSAXParser();
}
catch( ParserConfigurationException e ) {
throw new RiseClipseRuntimeException( "RiseClipseResourceSet.ResourceFactoryFinder", e );
}
catch( SAXException e ) {
throw new RiseClipseRuntimeException( "RiseClipseResourceSet.ResourceFactoryFinder", e );
}
/* (non-Javadoc)
* @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#createResource(org.eclipse.emf.common.util.URI, java.lang.String)
*/
@Override
public IRiseClipseResource createResource( URI uri, String contentType ) {
Resource res = super.createResource( uri, contentType );
if(( res != null ) && ( ! ( res instanceof IRiseClipseResource ))) {
throw new RiseClipseFatalException( "RiseClipseResourceSet.getResource(): not an IRiseClipseResource", null );
}
return ( IRiseClipseResource ) res;
}
public Resource.Factory findFactoryFor( URI uri ) {
DefaultHandler defaultHandler = new DefaultHandler() {
public void startElement( String uri, String localName, String qName, Attributes attributes )
throws SAXException {
for( int i = 0; i < attributes.getLength(); ++i ) {
String furi = attributes.getURI( i );
if( furi.length() == 0 ) {
furi = attributes.getQName( i );
int dc = furi.indexOf( ':' );
if( dc != -1 ) {
furi = furi.substring( 0, dc );
}
}
if( XMLNS_ATTRIBUTE_NAME.equals( furi ) ) {
String ns = attributes.getValue( i );
if( RiseClipseResourceSet.this.resourceFactories.containsKey( ns )) {
Resource.Factory factory = RiseClipseResourceSet.this.resourceFactories.get( ns );
// Stop parsing and give back result
throw new FactoryFoundException( factory );
}
}
}
}
};
}
try {
URIConverter uriConverter = getURIConverter();
InputStream inputStream = uriConverter.createInputStream( uri );
saxParser.parse( inputStream, defaultHandler );
}
catch( FactoryFoundException e ) {
return e.getFactory();
}
catch( SAXException e ) {
// Not an xml file or any other error : we will use the standard mechanism
return null;
}
catch( IOException e ) {
// Not an xml file or any other error : we will use the standard mechanism
return null;
}
return null;
}
}
}
/**
* 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.util;
public class RiseClipseResourceSetFactory {
public IRiseClipseResourceSet createResourceSet() {
return new RiseClipseResourceSet();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment