/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.gen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Map.Entry;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.whole.lang.model.AbstractEntity;
import org.whole.lang.model.IEntity;
import org.whole.lang.reflect.AbstractLanguageKit;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.util.StringUtils;
/**
* @author Riccardo Solmi
*/
public class JavaModelGenerator extends AbstractEntity {
public final AST ast;
public final List<CompilationUnit> cuList = new ArrayList<CompilationUnit>();
private CompilationUnitBuilder currentBuilder;
private String copyright = null;
private String license = null;
private String author = null;
public String basePackagePrefix = null;
public String packagePrefix = null;
public String uri = null;
public String version = "";
public JavaModelGenerator() {
this(AST.newAST(AST.JLS8), null);
}
public JavaModelGenerator(String packagePrefix) {
this(AST.newAST(AST.JLS8), packagePrefix);
}
public JavaModelGenerator(AST ast, String packagePrefix) {
this.ast = ast;
setPackagePrefix(packagePrefix);
}
public String getCopyright() {
return copyright;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getURI() {
if (uri == null)
uri = AbstractLanguageKit.defaultURI("");
return uri;
}
public void setURI(String uri) {
this.uri = uri;
}
public String getBasePackagePrefix() {
if (basePackagePrefix == null)
basePackagePrefix = AbstractLanguageKit.defaultPackagePrefix();
return basePackagePrefix;
}
public void setBasePackagePrefix(String basePackagePrefix) {
this.basePackagePrefix = basePackagePrefix;
}
public String getPackagePrefix() {
if (packagePrefix == null)
packagePrefix = getBasePackagePrefix();
return packagePrefix;
}
public void setPackagePrefix(String packagePrefix) {
this.packagePrefix = packagePrefix;
}
public String factoriesSuffix() {
return "factories";
}
public String modelSuffix() {
return "model";
}
public String modelImplSuffix() {
return "model.impl";
}
public String entityImplName(String entityName) {
return entityName+"Impl";
}
public String entityStrictImplName(String entityName) {
return entityName+"StrictImpl";
}
public String modelAdaptersSuffix() {
return "model.adapters";
}
public String entityAdapterName(String entityName) {
return entityName+"Adapter";
}
public String entityAdapterQName(String entityName) {
return modelAdaptersPackage()+"."+entityAdapterName(entityName);
}
public String entityInterfaceQName(String entityName) {
return modelPackage()+"."+StringUtils.toSimpleName(entityName);
}
public String codebasePackage() {
return getPackagePrefix()+".codebase";
}
public final String factoriesPackage() {
return getPackagePrefix()+"."+factoriesSuffix();
}
public final String modelPackage() {
return getPackagePrefix()+"."+modelSuffix();
}
public final String modelImplPackage() {
return getPackagePrefix()+"."+modelImplSuffix();
}
public final String modelAdaptersPackage() {
return getPackagePrefix()+"."+modelAdaptersSuffix();
}
public String visitorsPackage() {
return CompilationUnitBuilder.LANG_PACKAGE+".visitors";
}
public String specificVisitorsPackage() {
return getPackagePrefix()+".visitors";
}
public String buildersPackage() {
return CompilationUnitBuilder.LANG_PACKAGE+".builders";
}
public String specificBuildersPackage() {
return getPackagePrefix()+".builders";
}
public String reflectionPackage() {
return CompilationUnitBuilder.LANG_PACKAGE+".reflect";
}
public String specificReflectionPackage() {
return getPackagePrefix()+".reflect";
}
public String entityDescriptorName() {
return reflectionPackage()+".EntityDescriptor";
}
public String featureDescriptorName() {
return reflectionPackage()+".FeatureDescriptor";
}
public String entityDescriptorEnumName() {
return reflectionPackage()+".EntityDescriptorEnum";
}
public String featureDescriptorEnumName() {
return reflectionPackage()+".FeatureDescriptorEnum";
}
public String specificEntityDescriptorEnumName() {
return entityDescriptorEnumName();
}
public String specificFeatureDescriptorEnumName() {
return featureDescriptorEnumName();
}
public String specificEntityInterfaceName() {
return IEntity.class.getName();
}
public String abstractVisitorName() {
return visitorsPackage()+".AbstractVisitor";
}
public String abstractUnaryVisitorName() {
return visitorsPackage()+".AbstractUnaryVisitor";
}
public String abstractBinaryVisitorName() {
return visitorsPackage()+".AbstractBinaryVisitor";
}
public String identityVisitorName() {
return visitorsPackage()+".GenericVisitor";
}
public String visitorInterfaceName() {
return visitorsPackage()+".IVisitor";
}
public String unaryVisitorName() {
return visitorsPackage()+".IUnaryVisitor";
}
public String binaryVisitorName() {
return visitorsPackage()+".IBinaryVisitor";
}
public String ternaryVisitorName() {
return visitorsPackage()+".ITernaryVisitor";
}
public String javaStoreVisitorName() {
return specificVisitorsPackage()+".JavaStoreGeneratorVisitor";
}
public String modelContextName() {
return buildersPackage()+".ModelContext";
}
public String specificModelContextName() {
return modelContextName();
}
public String adapterFragmentName() {
return modelImplPackage()+".AdapterFragment";
}
public String baseFragmentName() {
return modelImplPackage()+".BaseFragment";
}
public String metaFragmentName() {
return modelImplPackage()+".MetaFragment";
}
public void addBuilder(CompilationUnitBuilder builder) {
cuList.add(builder.getCompilationUnit());
}
public final CompilationUnitBuilder getCurrentBuilder() {
if (currentBuilder == null)
currentBuilder = new CompilationUnitBuilder(this);
return currentBuilder;
}
public final void setCurrentBuilder(CompilationUnitBuilder builder) {
this.currentBuilder = builder;
}
private JavaStoreBuilder javaStoreBuilder;
public JavaStoreBuilder javaStoreBuilder() {
if (javaStoreBuilder == null)
javaStoreBuilder = new JavaStoreBuilder(this);
return javaStoreBuilder;
}
private SortedSet<String> entitySet = new TreeSet<String>(); // all entities types (empty and composite included)
public void putEntity(String entity) {
entitySet.add(StringUtils.toSimpleName(entity));
}
public Set<String> getEntitySet() {
return entitySet;
}
private Set<String> entityResolverSet = new HashSet<String>(); // types of optional features
public void putEntityResolver(String entity) {
entityResolverSet.add(entity);
}
public Set<String> getEntityResolverSet() {
return entityResolverSet;
}
public String entityResolverSimpleName(String typeName) {
return StringUtils.toSimpleName(typeName);//+"Resolver";
}
private Set<String> optionalEntitySet = new HashSet<String>(); // types of optional features
public void putOptionalEntity(String entity) {
optionalEntitySet.add(entity);
}
public Set<String> getOptionalEntitySet() {
return optionalEntitySet;
}
private Map<String, String> compositeComponentMap = new HashMap<String, String>(); // composite to componentType
public void putComposite(String compositeType, String componentType) {
compositeComponentMap.put(compositeType, componentType);
}
public Set<Entry<String, String>> getCompositesEntrySet() {
return compositeComponentMap.entrySet();
}
public Set<String> getAllComposites() {
return compositeComponentMap.keySet();
}
public String getComponentType(String compositeType) {
return compositeComponentMap.get(compositeType);
}
private Map<String, Set<String>> typeImplementationsMap = new HashMap<String, Set<String>>(); // type to set of implementations
public void putPlaceHolderTypes(Set<String> markerTypes) {
Set<String> placeHolderTypes = new HashSet<String>(markerTypes);
placeHolderTypes.removeAll(getAllTypes());
for (String placeHolderType : placeHolderTypes)
putPlaceHolderType(placeHolderType);
}
public void putPlaceHolderType(String type) {
Set<String> implementationSet = typeImplementationsMap.get(type);
if (implementationSet == null)
typeImplementationsMap.put(type, implementationSet = new HashSet<String>());
}
public void putImplementation(String type, String implementation) {
Set<String> implementationSet = typeImplementationsMap.get(type);
if (implementationSet == null)
typeImplementationsMap.put(type, implementationSet = new HashSet<String>());
implementationSet.add(implementation);
}
public Set<Entry<String, Set<String>>> getTypesEntrySet() {
return typeImplementationsMap.entrySet();
}
public Set<String> getAllTypes() {
return typeImplementationsMap.keySet();
}
public Set<String> getAllImplementations(String type) {
Set<String> implementationSet = typeImplementationsMap.get(type);
if (implementationSet == null) {
implementationSet = new HashSet<String>();
implementationSet.add(type);
}
return implementationSet;
}
private Map<String, Set<String>> typeSubtypesMap = new HashMap<String, Set<String>>(); // type to set of subtypes
public void putSubtype(String type, String subtype) {
Set<String> typesSet = typeSubtypesMap.get(type);
if (typesSet == null)
typeSubtypesMap.put(type, typesSet = new HashSet<String>());
typesSet.add(subtype);
}
public Set<String> getAllSubtypes(String type) {
Set<String> subtypesSet = typeSubtypesMap.get(type);
if (subtypesSet == null) {
subtypesSet = new HashSet<String>();
subtypesSet.add(type);
}
return subtypesSet;
}
//TODO deprecated
public Set<String> getAllImplementationsClosure(String type) {
Set<String> allImplementations = new HashSet<String>(getAllImplementations(type));
Set<String> allTypes = new HashSet<String>(getAllSubtypes(type));
Set<String> subtypes = new HashSet<String>(allTypes);
getAllImplementationsClosure(allImplementations, allTypes, subtypes);
return allImplementations;
}
public void getAllImplementationsClosure(Set<String> allImplementations, Set<String> allTypes, Set<String> subtypes) {
for (String subtype : subtypes) {
Set<String> newImplementations = getAllImplementations(subtype);
allImplementations.addAll(newImplementations);
Set<String> newSubtypes = getAllSubtypes(subtype);
newSubtypes.removeAll(allTypes);
if (!newSubtypes.isEmpty()) {
allTypes.addAll(newSubtypes);
getAllImplementationsClosure(allImplementations, allTypes, newSubtypes);
}
}
}
@Override
public EntityDescriptor<?> wGetEntityDescriptor() {
throw new UnsupportedOperationException();
}
}