blob: bfd6fd2bc5ceaf8de2470751f9a30982004e465a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Bundesinstitut für Risikobewertung 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:
* Bundesinstitut für Risikobewertung - initial API and implementation
*******************************************************************************/
package org.eclipse.stem.model.codegen;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.emf.codegen.ecore.genmodel.GenClass;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EObject;
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.util.EcoreUtil;
import org.eclipse.stem.model.codegen.descriptor.EClassDescriptor;
import org.eclipse.stem.model.codegen.descriptor.JavaClassDescriptor;
import org.eclipse.stem.model.metamodel.Compartment;
import org.eclipse.stem.model.metamodel.Model;
import org.eclipse.stem.model.metamodel.Package;
import org.eclipse.stem.model.metamodel.Transition;
/**
* Shared utilities for various common operations
* to assist with model generation
*
*/
public class GeneratorUtils
{
public static GenClass getGenClassForMetamodelModel(Model model, GenModel gm) {
List<GenPackage> genPackages = gm.getGenPackages();
if (genPackages.size() > 0) {
return getGenClassForMetamodelModel(model, genPackages.iterator().next());
}
return null;
}
public static GenClass getGenClassForMetamodelModel(Model model, GenPackage gp)
{
for (GenClass genClass : gp.getGenClasses()) {
if (genClass.getName().equals(model.getName())) {
return genClass;
}
}
return null;
}
public static Model getMetamodelModelForGenClass(GenClass genClass, Package metamodel)
{
for (Model model : metamodel.getModels()) {
if (genClass.getName().equals(model.getName())) {
return model;
}
}
return null;
}
public static Package loadMetamodel(URI uri) throws IOException {
if (uri != null) {
ResourceSet resourceSet = new ResourceSetImpl();
Resource resource = resourceSet.createResource(uri);
resource.load(null);
if (resource.getContents().size() > 0) {
EObject obj = resource.getContents().get(0);
EcoreUtil.resolveAll(obj);
if (obj instanceof Package) {
return (Package) obj;
}
}
}
return null;
}
public static GenModel loadGenModel(URI uri) throws IOException {
if (uri != null) {
ResourceSet resourceSet = new ResourceSetImpl();
Resource resource = resourceSet.createResource(uri);
resource.load(null);
if (resource.getContents().size() > 0) {
EObject obj = resource.getContents().get(0);
EcoreUtil.resolveAll(obj);
if (obj instanceof GenModel) {
return (GenModel)obj;
}
}
}
return null;
}
/**
* Converts a list of GenClasses to STEMGenClasses
* @param genClasses
* @return
*/
public static List<STEMGenClass> getSTEMGenClasses(List<GenClass> genClasses) {
List<STEMGenClass> classes = new ArrayList<STEMGenClass>();
for (GenClass gc : genClasses) {
classes.add(STEMGenClass.get(gc));
}
return classes;
}
/**
* Finds all GenClasses that extend the given EClass inthis GenPackage
* @param pkg
* @param descriptor
* @return
*/
public static List<GenClass> findGenClassesThatExtendBaseType(
GenPackage pkg, EClassDescriptor descriptor) {
List<GenClass> classes = new ArrayList<GenClass>();
for (GenClass genClass : pkg.getGenClasses()) {
if (classExtends(genClass, descriptor)) {
classes.add(genClass);
}
}
return classes;
}
/**
* Gets the fully-qualified Java name for the given JavaClassDescriptor
* @param descriptor
* @return
*/
public static String getQualifiedJavaNameForDescriptor(
JavaClassDescriptor descriptor) {
if (descriptor != null) {
return descriptor.getQualifiedClassName();
}
return null;
}
/**
* Gets the fully-qualified Java name for the given EClass within the context
* of the given GenPackage
*
* @param basePackage
* @param descriptor
* @return
*/
public static String getQualifiedJavaNameForDescriptor(
GenPackage basePackage, EClassDescriptor descriptor) {
if (descriptor != null) {
GenClass gc = findGenClassForNSURI(basePackage,
descriptor.getNSURI(), descriptor.getClassName());
if (gc != null) {
return gc.getQualifiedInterfaceName();
}
}
return null;
}
/**
* Find the GenClass for the given NS URI / EClass name
* within the context of the given GenPackage
* @param baseGenPackage
* @param nsURI
* @param className
* @return
*/
public static GenClass findGenClassForNSURI(GenPackage baseGenPackage,
String nsURI, String className) {
GenPackage containerGenPackage = findGenPackageForNSURI(
baseGenPackage, nsURI);
if (containerGenPackage != null) {
return findGenClassInPkg(containerGenPackage, className);
}
return null;
}
// public static boolean extendsConcreteImplementation(GenClass genClass,
// String topLevelClass) {
// if (classExtends(genClass, topLevelClass)) {
// if (genClass.isAbstract() || genClass.isInterface()) {
// for (GenClass g2 : genClass.getBaseGenClasses()) {
// if (extendsConcreteImplementation(g2, topLevelClass)) {
// return true;
// }
// }
// } else {
// return true;
// }
// }
//
// return false;
// }
// public static boolean classExtends(GenClass genClass, String className) {
// for (GenClass g2 : genClass.getAllBaseGenClasses()) {
// if (g2.getQualifiedInterfaceName().equals(className)) {
// return true;
// }
// }
// return false;
// }
// public static boolean uriMatchesEPackage(EPackage pkg, String nsURI) {
// return pkg.getNsURI().equals(nsURI);
// }
/**
* Whether or not the given EClass extends the GenClass
* @param genClass
* @param descriptor
* @return
*/
public static boolean classExtends(GenClass genClass,
EClassDescriptor descriptor) {
for (GenClass g2 : genClass.getAllBaseGenClasses()) {
if (g2.getGenPackage().getNSURI().equals(descriptor.getNSURI())
&& g2.getName().equals(descriptor.getClassName())) {
return true;
}
}
return false;
}
/**
* Gets the list of GenClass from the EAnnotation map
* @param baseGenClass
* @param annotation
* @return
*/
public static Map<String, GenClass> getGenClassesForAnnotations(
GenClass baseGenClass, EAnnotation annotation) {
Map<String, GenClass> retVal = new HashMap<String, GenClass>();
for (Entry<String, String> entry : annotation.getDetails().entrySet()) {
GenClass match = findGenClass(baseGenClass.getGenPackage(),
entry.getValue());
retVal.put(entry.getKey(), match);
if (match == null) {
ModelGeneratorAdapter.addWarning("Unable to find class "
+ entry.getValue() + " for " + baseGenClass.getName()
+ "/" + annotation.getSource() + "/" + entry.getKey());
}
}
return retVal;
}
/**
* Returns either the default or (if not found) first entry
* from the given map
*
* @param data
* @param defaultKey
* @return
*/
public static GenClass getDefaultOrFirstEntryFromMap(
Map<String, GenClass> data, String defaultKey) {
GenClass entry = getDefaultEntryFromMap(data, defaultKey);
if (entry == null && data != null && data.size() > 0) {
entry = data.values().iterator().next();
}
return entry;
}
/**
* Gets the default GenClass from the map for the given key
* @param data
* @param defaultKey
* @return
*/
public static GenClass getDefaultEntryFromMap(Map<String, GenClass> data,
String defaultKey) {
GenClass defaultEntry = null;
if (data != null) {
defaultEntry = data.get(defaultKey);
}
return defaultEntry;
}
/**
* Find and return the GenPackage for a given EMF Namespace URI
* within the scope of the given base Genpackage
* @param genPackage
* @param nsURI
* @return
*/
public static GenPackage findGenPackageForNSURI(
GenPackage basePackage, String nsURI) {
List<GenPackage> pkgs = basePackage.getGenModel().getUsedGenPackages();
if (basePackage.getNSURI().equals(nsURI)) {
return basePackage;
}
for (GenPackage pkg : pkgs) {
if (pkg.getNSURI().equals(nsURI)) {
return pkg;
}
}
return null;
}
/**
* Attempts to find a matching GenPackage/EPackage for the given
* Java package name.
*
* @param genPackage
* @param packageName
* @return
*/
public static List<GenPackage> findGenPackageForJavaPackageName(
GenPackage genPackage, String packageName) {
List<GenPackage> pkgs = genPackage.getGenModel().getUsedGenPackages();
List<GenPackage> candidates = new ArrayList<GenPackage>();
if (genPackage.getClassPackageName().equals(packageName)
|| genPackage.getInterfacePackageName().equals(packageName)) {
candidates.add(genPackage);
}
for (GenPackage pkg : pkgs) {
if (pkg.getClassPackageName().equals(packageName)
|| pkg.getInterfacePackageName().equals(packageName)) {
candidates.add(pkg);
}
}
return candidates;
}
/**
* Attempts to find a matching GenClass/EClass for the given
* fully-qualified Java name. This matches both interface as well as
* implementation name for the given Java Package.
*
* Examples matches for ExampleClass include com.example.ExampleClass
* and com.example.impl.ExampleClassImpl.
*
* @param genPackage
* @param className
* @return
*/
private static GenClass findGenClass(GenPackage genPackage, String className) {
String pkgName = null;
int pkgIdx = className.lastIndexOf('.');
if (pkgIdx >= 0) {
pkgName = className.substring(0, pkgIdx);
className = className.substring(pkgIdx + 1);
}
List<GenPackage> pkgsToSearch = null;
if (pkgName != null) {
pkgsToSearch = findGenPackageForJavaPackageName(genPackage, pkgName);
} else {
pkgsToSearch = new ArrayList<GenPackage>();
pkgsToSearch.add(genPackage);
pkgsToSearch.addAll(genPackage.getGenModel().getUsedGenPackages());
}
GenClass cls = null;
for (GenPackage pkg : pkgsToSearch) {
cls = findGenClassInPkg(pkg, className);
if (cls != null) {
break;
}
}
return cls;
}
/**
* @param genPkg
* @param className
* @return
*/
private static GenClass findGenClassInPkg(GenPackage genPkg,
String className) {
GenClass match = null;
for (GenClass cls : genPkg.getGenClasses()) {
if (cls.getName().equals(className)
|| cls.getClassName().equals(className)
|| cls.getInterfaceName().equals(className)) {
match = cls;
break;
}
}
return match;
}
/**
* Whether the string is either null or contains no content (empty).
* @param s
* @return
*/
public static boolean isNullOrEmpty(String s) {
return (s == null || CodeGenConstants.EMPTY_STRING.equals(s));
}
/**
* Transforms a string in condensed camel-case or Java identifier form
* into space-separated upper-case words.
*
* Example: thisIsAValue would returns "This Is A Value"
*
* @param str String to format
* @return The formatted string in space-separated, upper-case words
*/
public static String formatToCapWords(String str) {
StringBuilder sb = new StringBuilder();
if (str.length() > 0) {
sb.appendCodePoint(Character.toUpperCase(str.codePointAt(0)));
for (int idx = 1; idx < str.length(); idx++) {
int cp = str.codePointAt(idx);
if (Character.isUpperCase(cp)
&& (Character.isLowerCase(str.codePointAt(idx - 1)) || (str
.length() > idx + 1 && Character
.isLowerCase(str.codePointAt(idx + 1))))) {
sb.append(' ');
}
sb.appendCodePoint(cp);
}
}
return sb.toString();
}
/**
* Formats a string to camel case
* @param str
* @return
*/
public static String formatToCamelCase(String str)
{
StringBuilder sb = new StringBuilder();
if (str.length() > 0) {
boolean nextIsLC = true;
boolean nextIsUC = false;
for (int idx=0; idx<str.length(); idx++) {
int cp = str.codePointAt(idx);
if (Character.isJavaIdentifierPart(cp)) {
if (nextIsLC) {
sb.appendCodePoint(Character.toLowerCase(cp));
nextIsLC = false;
} else if (nextIsUC) {
sb.appendCodePoint(Character.toUpperCase(cp));
nextIsUC = false;
} else {
sb.appendCodePoint(cp);
}
} else {
if (!nextIsLC) {
nextIsUC = true;
}
}
}
}
return sb.toString();
}
/**
* Formats a string to upper case words with no spaces.
* Example: This is a test => ThisIsATest
* @param str
* @return
*/
public static String formatToUpperCaseWordsNoSpaces(String str)
{
str = formatToCamelCase(str);
StringBuilder sb = new StringBuilder();
if (str.length() > 0) {
sb.appendCodePoint(Character.toUpperCase(str.codePointAt(0)));
sb.append(str.substring(1));
}
return sb.toString();
}
/**
* Formats a string to a valid Java package name
* @param str String to format
* @return A formatted, valid Java package name
*/
public static String formatToJavaPackageName(String str)
{
boolean firstWhiteSpace = true;
str = str.trim();
StringBuilder sb = new StringBuilder();
if (str != null) {
for (int idx=0; idx<str.length(); idx++) {
int c = str.codePointAt(idx);
if (Character.isWhitespace(c)) {
if (firstWhiteSpace) {
sb.append('.');
firstWhiteSpace = false;
}
} else if (c == '.' || Character.isJavaIdentifierPart(c)) {
sb.appendCodePoint(c);
firstWhiteSpace = true;
}
}
}
return sb.toString().toLowerCase();
}
/**
* Checks whether the string is a valid Java package name / identifer
* @param str String to validate
* @return Whether the string is a valid Java package name
*/
public static boolean isValidJavaPackageName(String str)
{
boolean valid = false;
for (String token : str.split("\\.")) {
if (isValidJavaName(token)) {
valid = true;
} else {
valid = false;
break;
}
}
return valid;
}
/**
* Checks whether the string is a valid Java identifier
* @param str String to validate
* @return Whether the string is a valid Java identifier
*/
public static boolean isValidJavaName(String str)
{
boolean valid = false;
if (str.length() > 0) {
valid = Character.isJavaIdentifierStart(str.codePointAt(0));
for (int idx=1; valid && idx<str.length(); idx++) {
valid = Character.isJavaIdentifierPart(str.codePointAt(idx));
if (!valid) {
break;
}
}
}
return valid;
}
public static void safeClose(InputStream is) {
try {
is.close();
} catch (Throwable t) {
// do nothing
}
}
public static STEMGenFeature findGenFeatureForEClass(String name, List<STEMGenFeature> features) {
for (STEMGenFeature feature : features) {
if (feature.getGenFeature().getName().equals(name)) {
return feature;
}
}
return null;
}
public static String getTransitionPrettyName(Transition t) {
Compartment source = t.getSource();
Compartment target = t.getTarget();
String sourceName = "?";
String targetName = "?";
if (source != null) {
sourceName = source.getName();
}
if (target != null) {
targetName = target.getName();
}
return sourceName +" -> "+ targetName;
}
}