/**
* Copyright (c) 2005-2008 IBM Corporation and others.
* 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
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.exporter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.codegen.ecore.genmodel.GenAnnotation;
import org.eclipse.emf.codegen.ecore.genmodel.GenBase;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.converter.ConverterPlugin;
import org.eclipse.emf.converter.ModelConverter;
import org.eclipse.emf.converter.util.ConverterUtil;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.exporter.util.ExporterUtil;
/**
* @since 2.2.0
*/
public abstract class ModelExporter extends ModelConverter
{
public static final String GENANNOTATION_SOURCE_PREFIX = GenModelPackage.eNS_URI + "/exporter/";
public static final String GENANNOTATION_KEY_DIRECTORY_URI = "directoryURI";
// Nested GenAnnotations
public static final String GENANNOTATION_SOURCE_SELECTED_EPACKAGES = "selectedPackages";
public static final String GENANNOTATION_SOURCE_SELECTED_REFERENCES = "selectedReferencedPackages";
public static class EPackageExportInfo extends ModelConverter.EPackageConvertInfo
{
public String getArtifactLocation()
{
return getConvertData();
}
public void setArtifactLocation(String artifactLocation)
{
setConvertData(artifactLocation);
}
}
public static class ReferencedGenPackageExportInfo extends ModelConverter.ReferencedGenPackageConvertInfo
{
protected String modelExporterID;
protected URI artifactURI;
protected Map<String, List<URI>> nsURIToLocalArtifactURIs;
public String getModelExporterID()
{
return modelExporterID;
}
public void setModelExporterID(String modelExporterID)
{
this.modelExporterID = modelExporterID;
}
public URI getArtifactURI()
{
return artifactURI;
}
public void setArtifactURI(URI artifactURI)
{
this.artifactURI = artifactURI;
}
public Map<String, List<URI>> getNSURIToLocalArtifactURIs()
{
if (nsURIToLocalArtifactURIs == null)
{
nsURIToLocalArtifactURIs = new HashMap<String, List<URI>>();
}
return nsURIToLocalArtifactURIs;
}
}
public static class ExportData
{
public Map<GenPackage, URI> genPackageToArtifactURI;
public Map<GenPackage, List<GenPackage>> genPackageToReferencedGenPackages;
public Map<GenPackage, URI> referencedGenPackagesToArtifactURI;
}
protected static class GenPackagesTreeIterator extends AbstractTreeIterator<GenPackage>
{
private static final long serialVersionUID = 1L;
public GenPackagesTreeIterator(GenModel genModel)
{
this(genModel.getGenPackages());
}
public GenPackagesTreeIterator(Collection<GenPackage> genPackages)
{
super(genPackages, false);
}
@SuppressWarnings("unchecked")
@Override
protected Iterator<GenPackage> getChildren(Object object)
{
return object instanceof Collection<?> ?
((Collection<GenPackage>)object).iterator() :
((GenPackage)object).getNestedGenPackages().iterator();
}
}
protected Map<EPackage, GenPackage> ePackageToGenPackageMap;
protected URI directoryURI;
protected Map<GenBase, EMap<String, String>> genBaseToDetailsMap;
protected boolean saveExporter = false;
protected boolean saveEPackageArtifactURI = false;
@Override
public void dispose()
{
if (genBaseToDetailsMap != null)
{
genBaseToDetailsMap.clear();
genBaseToDetailsMap = null;
}
if (ePackageToGenPackageMap != null)
{
ePackageToGenPackageMap.clear();
ePackageToGenPackageMap = null;
}
super.dispose();
}
@Override
protected String getConverterGenAnnotationSource()
{
return GENANNOTATION_SOURCE_PREFIX + getID();
}
protected Map<EPackage, GenPackage> getEPackageToGenPackageMap()
{
if (ePackageToGenPackageMap == null)
{
ePackageToGenPackageMap = new HashMap<EPackage, GenPackage>();
}
return ePackageToGenPackageMap;
}
protected Map<GenBase, EMap<String, String>> getGenBaseToGenAnnotationDetailsMap()
{
if (genBaseToDetailsMap == null)
{
genBaseToDetailsMap = new HashMap<GenBase, EMap<String, String>>();
}
return genBaseToDetailsMap;
}
/**
* Returns the {@link GenBase} object's {@link GenAnnotation} Details map
* associated with this Model Exporter or {@link ECollections#EMPTY_EMAP}
*/
protected EMap<String, String> getExporterGenAnnotationDetails(GenBase genBase)
{
EMap<String, String> eMap = getGenBaseToGenAnnotationDetailsMap().get(genBase);
if (eMap == null)
{
GenAnnotation genAnnotation = genBase.getGenAnnotation(getConverterGenAnnotationSource());
if (genAnnotation != null)
{
eMap = genAnnotation.getDetails();
getGenBaseToGenAnnotationDetailsMap().put(genBase, eMap);
}
else
{
eMap = ECollections.emptyEMap();
}
}
return eMap;
}
protected List<GenAnnotation> getExporterNestedGenAnnotations(GenBase genBase)
{
if (genBase != null)
{
GenAnnotation exportAnnotation = genBase.getGenAnnotation(getConverterGenAnnotationSource());
if (exportAnnotation != null && !exportAnnotation.getGenAnnotations().isEmpty())
{
List<GenAnnotation> nestedAnnotations = exportAnnotation.getGenAnnotations();
if (nestedAnnotations != null)
{
return nestedAnnotations;
}
}
}
return Collections.emptyList();
}
protected EMap<String, String> getExporterNestedGenAnnotationDetails(GenBase genBase, String nestedGenAnnotationSource)
{
GenAnnotation genAnnotation = genBase.getGenAnnotation(getConverterGenAnnotationSource());
if (genAnnotation != null)
{
GenAnnotation nestedGenAnnotation = genAnnotation.getGenAnnotation(nestedGenAnnotationSource);
if (nestedGenAnnotation != null)
{
return nestedGenAnnotation.getDetails();
}
}
return ECollections.emptyEMap();
}
public List<URI> getArtifactURIs(GenPackage genPackage)
{
List<GenAnnotation> nestedAnnotations = getExporterNestedGenAnnotations(genPackage);
if (!nestedAnnotations.isEmpty())
{
List<URI> uris = new UniqueEList<URI>(nestedAnnotations.size());
URI genModelURI = genPackage.getGenModel().eResource() != null ?
genPackage.getGenModel().eResource().getURI() :
null;
for (GenAnnotation uriAnnotation : nestedAnnotations)
{
URI uri = URI.createURI(uriAnnotation.getSource());
if (genModelURI != null)
{
uri = uri.resolve(genModelURI);
}
uris.add(uri);
}
for (GenPackage referencedGenPackage : getReferencedGenPackages())
{
ReferencedGenPackageExportInfo genPackageInfo = getReferencedGenPackageExportInfo(referencedGenPackage);
if (genPackageInfo.getArtifactURI() != null)
{
List<URI> localURIs = genPackageInfo.getNSURIToLocalArtifactURIs().get(genPackage.getNSURI());
if (localURIs != null)
{
uris.addAll(localURIs);
}
}
}
return uris;
}
return Collections.emptyList();
}
public void setGenModel(GenModel genModel) throws DiagnosticException
{
dispose();
this.genModel = genModel;
genModel = getGenModel();
Diagnostic diagnostic = null;
if (genModel != null)
{
genModel.reconcile();
genModel.setValidateModel(true);
diagnostic = genModel.diagnose();
if (getDirectoryURI() == null)
{
String location = getExporterGenAnnotationDetails(genModel).get(GENANNOTATION_KEY_DIRECTORY_URI);
setDirectoryURI(location);
}
if (genModel.eResource() != null && getDirectoryURI() != null)
{
setDirectoryURI(getDirectoryURI().resolve(genModel.eResource().getURI()));
}
for (Iterator<GenPackage> i = new GenPackagesTreeIterator(genModel); i.hasNext();)
{
GenPackage genPackage = i.next();
if (isValidEPackage(genPackage))
{
EPackage ePackage = genPackage.getEcorePackage();
getEPackageToGenPackageMap().put(ePackage, genPackage);
getEPackages().add(genPackage.getEcorePackage());
}
}
List<GenPackage> exporterUsedGenPackages = new ConverterUtil.GenPackageList(genModel.getUsedGenPackages());
GenAnnotation genModelAnnotation = genModel.getGenAnnotation(getConverterGenAnnotationSource());
if (genModelAnnotation != null)
{
GenAnnotation referencedPackagesAnnotation = genModelAnnotation.getGenAnnotation(GENANNOTATION_SOURCE_SELECTED_REFERENCES);
if (referencedPackagesAnnotation != null)
{
for (Object o : referencedPackagesAnnotation.getReferences())
{
if (o instanceof GenPackage)
{
exporterUsedGenPackages.add((GenPackage)o);
}
}
}
}
for (Iterator<GenPackage> i = new GenPackagesTreeIterator(exporterUsedGenPackages); i.hasNext();)
{
GenPackage genPackage = i.next();
if (isValidEPackage(genPackage))
{
EPackage ePackage = genPackage.getEcorePackage();
getEPackageToGenPackageMap().put(ePackage, genPackage);
if (isValidReferencedGenPackage(genPackage))
{
getReferencedGenPackages().add(genPackage);
}
getEPackages().add(ePackage);
}
}
}
adjustGenModel();
if (diagnostic != null && diagnostic.getSeverity() != Diagnostic.OK)
{
throw new DiagnosticException(diagnostic);
}
}
protected void adjustGenModel()
{
boolean defaultLocationSet = false;
for (Map.Entry<EPackage, EPackageConvertInfo> entry : getEPackageToInfoMap().entrySet())
{
EPackage ePackage = entry.getKey();
EPackageExportInfo packageInfo = (EPackageExportInfo)entry.getValue();
if (packageInfo.getArtifactLocation() == null)
{
packageInfo.setArtifactLocation(getDefaultArtifactLocation(ePackage));
defaultLocationSet |= packageInfo.getArtifactLocation() == null;
}
}
if (defaultLocationSet)
{
makeEPackageConvertDataUnique();
}
}
protected String getDefaultArtifactLocation(EPackage ePackage)
{
return null;
}
/**
* Returns whether the EPackage associated with the specified GenPackage should be added
* to the ePackage list.
*/
protected boolean isValidEPackage(GenPackage genPackage)
{
return genPackage.getEcorePackage() != null && genPackage.hasClassifiers();
}
/**
* Returns whether the specified GenPackage should be added to the referenced
* GenPackage list.
*/
protected boolean isValidReferencedGenPackage(GenPackage genPackage)
{
return genPackage.getEcorePackage() != null && genPackage.hasClassifiers();
}
@Override
protected List<EPackage> createEPackagesList()
{
return
new ConverterUtil.EPackageList()
{
private static final long serialVersionUID = 1L;
@Override
protected void didAdd(int index, EPackage newObject)
{
EPackageExportInfo packageInfo = getEPackageExportInfo(newObject);
if (packageInfo.getArtifactLocation() == null)
{
String location = getExporterNestedGenAnnotationDetails(getGenModel(), GENANNOTATION_SOURCE_SELECTED_EPACKAGES).get(newObject.getNsURI());
if (location != null)
{
packageInfo.setConvert(true);
packageInfo.setArtifactLocation(location);
}
}
}
};
}
@Override
protected List<GenPackage> createReferencedGenPackagesList()
{
return
new ConverterUtil.GenPackageList()
{
private static final long serialVersionUID = 1L;
@Override
protected void didAdd(int index, GenPackage newObject)
{
URI genModelURI = newObject.getGenModel().eResource() != null ?
newObject.getGenModel().eResource().getURI() :
null;
String stringURI = getExporterNestedGenAnnotationDetails(getGenModel(), GENANNOTATION_SOURCE_SELECTED_REFERENCES).get(newObject.getNSURI());
if (stringURI != null)
{
ReferencedGenPackageExportInfo genPackageInfo = getReferencedGenPackageExportInfo(newObject);
if (genPackageInfo.getArtifactURI() == null)
{
genPackageInfo.setModelExporterID(getID());
URI uri = URI.createURI(stringURI);
if (genModelURI != null)
{
uri = uri.resolve(genModelURI);
}
genPackageInfo.setArtifactURI(uri);
}
}
List<GenAnnotation> uriAnnotations = getExporterNestedGenAnnotations(newObject);
if (!uriAnnotations.isEmpty())
{
ReferencedGenPackageExportInfo genPackageInfo = null;
for (GenAnnotation uriAnnotation : uriAnnotations)
{
if (!uriAnnotation.getDetails().isEmpty())
{
if (genPackageInfo == null)
{
genPackageInfo = getReferencedGenPackageExportInfo(newObject);
}
for (Map.Entry<String, String> entry : uriAnnotation.getDetails())
{
String packageNSURI = entry.getKey();
String stringArtifactURIs = entry.getValue();
if (stringArtifactURIs != null)
{
String[] stringURIs = stringArtifactURIs.split(" ");
List<URI> uris = genPackageInfo.getNSURIToLocalArtifactURIs().get(packageNSURI);
if (uris == null)
{
uris = new ArrayList<URI>(stringURIs.length);
genPackageInfo.getNSURIToLocalArtifactURIs().put(packageNSURI, uris);
}
for (int k = 0; k < stringURIs.length; k++)
{
URI uri = URI.createURI(stringURIs[k]);
if (genModelURI != null)
{
uri = uri.resolve(genModelURI);
}
uris.add(uri);
}
}
}
}
}
}
}
};
}
public void loadGenModel(URI uri) throws DiagnosticException
{
setGenModel(uri == null ? null :
(GenModel)createResourceSet().getResource(uri, true).getContents().get(0));
}
public EPackageExportInfo getEPackageExportInfo(EPackage ePackage)
{
return (EPackageExportInfo)getEPackageConvertInfo(ePackage);
}
@Override
protected EPackageConvertInfo createEPackageInfo(EPackage ePackage)
{
return new EPackageExportInfo();
}
public ReferencedGenPackageExportInfo getReferencedGenPackageExportInfo(GenPackage genPackage)
{
return (ReferencedGenPackageExportInfo)getReferenceGenPackageConvertInfo(genPackage);
}
@Override
protected ReferencedGenPackageConvertInfo createGenPackageConvertInfo(GenPackage genPackage)
{
ReferencedGenPackageExportInfo genPackageInfo = new ReferencedGenPackageExportInfo();
genPackageInfo.setValidReference(!getExporterNestedGenAnnotations(genPackage).isEmpty());
return genPackageInfo;
}
@Override
protected ReferencedEPackageFilter createReferencedEPackageFilterToConvert()
{
return new ReferencedEPackageFilter()
{
@Override
protected boolean isValidReference(GenPackage genPackage)
{
return super.isValidReference(genPackage) &&
getReferencedGenPackageExportInfo(genPackage).getArtifactURI() != null;
}
};
}
@Override
protected boolean canConvert(EPackage ePackage)
{
return super.canConvert(ePackage) && getEPackageExportInfo(ePackage).getArtifactLocation() != null;
}
/**
* <p>Creates the {@link ExportData} instance and delegates the export work to
* the {@link #doExport(Monitor, ModelExporter.ExportData)} method.</p>
* <p>The {@link Diagnostic} returned by this method should be used to provide
* the user some information regarding a <b>successful</b> export. If the
* export fails, an exception should be thrown.<p>
* @param monitor
* @return {@link Diagnostic}
* @throws Exception
*/
public Diagnostic export(Monitor monitor) throws Exception
{
Map<String, GenPackage> nsURIToReferencedGenPackage = null;
Map<GenPackage, URI> referencedGenPackageToArtifactURI = null;
if (referencedGenPackageToInfoMap != null)
{
referencedGenPackageToArtifactURI = new HashMap<GenPackage, URI>(referencedGenPackageToInfoMap.size());
nsURIToReferencedGenPackage = new HashMap<String, GenPackage>(referencedGenPackageToInfoMap.size());
List<GenPackage> referencedGenPackages = computeValidReferencedGenPackages();
for (GenPackage genPackage : referencedGenPackages)
{
URI artifactURI = getReferencedGenPackageExportInfo(genPackage).getArtifactURI();
referencedGenPackageToArtifactURI.put(genPackage, artifactURI);
nsURIToReferencedGenPackage.put(genPackage.getNSURI(), genPackage);
}
}
Map<GenPackage, URI> genPackageToArtifactURI = null;
Map<GenPackage, List<GenPackage>> genPackageToReferencedGenPackages = null;
if (ePackageToInfoMap != null && ePackageToGenPackageMap != null)
{
genPackageToArtifactURI = new HashMap<GenPackage, URI>(ePackageToInfoMap.size());
genPackageToReferencedGenPackages = new HashMap<GenPackage, List<GenPackage>>(ePackageToInfoMap.size());
List<EPackage> ePackages = computeEPackagesToConvert();
for (EPackage ePackage : ePackages)
{
GenPackage genPackage = ePackageToGenPackageMap.get(ePackage);
if (genPackage != null)
{
if (nsURIToReferencedGenPackage != null)
{
List<EPackage> requiredEPackages = ConverterUtil.computeRequiredPackages(ePackage);
List<GenPackage> requiredGenPackages = new ConverterUtil.GenPackageList(requiredEPackages.size());
for (EPackage requiredEPackage : requiredEPackages)
{
GenPackage referencedGenPackage = nsURIToReferencedGenPackage.get(requiredEPackage.getNsURI());
if (referencedGenPackage != null)
{
requiredGenPackages.add(referencedGenPackage);
}
}
if (!requiredGenPackages.isEmpty())
{
genPackageToReferencedGenPackages.put(genPackage, requiredGenPackages);
}
}
EPackageExportInfo exportInfo = getEPackageExportInfo(ePackage);
String artifactLocation = exportInfo.getArtifactLocation();
if (artifactLocation != null)
{
genPackageToArtifactURI.put(genPackage, computeArtifactURI(artifactLocation));
}
}
}
}
if (genPackageToArtifactURI == null || genPackageToArtifactURI.isEmpty())
{
throw new DiagnosticException(new BasicDiagnostic(Diagnostic.ERROR, ExporterPlugin.ID, 0, ExporterPlugin.INSTANCE.getString("_UI_NoPackagesToExport_error"), null));
}
else
{
ExportData exportData = new ExportData();
exportData.genPackageToArtifactURI = genPackageToArtifactURI;
exportData.referencedGenPackagesToArtifactURI = referencedGenPackageToArtifactURI != null && !referencedGenPackageToArtifactURI.isEmpty() ?
referencedGenPackageToArtifactURI :
Collections.<GenPackage, URI>emptyMap();
exportData.genPackageToReferencedGenPackages = genPackageToReferencedGenPackages != null && !genPackageToReferencedGenPackages.isEmpty() ?
genPackageToReferencedGenPackages :
Collections.<GenPackage, List<GenPackage>>emptyMap();
return doExport(monitor, exportData);
}
}
/**
* <p>Subclasses should overwrite this method, adding the code that performs the
* actions required to export the model.</p>
* <p>The {@link Diagnostic} returned by this method should be used to provide
* the user some information regarding a <b>successfull</b> export. If the
* export fails, an exception should be thrown.<p>
* @param monitor
* @return {@link Diagnostic}
* @throws Exception
*/
protected Diagnostic doExport(Monitor monitor, ExportData exportData) throws Exception
{
return Diagnostic.OK_INSTANCE;
}
public Diagnostic checkEPackageArtifactLocation(String location, String packageName)
{
String message = null;
if (location == null || location.equals(""))
{
message = packageName == null ?
ExporterPlugin.INSTANCE.getString("_UI_ArtifactFileNameCannotBeEmpty_message") :
ExporterPlugin.INSTANCE.getString("_UI_ArtifactFileNameForPackageCannotBeEmpty_message", new Object []{packageName});
}
else
{
message = doCheckEPackageArtifactLocation(location, packageName);
}
if (message == null)
{
return Diagnostic.OK_INSTANCE;
}
else
{
return new BasicDiagnostic(Diagnostic.ERROR, ConverterPlugin.ID, ConverterUtil.ACTION_DEFAULT, message, null);
}
}
protected String doCheckEPackageArtifactLocation(String location, String packageName)
{
return null;
}
public URI getDirectoryURI()
{
return directoryURI;
}
public void setDirectoryURI(URI directoryURI)
{
this.directoryURI = directoryURI;
}
public void setDirectoryURI(String location)
{
directoryURI = createEncodedURI(location);
}
/**
* Returns the artifact URI for a given artifact location. The
* URI is resolved against the directory URI.
*/
protected URI computeArtifactURI(String location)
{
URI artifactURI = createEncodedURI(location);
URI directoryURI = getDirectoryURI();
if (directoryURI != null)
{
artifactURI = artifactURI.resolve(directoryURI);
}
return artifactURI;
}
protected URI createEncodedURI(String location)
{
return location != null ?
URI.createURI(location, true, URI.FRAGMENT_NONE) :
null;
}
public Diagnostic validateDirectoryURI(String uri)
{
if (uri != null && uri.length() > 0 && !uri.endsWith("/"))
{
return new BasicDiagnostic(Diagnostic.ERROR,
ConverterPlugin.ID, ConverterUtil.ACTION_MESSAGE_SET_ERROR,
ExporterPlugin.INSTANCE.getString("_UI_DirectoryURI_error"), null);
}
else
{
return Diagnostic.OK_INSTANCE;
}
}
public boolean isSaveEPackageArtifactURI()
{
return saveEPackageArtifactURI;
}
public void setSaveEPackageArtifactURI(boolean saveEPackageArtifactURI)
{
this.saveEPackageArtifactURI = saveEPackageArtifactURI;
}
public boolean isSaveExporter()
{
return saveExporter;
}
public void setSaveExporter(boolean saveExporter)
{
this.saveExporter = saveExporter;
}
/**
* Saves this exporters settings in the selected GenModel.
*/
public void save() throws Exception
{
Resource genModelResource = getGenModel().eResource();
boolean changed = false;
if (isSaveExporter())
{
changed |= saveExporter();
}
if (isSaveEPackageArtifactURI())
{
changed |= saveEPackageArtifactURI();
}
changed |= genModelResource.isModified();
if (changed)
{
if (EMFPlugin.IS_ECLIPSE_RUNNING)
{
String readOnlyFiles = ConverterUtil.WorkspaceResourceValidator.validate(Collections.singletonList(genModelResource));
if (readOnlyFiles != null)
{
throw new Exception(ExporterPlugin.INSTANCE.getString("_UI_ReadOnlyFiles_error", new String[]{readOnlyFiles}));
}
}
genModelResource.save(getGenModelSaveOptions());
}
}
/**
* Saves this exporter settings.
* @return Whether this method has changed the GenModel instance
*/
protected boolean saveExporter()
{
boolean changed = false;
GenAnnotation genModelAnnotation = getGenModel().getGenAnnotation(getConverterGenAnnotationSource());
URI directoryURI = getDirectoryURI();
if (directoryURI == null)
{
if (genModelAnnotation != null)
{
changed |= genModelAnnotation.getDetails().remove(GENANNOTATION_KEY_DIRECTORY_URI);
}
}
else
{
if (getGenModel().eResource() != null)
{
directoryURI = directoryURI.deresolve(getGenModel().eResource().getURI());
}
if (genModelAnnotation == null)
{
genModelAnnotation = ExporterUtil.findOrCreateGenAnnotation(getGenModel(), getConverterGenAnnotationSource());
changed = true;
}
String stringURI = directoryURI.toString();
Object oldValue = genModelAnnotation.getDetails().put(GENANNOTATION_KEY_DIRECTORY_URI, stringURI);
changed |= !stringURI.equals(oldValue);
}
List<EPackage> ePackages = computeEPackagesToConvert();
if (ePackages.isEmpty())
{
if (genModelAnnotation != null)
{
GenAnnotation nestedGenAnnotation = genModelAnnotation.getGenAnnotation(GENANNOTATION_SOURCE_SELECTED_EPACKAGES);
if (nestedGenAnnotation != null)
{
genModelAnnotation.getGenAnnotations().remove(nestedGenAnnotation);
changed = true;
}
}
}
else
{
if (genModelAnnotation == null)
{
genModelAnnotation = ExporterUtil.findOrCreateGenAnnotation(getGenModel(), getConverterGenAnnotationSource());
changed = true;
}
GenAnnotation nestedGenAnnotation = ExporterUtil.findOrCreateGenAnnotation(genModelAnnotation, GENANNOTATION_SOURCE_SELECTED_EPACKAGES);
Set<String> nsURIs = new HashSet<String>();
for (EPackage ePackage : ePackages)
{
String location = getEPackageExportInfo(ePackage).getArtifactLocation();
if (location != null)
{
nsURIs.add(ePackage.getNsURI());
Object oldValue = nestedGenAnnotation.getDetails().put(ePackage.getNsURI(), location);
changed |= !location.equals(oldValue);
}
}
changed |= nestedGenAnnotation.getDetails().keySet().retainAll(nsURIs);
}
List<GenPackage> referencedGenPackages = computeValidReferencedGenPackages();
if (referencedGenPackages.isEmpty())
{
if (genModelAnnotation != null)
{
GenAnnotation nestedGenAnnotation = genModelAnnotation.getGenAnnotation(GENANNOTATION_SOURCE_SELECTED_REFERENCES);
if (nestedGenAnnotation != null)
{
changed |= genModelAnnotation.getGenAnnotations().remove(nestedGenAnnotation);
}
}
}
else
{
if (genModelAnnotation == null)
{
genModelAnnotation = ExporterUtil.findOrCreateGenAnnotation(getGenModel(), getConverterGenAnnotationSource());
changed = true;
}
GenAnnotation nestedGenAnnotation = ExporterUtil.findOrCreateGenAnnotation(genModelAnnotation, GENANNOTATION_SOURCE_SELECTED_REFERENCES);
Set<String> nsURIs = new HashSet<String>();
for (GenPackage genPackage : referencedGenPackages)
{
nsURIs.add(genPackage.getNSURI());
URI uri = getReferencedGenPackageExportInfo(genPackage).getArtifactURI();
if (genPackage.getGenModel().eResource() != null)
{
uri = uri.deresolve(genPackage.getGenModel().eResource().getURI());
}
String stringURI = uri.toString();
Object oldValue = nestedGenAnnotation.getDetails().put(genPackage.getNSURI(), stringURI);
changed |= !stringURI.equals(oldValue);
if (getGenModel().getUsedGenPackages().contains(genPackage))
{
changed |= nestedGenAnnotation.getReferences().remove(genPackage);
}
else
{
changed |= nestedGenAnnotation.getReferences().add(genPackage);
}
}
changed |= nestedGenAnnotation.getDetails().keySet().retainAll(nsURIs);
}
return changed;
}
/**
* Saves the exported artifact URI as annotations on the respective GenPackage.
* @return Whether this method has changed the GenModel instance
*/
protected boolean saveEPackageArtifactURI()
{
List<GenPackage> localGenPackages = new ConverterUtil.GenPackageList();
List<EPackage> externalEPackages = new ConverterUtil.EPackageList();
boolean isLocalGePackage = false;
List<EPackage> ePackages = computeEPackagesToConvert();
for (EPackage ePackage : ePackages)
{
for (Iterator<GenPackage> j = new GenPackagesTreeIterator(getGenModel()); j.hasNext();)
{
GenPackage genPackage = j.next();
if (genPackage.getEcorePackage() == ePackage)
{
isLocalGePackage = localGenPackages.add(genPackage);
break;
}
}
if (!isLocalGePackage)
{
externalEPackages.add(ePackage);
}
else
{
isLocalGePackage = false;
}
}
boolean changed = false;
if (!localGenPackages.isEmpty())
{
URI genModelURI = getGenModel().eResource() != null ?
getGenModel().eResource().getURI() :
null;
Map<String, String> externalPackageToLocalURIMap = new HashMap<String, String>(externalEPackages.size());
for (EPackage ePackage : externalEPackages)
{
String location = getEPackageExportInfo(ePackage).getArtifactLocation();
if (location != null)
{
URI uri = computeArtifactURI(location);
if (genModelURI != null)
{
uri = uri.deresolve(genModelURI);
}
String stringURI = uri.toString();
externalPackageToLocalURIMap.put(ePackage.getNsURI(), stringURI);
}
}
for (GenPackage genPackage : localGenPackages)
{
EPackage ePackage = genPackage.getEcorePackage();
String location = getEPackageExportInfo(ePackage).getArtifactLocation();
if (location != null)
{
GenAnnotation genPackageAnnotation = genPackage.getGenAnnotation(getConverterGenAnnotationSource());
if (genPackageAnnotation == null)
{
genPackageAnnotation = ExporterUtil.findOrCreateGenAnnotation(genPackage, getConverterGenAnnotationSource());
changed = true;
}
URI uri = computeArtifactURI(location);
if (genModelURI != null)
{
uri = uri.deresolve(genModelURI);
}
String stringURI = uri.toString();
GenAnnotation uriAnnotation = genPackageAnnotation.getGenAnnotation(stringURI);
if (uriAnnotation == null)
{
uriAnnotation = ExporterUtil.findOrCreateGenAnnotation(genPackageAnnotation, stringURI);
if (!externalPackageToLocalURIMap.isEmpty())
{
uriAnnotation.getDetails().putAll(externalPackageToLocalURIMap);
}
changed = true;
}
else
{
if (externalPackageToLocalURIMap.isEmpty())
{
if (!uriAnnotation.getDetails().isEmpty())
{
uriAnnotation.getDetails().clear();
changed = true;
}
}
else
{
if (!externalPackageToLocalURIMap.equals(uriAnnotation.getDetails().map()))
{
uriAnnotation.getDetails().clear();
uriAnnotation.getDetails().putAll(externalPackageToLocalURIMap);
changed = true;
}
}
}
}
}
}
return changed;
}
protected String getDefaultArtifactFileName(EPackage ePackage)
{
if (ePackage.eResource() != null && ePackage.getESuperPackage() == null)
{
String fileName = ePackage.eResource().getURI().lastSegment();
int lastIndex = fileName.lastIndexOf('.');
if (lastIndex > 0)
{
return fileName.substring(0, lastIndex);
}
}
return ConverterUtil.getQualifiedName(ePackage);
}
/*
* For debugging purposes. May be removed in the future.
*/
protected void printExportData(ExportData exportData)
{
System.out.println("\nExport Data =======================================");
for (Map.Entry<GenPackage, URI> entry : exportData.genPackageToArtifactURI.entrySet())
{
GenPackage genPackage = entry.getKey();
URI artifactURI = entry.getValue();
List<GenPackage> referencedGenPackages = exportData.genPackageToReferencedGenPackages.get(genPackage);
System.out.println("\nGenPackage: " + genPackage.getNSURI());
System.out.println("Resource: " + genPackage.eResource().getURI());
System.out.println("Artifact: " + artifactURI.toString());
if (referencedGenPackages != null)
{
System.out.println("Referenced GenPackages:");
for (GenPackage referencedGenPackage : referencedGenPackages)
{
System.out.println("\tGenPackage: " + referencedGenPackage.getNSURI());
System.out.println("\tResource: " + referencedGenPackage.eResource().getURI());
}
}
}
if (!exportData.referencedGenPackagesToArtifactURI.isEmpty())
{
System.out.println("\n-Referenced GenPackages-----------------------------");
for (Map.Entry<GenPackage, URI> entry : exportData.referencedGenPackagesToArtifactURI.entrySet())
{
GenPackage genPackage = entry.getKey();
URI artifactURI = entry.getValue();
System.out.println("\nReferenced GenPackage: " + genPackage.getNSURI());
System.out.println("Resource: " + genPackage.eResource().getURI());
System.out.println("Artifact: " + artifactURI.toString());
}
}
System.out.println("\n====================================================");
}
}