/**
* Copyright (c) 2002-2010 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.codegen.ecore.genmodel.impl;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
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.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.emf.codegen.ecore.CodeGenEcorePlugin;
import org.eclipse.emf.codegen.ecore.Generator;
import org.eclipse.emf.codegen.ecore.genmodel.GenAnnotation;
import org.eclipse.emf.codegen.ecore.genmodel.GenBase;
import org.eclipse.emf.codegen.ecore.genmodel.GenClass;
import org.eclipse.emf.codegen.ecore.genmodel.GenClassifier;
import org.eclipse.emf.codegen.ecore.genmodel.GenDataType;
import org.eclipse.emf.codegen.ecore.genmodel.GenEnum;
import org.eclipse.emf.codegen.ecore.genmodel.GenFeature;
import org.eclipse.emf.codegen.ecore.genmodel.GenJDKLevel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenOperation;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenRuntimeVersion;
import org.eclipse.emf.codegen.jet.JETCompiler;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.emf.codegen.merge.java.JControlModel;
import org.eclipse.emf.codegen.merge.java.JMerger;
import org.eclipse.emf.codegen.merge.java.facade.FacadeHelper;
import org.eclipse.emf.codegen.merge.properties.PropertyMerger;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.codegen.util.ImportManager;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
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.common.util.WrappedException;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreValidator;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
/**
*
* An implementation of the model object 'Gen Base'.
*
*
* The following features are implemented:
*
* - {@link org.eclipse.emf.codegen.ecore.genmodel.impl.GenBaseImpl#getGenAnnotations Gen Annotations}
*
*
*
* @generated
*/
public abstract class GenBaseImpl extends EObjectImpl implements GenBase
{
/**
* The cached value of the '{@link #getGenAnnotations() Gen Annotations}' containment reference list.
*
*
* @see #getGenAnnotations()
* @generated
* @ordered
*/
protected EList genAnnotations;
/**
*
*
* @generated modifiable
*/
protected GenBaseImpl()
{
super();
}
/**
*
*
* @generated
*/
@Override
protected EClass eStaticClass()
{
return GenModelPackage.Literals.GEN_BASE;
}
/**
*
*
* @generated
*/
public EList getGenAnnotations()
{
if (genAnnotations == null)
{
genAnnotations = new EObjectContainmentWithInverseEList(GenAnnotation.class, this, GenModelPackage.GEN_BASE__GEN_ANNOTATIONS, GenModelPackage.GEN_ANNOTATION__GEN_BASE);
}
return genAnnotations;
}
/**
*
*
* @generated NOT
*/
public GenAnnotation getGenAnnotation(String source)
{
if (source == null)
{
for (GenAnnotation genAnnotation : getGenAnnotations())
{
if (genAnnotation.getSource() == null)
{
return genAnnotation;
}
}
}
else
{
for (GenAnnotation genAnnotation : getGenAnnotations())
{
if (source.equals(genAnnotation.getSource()))
{
return genAnnotation;
}
}
}
return null;
}
/**
*
*
* @generated
*/
@SuppressWarnings("unchecked")
@Override
public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs)
{
switch (featureID)
{
case GenModelPackage.GEN_BASE__GEN_ANNOTATIONS:
return ((InternalEList)(InternalEList>)getGenAnnotations()).basicAdd(otherEnd, msgs);
}
return super.eInverseAdd(otherEnd, featureID, msgs);
}
/**
*
*
* @generated
*/
@Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
{
switch (featureID)
{
case GenModelPackage.GEN_BASE__GEN_ANNOTATIONS:
return ((InternalEList>)getGenAnnotations()).basicRemove(otherEnd, msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
/**
*
*
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType)
{
switch (featureID)
{
case GenModelPackage.GEN_BASE__GEN_ANNOTATIONS:
return getGenAnnotations();
}
return super.eGet(featureID, resolve, coreType);
}
/**
*
*
* @generated
*/
@SuppressWarnings("unchecked")
@Override
public void eSet(int featureID, Object newValue)
{
switch (featureID)
{
case GenModelPackage.GEN_BASE__GEN_ANNOTATIONS:
getGenAnnotations().clear();
getGenAnnotations().addAll((Collection extends GenAnnotation>)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
*
*
* @generated
*/
@Override
public void eUnset(int featureID)
{
switch (featureID)
{
case GenModelPackage.GEN_BASE__GEN_ANNOTATIONS:
getGenAnnotations().clear();
return;
}
super.eUnset(featureID);
}
/**
*
*
* @generated
*/
@Override
public boolean eIsSet(int featureID)
{
switch (featureID)
{
case GenModelPackage.GEN_BASE__GEN_ANNOTATIONS:
return genAnnotations != null && !genAnnotations.isEmpty();
}
return super.eIsSet(featureID);
}
public GenModel getGenModel()
{
return ((GenBase)eInternalContainer()).getGenModel();
}
public abstract String getName();
public String capName(String name)
{
return CodeGenUtil.capName(name, getGenModel().getLocale());
}
public String uncapName(String name)
{
return CodeGenUtil.uncapName(name, getGenModel().getLocale());
}
public String uncapPrefixedName(String name)
{
return CodeGenUtil.uncapPrefixedName(name, false, getGenModel().getLocale());
}
public String uncapPrefixedName(String name, boolean forceDifferent)
{
return CodeGenUtil.uncapPrefixedName(name, forceDifferent, getGenModel().getLocale());
}
public String safeName(String name)
{
return CodeGenUtil.safeName(name);
}
/**
* @since 2.5
*/
protected String getInterfaceName(String name)
{
String pattern = getGenModel().getInterfaceNamePattern();
return isBlank(pattern) ? name : MessageFormat.format(pattern, name);
}
protected String getImplClassName(String name)
{
String pattern = getGenModel().getClassNamePattern();
return isBlank(pattern) ? (name + "Impl") : MessageFormat.format(pattern, name);
}
public boolean canGenerate()
{
return getGenModel() != null && getGenModel().canGenerate() && hasModelContribution();
}
protected boolean hasModelContribution()
{
return false;
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.Generator Generator} should be used to generate code.
* This method will be removed after 2.2.
*/
@Deprecated
public final void generate(IProgressMonitor progressMonitor)
{
generate(BasicMonitor.toMonitor(progressMonitor));
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.Generator Generator} should be used to generate code.
* This method will be removed after 2.2.
*/
@Deprecated
public final void gen(Monitor progressMonitor)
{
generate(progressMonitor);
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.Generator Generator} should be used to generate code.
* This method will be removed after 2.2.
*/
@Deprecated
public void generate(Monitor progressMonitor)
{
// Does nothing
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected void generate(Monitor progressMonitor, int style, List pluginVariables, String outputFilePath, JETEmitter jetEmitter)
{
try
{
URI outputURI = URI.createPlatformResourceURI(outputFilePath.substring(0, outputFilePath.lastIndexOf("/")));
progressMonitor.beginTask("", 3);
progressMonitor.subTask(CodeGenEcorePlugin.INSTANCE.getString("_UI_GeneratingFile_message", new Object [] { outputFilePath }));
if (findOrCreateContainer(createMonitor(progressMonitor, 1), style, pluginVariables, outputURI, false))
{
URI targetFile = outputURI.appendSegment(outputFilePath.substring(outputFilePath.lastIndexOf("/") + 1));
if (exists(targetFile) && (outputFilePath.endsWith("/build.properties") || !outputFilePath.endsWith(".properties")))
{
return;
}
//We are not generating the manifest file if the plugin.xml exists.
//
if (outputFilePath.endsWith("/META-INF/MANIFEST.MF") && exists(targetFile.trimSegments(2).appendSegment("plugin.xml")))
{
return;
}
boolean changed = false;
boolean isUnicodeEscapeEncoded = outputFilePath.endsWith(".properties");
String emitterResult = jetEmitter.generate(createMonitor(progressMonitor, 1), new Object [] { this });
if (isUnicodeEscapeEncoded)
{
emitterResult = unicodeEscapeEncode(emitterResult);
}
progressMonitor.worked(1);
byte [] bytes = emitterResult.toString().getBytes(isUnicodeEscapeEncoded ? "ISO-8859-1" : "UTF-8");
if (exists(targetFile))
{
// Don't overwrite exising file
PropertyMerger propertyMerger = new PropertyMerger();
propertyMerger.setSourceProperties(emitterResult);
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_ExaminingOld_message", new Object [] { targetFile }));
String oldProperties = propertyMerger.createPropertiesForInputStream(createInputStream(targetFile));
propertyMerger.setTargetProperties(oldProperties);
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_PreparingNew_message", new Object [] { targetFile }));
propertyMerger.merge();
progressMonitor.worked(1);
String mergedResult = propertyMerger.getTargetProperties();
changed = !mergedResult.equals(oldProperties);
if (changed)
{
if (isReadOnly(targetFile) && EclipseUtil.validateEdit(targetFile.toString(), createMonitor(progressMonitor, 1)))
{
propertyMerger.setTargetProperties(propertyMerger.createPropertiesForInputStream(createInputStream(targetFile)));
propertyMerger.merge();
mergedResult = propertyMerger.getTargetProperties();
}
bytes = mergedResult.getBytes(isUnicodeEscapeEncoded ? "ISO-8859-1" : "UTF-8");
}
}
else
{
changed = true;
}
if (changed)
{
String redirection = getGenModel().getRedirection();
boolean redirect = redirection != null && redirection.indexOf("{0}") != -1;
// Use an alternate if we can't write to this one.
//
if (redirect)
{
String baseName = MessageFormat.format(redirection, new Object [] { targetFile.lastSegment() });
targetFile = outputURI.appendSegment(baseName);
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_UsingAlternate_message", new Object [] { targetFile }));
}
if (isReadOnly(targetFile))
{
if (getGenModel().isForceOverwrite())
{
setOverwriteable(targetFile);
}
else
{
targetFile = outputURI.appendSegment("." + targetFile.lastSegment() + ".new");
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_UsingDefaultAlternate_message", new Object [] { targetFile }));
}
}
OutputStream outputStream = createOutputStream(targetFile);
outputStream.write(bytes);
outputStream.close();
}
}
}
catch (Exception exception)
{
CodeGenEcorePlugin.INSTANCE.log(exception);
}
finally
{
progressMonitor.done();
}
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@Deprecated
protected Monitor createMonitor(Monitor monitor, int ticks)
{
return CodeGenUtil.createMonitor(monitor, ticks);
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected void generate
(Monitor progressMonitor,
int style,
List pluginVariables,
String outputFilePath,
GIFEmitter gifEmitter,
String key)
{
generate(progressMonitor, style, pluginVariables, outputFilePath, gifEmitter, key, null);
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected void generate
(Monitor progressMonitor,
int style,
List pluginVariables,
String outputFilePath,
GIFEmitter gifEmitter,
String parentKey,
String childKey)
{
try
{
URI outputURI = URI.createPlatformResourceURI(outputFilePath.substring(0, outputFilePath.lastIndexOf("/")));
progressMonitor.beginTask("", 3);
progressMonitor.subTask(CodeGenEcorePlugin.INSTANCE.getString("_UI_GeneratingImage_message", new Object [] { outputFilePath }));
if (findOrCreateContainer(createMonitor(progressMonitor, 1), style, pluginVariables, outputURI, false))
{
URI targetFile = outputURI.appendSegment(outputFilePath.substring(outputFilePath.lastIndexOf("/") + 1));
if (exists(targetFile))
{
// Don't overwrite exising file
}
else
{
byte[] emitterResult = gifEmitter.generateGIF(parentKey, childKey);
progressMonitor.worked(1);
OutputStream outputStream = createOutputStream(targetFile);
outputStream.write(emitterResult);
outputStream.close();
}
}
}
catch (Exception exception)
{
CodeGenEcorePlugin.INSTANCE.log(exception);
}
progressMonitor.done();
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@SuppressWarnings("rawtypes")
@Deprecated
public void gen
(Monitor progressMonitor,
int style,
List pluginVariables,
String targetDirectory,
String packageName,
String className,
JETEmitter jetEmitter)
{
generate(progressMonitor, style, pluginVariables, targetDirectory, packageName, className, jetEmitter, new Object [] { this });
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected void generate
(Monitor progressMonitor,
int style,
List pluginVariables,
String targetDirectory,
String packageName,
String className,
JETEmitter jetEmitter)
{
generate(progressMonitor, style, pluginVariables, targetDirectory, packageName, className, jetEmitter, new Object [] { this });
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected void generate
(Monitor progressMonitor,
int style,
List pluginVariables,
String targetDirectory,
String packageName,
String className,
JETEmitter jetEmitter,
Object [] arguments)
{
try
{
URI outputURI = URI.createPlatformResourceURI(targetDirectory).appendSegments(packageName.split("\\."));
progressMonitor.beginTask("", 4);
if (findOrCreateContainer(createMonitor(progressMonitor, 1), style, pluginVariables, outputURI, false))
{
// Create an import manager for this compilation unit
ImportManager importManager = new ImportManager(packageName);
importManager.addMasterImport(packageName, className);
setImportManager(importManager);
String emitterResult = jetEmitter.generate(createMonitor(progressMonitor, 1), arguments );
progressMonitor.worked(1);
boolean changed = true;
URI targetFile = outputURI.appendSegment(className + ".java");
progressMonitor.subTask(CodeGenEcorePlugin.INSTANCE.getString("_UI_Generating_message", new Object [] { targetFile }));
String newContents = emitterResult;
JControlModel jControlModel = getGenModel().getJControlModel();
if (getGenModel().getFacadeHelperClass() != null && (jControlModel.getFacadeHelper() == null || !jControlModel.getFacadeHelper().getClass().getName().equals(getGenModel().getFacadeHelperClass())))
{
FacadeHelper facadeHelper = CodeGenUtil.instantiateFacadeHelper(getGenModel().getFacadeHelperClass());
jControlModel.initialize(facadeHelper, getGenModel().getMergeRulesLocation());
}
if (jControlModel.canMerge())
{
JMerger jMerger = new JMerger(jControlModel);
jMerger.setFixInterfaceBrace(jControlModel.getFacadeHelper().fixInterfaceBrace());
jMerger.setSourceCompilationUnit(jMerger.createCompilationUnitForContents(emitterResult));
// Create a code formatter for this compilation unit, if needed
CodeFormatter codeFormatter = getGenModel().isCodeFormatting() ? getGenModel().createCodeFormatter() : null;
if (exists(targetFile))
{
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_ExaminingOld_message", new Object [] { targetFile }));
jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForInputStream(createInputStream(targetFile), getEncoding(targetFile)));
String oldContents = jMerger.getTargetCompilationUnitContents();
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_PreparingNew_message", new Object [] { targetFile }));
jMerger.merge();
progressMonitor.worked(1);
newContents = formatCode(jMerger.getTargetCompilationUnitContents(), codeFormatter);
changed = !oldContents.equals(newContents);
if (changed)
{
if (isReadOnly(targetFile) && EclipseUtil.validateEdit(targetFile.toString(), createMonitor(progressMonitor, 1)))
{
jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForInputStream(createInputStream(targetFile), getEncoding(targetFile)));
jMerger.remerge();
newContents = formatCode(jMerger.getTargetCompilationUnitContents(), codeFormatter);
}
}
}
else
{
changed = true;
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_PreparingNew_message", new Object [] { targetFile }));
jMerger.merge();
newContents = formatCode(jMerger.getTargetCompilationUnitContents(), codeFormatter);
}
if (jControlModel.getFacadeHelper() != null)
{
jControlModel.getFacadeHelper().reset();
}
}
else
{
newContents =
CodeGenUtil.convertFormat(jControlModel.getLeadingTabReplacement(), jControlModel.convertToStandardBraceStyle(), emitterResult);
if (exists(targetFile))
{
String oldContents = getContents(targetFile);
changed = !oldContents.equals(newContents);
}
else
{
changed = true;
}
}
if (changed)
{
//purpose: using charset from 'targetFile' to encode in-memory
// 'newContents' object into bytes
//modifer: Wu Zhi Qiang
//date: Aug 25, 2004
//action: first get the charset from 'targetFile', then use it
// to encode the 'newContents' object into bytes
String encoding = getEncoding(targetFile);
byte[] bytes = encoding == null
? newContents.getBytes()
: newContents.getBytes(encoding);
// InputStream contents = new ByteArrayInputStream(bytes);
String redirection = getGenModel().getRedirection();
boolean redirect = redirection != null && redirection.indexOf("{0}") != -1;
// Use an alternate if we can't write to this one.
//
if (redirect)
{
String baseName = MessageFormat.format(redirection, new Object [] { className + ".java" });
targetFile = outputURI.appendSegment(baseName);
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_UsingAlternate_message", new Object [] { targetFile }));
}
if (isReadOnly(targetFile))
{
if (getGenModel().isForceOverwrite())
{
setOverwriteable(targetFile);
}
else
{
targetFile = outputURI.appendSegment("." + className + ".java.new");
progressMonitor.subTask
(CodeGenEcorePlugin.INSTANCE.getString("_UI_UsingDefaultAlternate_message", new Object [] { targetFile }));
}
}
OutputStream outputStream = createOutputStream(targetFile);
outputStream.write(bytes);
outputStream.close();
}
}
}
catch (JETException exception)
{
CodeGenEcorePlugin.INSTANCE.log(exception);
}
catch (Exception exception)
{
CodeGenEcorePlugin.INSTANCE.log(exception);
}
// Clear the import manager
setImportManager(null);
progressMonitor.done();
}
protected ImportManager getImportManager()
{
return getGenModel().getImportManager();
}
protected void setImportManager(ImportManager importManager)
{
getGenModel().setImportManager(importManager);
}
/**
* @deprecated In EMF 2.2, a {@link org.eclipse.emf.codegen.ecore.generator.GeneratorAdapter GeneratorAdapter} should be used to
* implement code generation. {@link org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter AbstractGeneratorAdapter} provides
* an equivalent to this method. This method will be removed after 2.2.
*/
@Deprecated
protected String formatCode(String contents, CodeFormatter codeFormatter)
{
return
EMFPlugin.IS_ECLIPSE_RUNNING && getGenModel().isCodeFormatting() ?
EclipseUtil.formatCode(contents, codeFormatter) :
contents;
}
/**
* @deprecated in 2.2. Please use {@link #format(String, char, String, boolean, boolean)} instead.
*/
@Deprecated
public String format(String name, char separator, String prefix, boolean includePrefix)
{
return CodeGenUtil.format(name, separator, prefix, includePrefix);
}
/**
* @since 2.2.
*/
protected String format(String name, char separator, String prefix, boolean includePrefix, boolean includeLeadingSeparator)
{
return CodeGenUtil.format(name, separator, prefix, includePrefix, includeLeadingSeparator);
}
/**
* This method was used to break sourceName into words delimited by sourceSeparator and/or mixed-case naming.
* Now, it simply returns an empty list.
* @deprecated in 2.1.0. Use {@link CodeGenUtil#parseName(String, char)} instead.
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected final List parseName(String sourceName, char sourceSeparator)
{
return Collections.EMPTY_LIST;
}
protected List getAllGenPackages()
{
GenModel genModel = getGenModel();
List genPackages = genModel.getGenPackages();
List usedGenPackages = genModel.getUsedGenPackages();
List staticGenPackages = genModel.getStaticGenPackages();
List result = new ArrayList(genPackages.size() + usedGenPackages.size() + staticGenPackages.size());
result.addAll(genPackages);
result.addAll(usedGenPackages);
result.addAll(staticGenPackages);
return result;
}
/**
* Finds the GenPackage corresponding to the EPackage, taking into account any nested GenPackages.
*/
protected GenPackage findGenPackageHelper(GenPackage genPackage, EPackage ePackage)
{
if (genPackage.getEcorePackage() != null)
{
if (ePackage.getNsURI() == null ?
genPackage.getEcorePackage().getNsURI() == null :
ePackage.getNsURI().equals(genPackage.getEcorePackage().getNsURI())) //FB TBD different objects for ecore model!
{
return genPackage;
}
for (GenPackage nestedGenPackage : genPackage.getNestedGenPackages())
{
GenPackage nestedResult = findGenPackageHelper(nestedGenPackage, ePackage);
if (nestedResult != null)
{
return nestedResult;
}
}
}
return null;
}
// protected static GenPackage ecoreGenPackage;
// protected static GenPackage xmlTypeGenPackage;
// protected static GenPackage xmlNamespaceGenPackage;
public GenPackage findGenPackage(EPackage ePackage)
{
return getGenModel().findGenPackage(ePackage);
}
protected GenClass findGenClass(EClass eClass)
{
return ((GenModelImpl)getGenModel()).findGenClass(eClass);
}
protected GenEnum findGenEnum(EEnum eEnum)
{
return ((GenModelImpl)getGenModel()).findGenEnum(eEnum);
}
protected GenDataType findGenDataType(EDataType eDataType)
{
return ((GenModelImpl)getGenModel()).findGenDataType(eDataType);
}
protected GenClassifier findGenClassifier(EClassifier eClassifier)
{
if (eClassifier instanceof EClass)
{
return findGenClass((EClass)eClassifier);
}
else if (eClassifier instanceof EEnum)
{
return findGenEnum((EEnum)eClassifier);
}
else if (eClassifier instanceof EDataType)
{
return findGenDataType((EDataType)eClassifier);
}
else
{
return null;
}
}
protected GenFeature findGenFeature(EStructuralFeature eStructuralFeature)
{
GenClass genClass = findGenClass(eStructuralFeature.getEContainingClass());
for (GenFeature genFeature : genClass.getGenFeatures())
{
if (eStructuralFeature.getName().equals(genFeature.getEcoreFeature().getName())) //FB TBD different objects for ecore model!
{
return genFeature;
}
}
return null;
}
protected GenOperation findGenOperation(EOperation eOperation)
{
GenClass genClass = findGenClass(eOperation.getEContainingClass());
genOperationsLoop: for (GenOperation genOperation : genClass.getGenOperations())
{
EOperation ecoreOperation = genOperation.getEcoreOperation();
if (eOperation.getName().equals(ecoreOperation.getName())
&& eOperation.getEParameters().size() == ecoreOperation.getEParameters().size())
{
for (int j = 0; j < eOperation.getEParameters().size(); j++)
{
EParameter ecoreParameter = eOperation.getEParameters().get(j);
if (!ecoreParameter.getEType().getName().equals((ecoreOperation.getEParameters().get(j)).getEType().getName()))
{
continue genOperationsLoop;
}
}
return genOperation;
}
}
return null;
}
protected GenJDKLevel getEffectiveComplianceLevel()
{
return getGenModel().getComplianceLevel();
}
protected boolean isEffectiveSuppressEMFTypes()
{
return getGenModel().isSuppressEMFTypes();
}
protected String getEffectiveMapType(GenClass context, EGenericType eGenericType, GenClass genClass)
{
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50 && eGenericType.getETypeArguments().size() == 2)
{
String mapType = getEffectiveMapType();
String keyType = getTypeArgument(context, eGenericType.getETypeArguments().get(0), true, false);
String valueType = getTypeArgument(context, eGenericType.getETypeArguments().get(1), true, false);
mapType += "<" + keyType + ", " + valueType + ">";
return mapType;
}
else
{
return getEffectiveMapType(context, genClass);
}
}
protected String getEffectiveMapType(GenClass context, GenClass genClass)
{
String mapType = getEffectiveMapType();
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50)
{
String keyType = genClass.getMapEntryKeyFeature().getType(context);
String valueType = genClass.getMapEntryValueFeature().getType(context);
mapType += "<" + keyType + ", " + valueType + ">";
}
return mapType;
}
protected String getEffectiveMapType()
{
return isEffectiveSuppressEMFTypes() ? "java.util.Map" : "org.eclipse.emf.common.util.EMap";
}
protected String getEffectiveMapEntryType(GenClass context, EGenericType eGenericType, GenClass genClass)
{
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50 && eGenericType.getETypeArguments().size() == 2)
{
String mapType = getEffectiveMapEntryType();
String keyType = getTypeArgument(context, eGenericType.getETypeArguments().get(0), false, false);
String valueType = getTypeArgument(context, eGenericType.getETypeArguments().get(1), false, false);
mapType += "<" + keyType + ", " + valueType + ">";
return mapType;
}
else
{
return getEffectiveMapEntryType(context, genClass);
}
}
protected String getEffectiveMapEntryType(GenClass context, GenClass genClass)
{
String mapType = getEffectiveMapEntryType();
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50)
{
GenFeature mapEntryKeyFeature = genClass.getMapEntryKeyFeature();
GenFeature mapEntryValueFeature = genClass.getMapEntryValueFeature();
if (mapEntryKeyFeature.getTypeGenClassifier() != genClass && mapEntryValueFeature.getTypeGenClassifier() != genClass)
{
String keyType = mapEntryKeyFeature.getType(context);
String valueType = mapEntryValueFeature.getType(context);
mapType += "<" + keyType + ", " + valueType + ">";
}
}
return mapType;
}
protected String getEffectiveMapEntryType()
{
return "java.util.Map$Entry";
}
protected String getEffectiveListType(GenClass context, EGenericType eGenericType)
{
String listType = getEffectiveListType();
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50)
{
String itemType = getType(context, eGenericType, true);
listType += "<" + itemType + ">";
}
return listType;
}
protected String getEffectiveListType(GenClass context, EClassifier eType)
{
String listType = getEffectiveListType();
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50)
{
String itemType = getType(context, eType, true);
listType += "<" + itemType + ">";
}
return listType;
}
protected String getEffectiveListType()
{
return isEffectiveSuppressEMFTypes() ? "java.util.List" : "org.eclipse.emf.common.util.EList";
}
protected String getEffectiveEObjectType()
{
return isEffectiveSuppressEMFTypes() ? "java.lang.Object" : "org.eclipse.emf.ecore.EObject";
}
protected String getEffectiveFeatureMapWrapperInterface()
{
String result = getGenModel().getFeatureMapWrapperInterface();
return isBlank(result) ? "org.eclipse.emf.ecore.util.FeatureMap" : result;
}
protected String getImportedEffectiveFeatureMapWrapperInternalInterface()
{
String result = getGenModel().getFeatureMapWrapperInternalInterface();
return getGenModel().getImportedName(isBlank(result) ? "org.eclipse.emf.ecore.util.FeatureMap" : result);
}
protected String getImportedEffectiveFeatureMapWrapperClass()
{
String result = getGenModel().getFeatureMapWrapperClass();
return getGenModel().getImportedName(isBlank(result) ? "org.eclipse.emf.ecore.util.FeatureMap" : result);
}
protected Class> getInstanceClass(EClassifier eType)
{
try
{
Class> instanceClass = eType.getInstanceClass();
return instanceClass;
}
catch (Exception e)
{
return null;
}
}
protected boolean isPrimitiveType(EClassifier eType)
{
return CodeGenUtil.isJavaPrimitiveType(eType.getInstanceClassName());
}
protected String getPrimitiveObjectType(EClassifier eType)
{
Class> instanceClass = getInstanceClass(eType);
if (instanceClass == java.lang.Boolean.TYPE)
return "java.lang.Boolean";
if (instanceClass == java.lang.Byte.TYPE)
return "java.lang.Byte";
if (instanceClass == java.lang.Character.TYPE)
return "java.lang.Character";
if (instanceClass == java.lang.Double.TYPE)
return "java.lang.Double";
if (instanceClass == java.lang.Float.TYPE)
return "java.lang.Float";
if (instanceClass == java.lang.Integer.TYPE)
return "java.lang.Integer";
if (instanceClass == java.lang.Long.TYPE)
return "java.lang.Long";
if (instanceClass == java.lang.Short.TYPE)
return "java.lang.Short";
return null;
}
protected String getPrimitiveDefault(EClassifier eType)
{
if (isPrimitiveType(eType))
{
Class> instanceClass = eType.getInstanceClass();
if (instanceClass == java.lang.Boolean.TYPE)
return "false";
if (instanceClass == java.lang.Byte.TYPE ||
instanceClass == java.lang.Integer.TYPE ||
instanceClass == java.lang.Long.TYPE ||
instanceClass == java.lang.Short.TYPE)
return "0";
if (instanceClass == java.lang.Character.TYPE)
return "'\\u0000'";
if (instanceClass == java.lang.Double.TYPE)
return "0.0";
if (instanceClass == java.lang.Float.TYPE)
return "0.0F";
}
return null;
}
protected boolean hasReferenceToClassifierWithInstanceTypeName(List extends EGenericType> eGenericTypes)
{
for (EGenericType eGenericType : eGenericTypes)
{
if (hasReferenceToClassifierWithInstanceTypeName(eGenericType))
{
return true;
}
}
return false;
}
protected boolean hasReferenceToClassifierWithInstanceTypeName(EGenericType eGenericType)
{
EClassifier eClassifier = eGenericType.getEClassifier();
if (eClassifier != null)
{
return
eClassifier.eIsSet(EcorePackage.Literals.ECLASSIFIER__INSTANCE_CLASS_NAME) ||
eClassifier.eIsSet(EcorePackage.Literals.ECLASSIFIER__INSTANCE_TYPE_NAME) ||
hasReferenceToClassifierWithInstanceTypeName(eGenericType.getETypeArguments());
}
else
{
ETypeParameter eTypeParameter = eGenericType.getETypeParameter();
if (eTypeParameter != null)
{
return false;
}
else
{
EGenericType eUpperBound = eGenericType.getEUpperBound();
if (eUpperBound != null)
{
return hasReferenceToClassifierWithInstanceTypeName(eUpperBound);
}
else
{
EGenericType eLowerBound = eGenericType.getELowerBound();
if (eLowerBound != null)
{
return hasReferenceToClassifierWithInstanceTypeName(eLowerBound);
}
}
}
}
return false;
}
protected String getEcoreType(EGenericType eGenericType)
{
StringBuilder result = new StringBuilder();
boolean useGenerics = getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50;
EClassifier eClassifier = useGenerics ? eGenericType.getEClassifier() : eGenericType.getERawType();
if (eClassifier != null)
{
GenClassifier genClassifier = findGenClassifier(eClassifier);
if (genClassifier != null)
{
result.append(genClassifier.getGenPackage().getInterfacePackageName());
result.append('.');
result.append(genClassifier.getName());
}
if (useGenerics)
{
EList eTypeArguments = eGenericType.getETypeArguments();
if (!eTypeArguments.isEmpty())
{
result.append('<');
for (int i = 0, size = eTypeArguments.size(); i < size; ++i)
{
if (i != 0)
{
result.append(", ");
}
result.append(getEcoreType(eTypeArguments.get(i)));
}
result.append('>');
}
}
}
else
{
ETypeParameter eTypeParameter = eGenericType.getETypeParameter();
if (eTypeParameter != null)
{
result.append(eTypeParameter.getName());
}
else
{
result.append('?');
EGenericType eUpperBound = eGenericType.getEUpperBound();
if (eUpperBound != null)
{
result.append(" extends ");
result.append(getEcoreType(eUpperBound));
}
else
{
EGenericType eLowerBound = eGenericType.getELowerBound();
if (eLowerBound != null)
{
result.append(" super ");
result.append(getEcoreType(eLowerBound));
}
}
}
}
return result.toString();
}
/**
* Returns the primitive or qualified class name for the given
* EClassifier. If primitiveAsObject is true, wrapper object names will
* be returned instead of primitive names (e.g. java.lang.Integer instead
* of int).
*/
protected String getType(GenClass context, EClassifier eType, boolean primitiveAsObject)
{
return getType(context, eType, primitiveAsObject, false);
}
protected String getType(GenClass context, EClassifier eType, boolean primitiveAsObject, boolean erased)
{
if (eType instanceof EClass)
{
GenClass genClass = (context == null ? this : (GenBaseImpl)context).findGenClass((EClass)eType);
return genClass == null ? "java.lang.Void" : genClass.getQualifiedInterfaceName();
}
if (eType instanceof EEnum)
{
GenEnum genEnum = (context == null ? this : (GenBaseImpl)context).findGenEnum((EEnum)eType);
return genEnum == null ? "java.lang.Enum" : genEnum.getQualifiedName();
}
//(eType instanceof EDataType)
if (primitiveAsObject && isPrimitiveType(eType))
{
return getPrimitiveObjectType(eType);
}
if ("org.eclipse.emf.common.util.Enumerator".equals(eType.getInstanceClassName()))
{
for (EDataType baseType = getExtendedMetaData().getBaseType((EDataType)eType);
baseType != null;
baseType = getExtendedMetaData().getBaseType(baseType))
{
if (baseType instanceof EEnum)
{
GenEnum genEnum = findGenEnum((EEnum)baseType);
if (genEnum != null)
{
return genEnum.getQualifiedName();
}
}
}
}
if (isRemappedXMLType(eType))
{
return "java.lang.Object";
}
String instanceTypeName = eType.getInstanceTypeName();
if (getEffectiveComplianceLevel().getValue() < GenJDKLevel.JDK50 || isPrimitiveType(eType) || erased && (instanceTypeName == null || !instanceTypeName.contains(".")))
{
return eType.getInstanceClassName();
}
else
{
Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(instanceTypeName);
EGenericType eGenericType = (EGenericType)diagnostic.getData().get(0);
return getTypeArgument(context, eGenericType, false, erased);
}
}
/**
* Returns the primitive or class name for the given EClassifier. Class
* names will be added as imports to the GenModel's ImportManager, and the
* imported form will be returned. If primitiveAsObject is true, wrapper
* object names will be returned instead of primitive names (e.g. Integer
* instead of int).
*/
protected String getImportedType(GenClass context, EGenericType eGenericType, boolean primitiveAsObject)
{
String t = getType(context, eGenericType, primitiveAsObject);
return !primitiveAsObject && isPrimitiveType(eGenericType.getERawType()) ? t : getGenModel().getImportedName(t);
}
/**
* Returns the primitive or qualified class name for the given
* EClassifier. If primitiveAsObject is true, wrapper object names will
* be returned instead of primitive names (e.g. java.lang.Integer instead
* of int).
*/
protected String getType(GenClass context, EGenericType eGenericType, boolean primitiveAsObject)
{
if (getEffectiveComplianceLevel().getValue() >= GenJDKLevel.JDK50)
{
return
primitiveAsObject && isPrimitiveType(eGenericType.getERawType()) ?
getPrimitiveObjectType(eGenericType.getERawType()) :
getTypeArgument(context, eGenericType, false, false);
}
else
{
return getType(context, eGenericType.getERawType(), primitiveAsObject);
}
}
/**
* Returns the primitive or class name for the given EClassifier. Class
* names will be added as imports to the GenModel's ImportManager, and the
* imported form will be returned. If primitiveAsObject is true, wrapper
* object names will be returned instead of primitive names (e.g. Integer
* instead of int).
*/
protected String getImportedType(GenClass context, EClassifier eType, boolean primitiveAsObject)
{
return getImportedType(context, eType, primitiveAsObject, false);
}
protected String getImportedType(GenClass context, EClassifier eType, boolean primitiveAsObject, boolean erased)
{
String t = getType(context, eType, primitiveAsObject, erased);
return !primitiveAsObject && isPrimitiveType(eType) ? t : getGenModel().getImportedName(t);
}
/**
* If eType is an EClass, returns the list of GenClasses representing its
* non-abstract subclasses, beginning with those from the specified
* firstGenPackage followed by the others in genPackages, and ordered down
* the inheritance chains within each package. Stops searching after
* max GenClasses are found; -1 for no limit. If eType corresponds to an
* anonymous complex type, only that class itself is returned; otherwise,
* no such anonymous classes are included.
*/
protected List getTypeGenClasses(EClassifier eType, GenPackage firstGenPackage, List genPackages, int max)
{
if (max == 0 || !(eType instanceof EClass)) return Collections.emptyList();
boolean hasMax = max > -1;
List result = new ArrayList();
EClass baseClass = (EClass)eType;
ExtendedMetaData extendedMetaData = getExtendedMetaData();
if (extendedMetaData.isAnonymous(baseClass))
{
result.add(findGenClass(baseClass));
return result;
}
// order genPackages by putting firstGenPackage (if non-null) first
List orderedGenPackages = genPackages;
if (firstGenPackage != null)
{
orderedGenPackages = new ArrayList(genPackages.size() + 1);
orderedGenPackages.add(firstGenPackage);
for (GenPackage genPackage : genPackages)
{
if (genPackage != firstGenPackage) orderedGenPackages.add(genPackage);
}
}
for (GenPackage genPackage : orderedGenPackages)
{
if (baseClass == EcorePackage.Literals.EOBJECT)
{
for (GenClass genClass : genPackage.getOrderedGenClasses())
{
if (!genClass.isAbstract() && !extendedMetaData.isAnonymous(genClass.getEcoreClass()))
{
result.add(genClass);
if (hasMax && result.size() >= max) return result;
}
}
}
else
{
for (GenClass genClass : genPackage.getOrderedGenClasses())
{
if (!genClass.isAbstract() &&
baseClass.isSuperTypeOf(genClass.getEcoreClass()) &&
!extendedMetaData.isAnonymous(genClass.getEcoreClass()))
{
result.add(genClass);
if (hasMax && result.size() >= max) return result;
}
}
}
}
return result;
}
/**
* Returns a hash of all Java's keywords and textual literals, as of Java
* 1.4.
* @deprecated
*/
@SuppressWarnings("rawtypes")
@Deprecated
protected static Set getJavaReservedWords()
{
return CodeGenUtil.getJavaReservedWords();
}
/**
* @deprecated
*/
@Deprecated
@SuppressWarnings("rawtypes")
protected static Set getJavaLangTypes()
{
return CodeGenUtil.getJavaDefaultTypes();
}
protected static interface GenClassFilter
{
boolean accept(GenClass genClass);
}
protected static interface GenFeatureFilter
{
boolean accept(GenFeature genFeature);
}
protected static interface GenOperationFilter
{
boolean accept(GenOperation genOperation);
}
protected static interface GenConstraintFilter
{
boolean accept(String genConstraint);
}
/**
* Return all GenClasses in the specified genClasses list that are
* accepted by filter; all are accepted if filter is null.
*/
protected List filterGenClasses(List genClasses, GenClassFilter filter)
{
List result = new ArrayList();
for (GenClass genClass : genClasses)
{
if (filter == null || filter.accept(genClass))
{
result.add(genClass);
}
}
return result;
}
/**
* Iterate over the specified eClasses list, finding the GenClass
* corresponding to each EClass. Return all such GenClasses if filter is
* null, or those accepted by filter, otherwise.
*/
protected List collectGenClasses(List eClasses, GenClassFilter filter)
{
GenModelImpl genModelImpl = (GenModelImpl)getGenModel();
List result = new ArrayList();
for (int i = 0, size = eClasses.size(); i < size; ++i)
{
GenClass genClass = genModelImpl.findGenClass(eClasses.get(i));
if (genClass != null && (filter == null || filter.accept(genClass)))
{
result.add(genClass);
}
}
return result;
}
/**
* Iterate over the lists returned by calling getGenFeatures() on items in
* the list of genClasses, and then over the list of genFeatures. Return
* all such GenFeatures if filter is null, or those accepted by filter,
* otherwise. Either list argument is ignored if it is null.
*/
protected List collectGenFeatures(List genClasses, List genFeatures, GenFeatureFilter filter)
{
List result = new ArrayList();
if (genClasses != null)
{
for (int i = 0, iSize = genClasses.size(); i < iSize; ++i)
{
GenClass genClass = genClasses.get(i);
List features = genClass.getGenFeatures();
if (filter == null)
{
result.addAll(features);
}
else
{
for (int j = 0, jSize = features.size(); j < jSize; ++j)
{
GenFeature genFeature = features.get(j);
if (filter.accept(genFeature))
{
result.add(genFeature);
}
}
}
}
}
if (genFeatures != null)
{
if (filter == null)
{
result.addAll(genFeatures);
}
else
{
for (int i = 0, size = genFeatures.size(); i < size; ++i)
{
GenFeature genFeature = genFeatures.get(i);
if (filter.accept(genFeature))
{
result.add(genFeature);
}
}
}
}
return result;
}
/**
* Iterate over the lists returned by calling getGenOperations() on items
* in the list of genClasses, and then over the list of genOperations.
* Return all such GenOperations if filter is null, or those accepted by
* filter, otherwise. Either list argument is ignored if it is null.
*/
protected List collectGenOperations(GenClass context, List genClasses, List genOperations, GenOperationFilter filter)
{
return collectGenOperations(context, genClasses, genOperations, filter, true);
}
/**
* @since 2.6
*/
protected List collectGenOperations(GenClass context, List genClasses, List genOperations, GenOperationFilter filter, boolean excludeOverrides)
{
List result = new ArrayList();
if (genClasses != null)
{
for (GenClass genClass : genClasses)
{
LOOP:
for (GenOperation genOperation : genClass.getGenOperations())
{
if (filter == null || filter.accept(genOperation))
{
if (excludeOverrides)
{
for (GenOperation otherGenOperation : result)
{
if (otherGenOperation.isOverrideOf(context, genOperation))
{
continue LOOP;
}
}
}
result.add(genOperation);
}
}
}
}
if (genOperations != null)
{
LOOP:
for (GenOperation genOperation : genOperations)
{
if (filter == null || filter.accept(genOperation))
{
if (excludeOverrides)
{
for (GenOperation otherGenOperation : result)
{
if (otherGenOperation.isOverrideOf(context, genOperation))
{
continue LOOP;
}
}
}
result.add(genOperation);
}
}
}
return result;
}
/**
* Iterate over the lists returned by calling getGenConstraints() on items in
* the list of genClassifiers, and then over the list of genConstraints. Return
* all such constraint if filter is null, or those accepted by filter,
* otherwise. Either list argument is ignored if it is null.
*/
protected List collectGenConstraints(List extends GenClassifier> genClassifiers, List genConstraints, GenConstraintFilter filter)
{
List result = new UniqueEList();
if (genClassifiers != null)
{
for (GenClassifier genClassifier : genClassifiers)
{
for (String genConstraint : genClassifier.getGenConstraints())
{
if (filter == null || filter.accept(genConstraint))
{
result.add(genConstraint);
}
}
}
}
if (genConstraints != null)
{
for (String genConstraint : genConstraints)
{
if (filter == null || filter.accept(genConstraint))
{
result.add(genConstraint);
}
}
}
return result;
}
public String getModelInfo()
{
return "";
}
protected static interface AnnotationFilter
{
boolean accept(EModelElement eModelElement, String source, String key, String value);
}
protected static class AnnotationFilterImpl implements AnnotationFilter
{
public AnnotationFilterImpl()
{
super();
}
public boolean accept(EModelElement eModelElement, String source, String key, String value)
{
return !(GenModelPackage.eNS_URI.equals(source) && ("documentation".equals(key) || "copyright".equals(key)));
}
}
protected static final AnnotationFilter DEFAULT_ANNOTATION_FILTER = new AnnotationFilterImpl();
protected List getAnnotationInfo(EModelElement eModelElement)
{
return getAnnotationInfo(eModelElement, DEFAULT_ANNOTATION_FILTER);
}
protected List getAnnotationInfo(EModelElement eModelElement, AnnotationFilter annotationFilter)
{
List result = Collections.emptyList();
for (EAnnotation eAnnotation : eModelElement.getEAnnotations())
{
String source = eAnnotation.getSource();
if (source != null)
{
StringBuffer stringBuffer = null;
for (Map.Entry entry : eAnnotation.getDetails())
{
String key = entry.getKey();
String value = entry.getValue();
if (annotationFilter.accept(eModelElement, source, key, value))
{
if (stringBuffer == null)
{
stringBuffer = new StringBuffer(escapeString(source, " ="));
}
stringBuffer.append(' ');
stringBuffer.append(escapeString(key, " ="));
stringBuffer.append("=\'");
stringBuffer.append(escapeString(value, ""));
stringBuffer.append('\'');
}
}
if (stringBuffer != null)
{
if (result.size() == 0)
{
result = new ArrayList();
}
result.add(stringBuffer.toString());
}
}
}
return result;
}
protected void appendAnnotationInfo(StringBuffer result, EModelElement eModelElement)
{
appendAnnotationInfo(result, eModelElement, DEFAULT_ANNOTATION_FILTER);
}
protected void appendAnnotationInfo(StringBuffer result, EModelElement eModelElement, AnnotationFilter annotationFilter)
{
appendAnnotationInfo(result, false, eModelElement, annotationFilter);
}
protected void appendAnnotationInfo(StringBuffer result, boolean qualified, EModelElement eModelElement, AnnotationFilter annotationFilter)
{
for (String annotationInfo : getAnnotationInfo(eModelElement, annotationFilter))
{
appendLineBreak(result);
String qualifier = qualified && eModelElement instanceof ENamedElement ? ((ENamedElement)eModelElement).getName() : null;
if (annotationInfo.startsWith(ExtendedMetaData.ANNOTATION_URI))
{
appendModelSetting(result, qualifier, "extendedMetaData", annotationInfo.substring(ExtendedMetaData.ANNOTATION_URI.length() + 1));
}
else
{
appendModelSetting(result, qualifier, "annotation", annotationInfo);
}
}
}
protected static String escapeString(String s, String additionalCharactersToEscape)
{
if (s == null) return null;
int len = s.length();
StringBuffer result = new StringBuffer(len + 16);
for (int i = 0; i < len; i++)
{
char c = s.charAt(i);
if (c == '\b') result.append("\\b");
else if (c == '\t') result.append("\\t");
else if (c == '\n') result.append("\\n");
else if (c == '\f') result.append("\\f");
else if (c == '\r') result.append("\\r");
else if (c == '\"') result.append("\\\"");
else if (c == '\'') result.append("\\\'");
else if (c == '\\') result.append("\\\\");
else if (additionalCharactersToEscape.indexOf(c) == -1 && c >= 32 && c < 127)
{
result.append(c);
}
else if (c < 256)
{
String num = Integer.toOctalString(c);
switch(num.length())
{
case 1: result.append("\\00"); break;
case 2: result.append("\\0"); break;
default: result.append("\\"); break;
}
result.append(num);
}
else
{
String num = Integer.toHexString(c);
switch(num.length())
{
case 1: result.append("\\u000"); break;
case 2: result.append("\\u00"); break;
case 3: result.append("\\u0"); break;
default: result.append("\\u"); break;
}
result.append(num);
}
}
// Escape a string that will terminate the comment in which this will all be nested.
//
for (int index = result.indexOf("*/"); index != -1; index = result.indexOf("*/", index))
{
result.replace(index, index + 1, "\\052");
}
return result.toString();
}
protected void appendLineBreak(StringBuffer result)
{
for (int i = result.length(); --i >= 0; )
{
if (Character.isWhitespace(result.charAt(i)))
{
result.deleteCharAt(i);
}
else
{
break;
}
}
result.append(getGenModel().getLineDelimiter());
}
protected void appendModelSetting(StringBuffer result, String qualifier, String name, String value)
{
if (qualifier != null)
{
result.append(qualifier);
result.append(capName(name));
}
else
{
result.append(name);
}
result.append("=\"");
result.append(value);
result.append("\" ");
}
protected void appendModelSetting(StringBuffer result, String name, String value)
{
result.append(name);
result.append("=\"");
result.append(value);
result.append("\" ");
}
protected static boolean isJavaUtilMapEntry(String name)
{
return "java.util.Map.Entry".equals(name) || "java.util.Map$Entry".equals(name);
}
protected static boolean isBlank(String string)
{
return string == null || string.length() == 0;
}
protected abstract class UniqueNameHelper
{
private Map nameToObjectMap;
private Map