Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
346 additions
and
11 deletions.
There are no files selected for viewing
331 changes: 331 additions & 0 deletions
331
...e.bootstrap.dev/src/main/java/org/kevoree/bootstrap/dev/annotator/ModelBuilderHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,331 @@ | ||
package org.kevoree.bootstrap.dev.annotator; | ||
|
||
import javassist.*; | ||
import org.kevoree.*; | ||
import org.kevoree.annotation.Input; | ||
import org.kevoree.annotation.Output; | ||
import org.kevoree.annotation.Param; | ||
import org.kevoree.api.*; | ||
import org.kevoree.factory.KevoreeFactory; | ||
|
||
import java.io.File; | ||
import java.io.InputStream; | ||
import java.net.URL; | ||
import java.util.HashMap; | ||
|
||
/** | ||
* Created by duke on 23/01/2014. | ||
* <p/> | ||
* ModelBuilder in Pure Java, Need to be tested before going to production | ||
*/ | ||
|
||
|
||
public class ModelBuilderHelper { | ||
|
||
public static void addLibrary(String libName, TypeDefinition typeDef, ContainerRoot root, KevoreeFactory factory) { | ||
TypeLibrary lib = root.findLibrariesByID(libName); | ||
if (lib == null) { | ||
lib = factory.createTypeLibrary(); | ||
lib.setName(libName); | ||
root.addLibraries(lib); | ||
} | ||
lib.addSubTypes(typeDef); | ||
} | ||
|
||
public static void deepMethods(CtClass clazz, KevoreeFactory factory, TypeDefinition currentTypeDefinition) throws ClassNotFoundException, NotFoundException { | ||
for (CtMethod method : clazz.getDeclaredMethods()) { | ||
for (Object annotation : method.getAnnotations()) { | ||
if (annotation instanceof Input) { | ||
Input annotationInput = (Input) annotation; | ||
if (currentTypeDefinition instanceof ComponentType) { | ||
ComponentType currentTypeDefinitionCT = (ComponentType) currentTypeDefinition; | ||
PortTypeRef providedPortRef = factory.createPortTypeRef(); | ||
providedPortRef.setName(method.getName()); | ||
providedPortRef.setOptional(annotationInput.optional()); | ||
currentTypeDefinitionCT.addProvided(providedPortRef); | ||
} | ||
} | ||
} | ||
} | ||
for (CtClass interfaceLoop : clazz.getInterfaces()) { | ||
deepMethods(interfaceLoop, factory, currentTypeDefinition); | ||
} | ||
if (clazz.getSuperclass() != null) { | ||
deepMethods(clazz.getSuperclass(), factory, currentTypeDefinition); | ||
} | ||
} | ||
|
||
public static void deepFields(CtClass clazz, KevoreeFactory factory, TypeDefinition currentTypeDefinition) throws Exception { | ||
for (CtField field : clazz.getDeclaredFields()) { | ||
for (Object annotation : field.getAnnotations()) { | ||
if (annotation instanceof org.kevoree.annotation.KevoreeInject) { | ||
boolean checkType = false; | ||
if (field.getType().getName().equals(ModelService.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(BootstrapService.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(KevScriptService.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(Context.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(ChannelContext.class.getName())) { | ||
checkType = true; | ||
} | ||
if (!checkType) { | ||
throw new Exception("KevoreeInject annotation is only suitable for following types : ModelService,BootstrapService,KevScriptService,Context,ChannelContext : currently found : " + field.getType().getName()); | ||
} | ||
} | ||
if (annotation instanceof Output) { | ||
Output annotationOutput = (Output) annotation; | ||
if (!field.getType().getName().equals(org.kevoree.api.Port.class.getName())) { | ||
throw new Exception("Output port field must of type of " + org.kevoree.api.Port.class.getName()); | ||
} | ||
if (currentTypeDefinition instanceof ComponentType) { | ||
ComponentType currentTypeDefinitionComponentType = (ComponentType) currentTypeDefinition; | ||
PortTypeRef requiredPortRef = factory.createPortTypeRef(); | ||
requiredPortRef.setName(field.getName()); | ||
requiredPortRef.setOptional(annotationOutput.optional()); | ||
currentTypeDefinitionComponentType.addRequired(requiredPortRef); | ||
} | ||
} | ||
if (annotation instanceof Param) { | ||
Param annotationParam = (Param) annotation; | ||
boolean checkType = false; | ||
if (field.getType().getName().equals(String.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(Float.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(Integer.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(Double.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(Boolean.class.getName())) { | ||
checkType = true; | ||
} | ||
if (field.getType().getName().equals(Long.class.getName())) { | ||
checkType = true; | ||
} | ||
if (!checkType) { | ||
if (!field.getType().isPrimitive()) { | ||
throw new Exception("Param annotation is only applicable on field of type String,Long,Double,Float,Integer, current " + field.getType().getName()); | ||
} | ||
} | ||
DictionaryAttribute dicAtt = factory.createDictionaryAttribute(); | ||
if (currentTypeDefinition.getDictionaryType() == null) { | ||
currentTypeDefinition.setDictionaryType(factory.createDictionaryType()); | ||
} | ||
dicAtt.setName(field.getName()); | ||
dicAtt.setDatatype(field.getType().getName()); | ||
dicAtt.setOptional(annotationParam.optional()); | ||
dicAtt.setFragmentDependant(annotationParam.fragmentDependent()); | ||
dicAtt.setDefaultValue(annotationParam.defaultValue()); | ||
currentTypeDefinition.getDictionaryType().addAttributes(dicAtt); | ||
} | ||
} | ||
} | ||
for (CtClass interfaceLoop : clazz.getInterfaces()) { | ||
deepFields(interfaceLoop, factory, currentTypeDefinition); | ||
} | ||
if (clazz.getSuperclass() != null) { | ||
deepFields(clazz.getSuperclass(), factory, currentTypeDefinition); | ||
} | ||
} | ||
|
||
private static void checkParent(TypeDefinition current, CtClass clazz, CtClass originClazz, ContainerRoot root, KevoreeFactory factory) throws Exception { | ||
if (clazz == null) { | ||
return; | ||
} | ||
String name = clazz.getSimpleName(); | ||
String version = null; | ||
String currentTypeName = null; | ||
try { | ||
for (Object an : clazz.getAnnotations()) { | ||
String newMeta = metaClassName(an); | ||
if (newMeta != null) { | ||
if (currentTypeName != null) { | ||
throw new Exception("A Java Class can't be mapped to several Kevoree TypeDefinition " + clazz.getName()); | ||
} else { | ||
currentTypeName = newMeta; | ||
} | ||
} | ||
} | ||
} catch (ClassNotFoundException e) { | ||
e.printStackTrace(); | ||
} | ||
if (currentTypeName != null) { | ||
|
||
|
||
String endPath = clazz.getName().replace(".", File.separator) + ".class"; | ||
String baseURL = clazz.getURL().toString().replace(endPath, ""); | ||
|
||
|
||
/* | ||
String manifest = baseURL + "META-INF" + File.separator + "MANIFEST.MF"; | ||
URL u2 = new URL(manifest); | ||
System.out.println(u2.openStream().available()); | ||
*/ | ||
|
||
|
||
|
||
/* | ||
if (version == null) { | ||
File metaInf = new File(baseURL + "META-INF" + File.separator + "maven"); | ||
System.out.println(metaInf.exists()); | ||
if (metaInf.exists()) { | ||
if (metaInf.listFiles().length > 0) { | ||
File groupFile = metaInf.listFiles()[0]; | ||
} | ||
} | ||
} */ | ||
if (version == null) { | ||
try { | ||
String kevManifest = baseURL + "KEV-INF" + File.separator + "lib.json"; | ||
URL ukevManifest = new URL(kevManifest); | ||
InputStream is = ukevManifest.openStream(); | ||
ContainerRoot libModel = (ContainerRoot) factory.createJSONLoader().loadModelFromStream(is).get(0); | ||
HashMap<DeployUnit, Integer> links = new HashMap<DeployUnit, Integer>(); | ||
for (DeployUnit du : libModel.getDeployUnits()) { | ||
if (!links.containsKey(du)) { | ||
links.put(du, 0); | ||
} | ||
for (DeployUnit dul : du.getRequiredLibs()) { | ||
if (!links.containsKey(dul)) { | ||
links.put(dul, 0); | ||
} | ||
links.put(dul, links.get(dul) + 1); | ||
} | ||
} | ||
//This current deploy unit should be the only one with no external references, tricky part | ||
for (DeployUnit d : links.keySet()) { | ||
if (links.get(d) == 0) { | ||
version = d.getVersion(); | ||
} | ||
} | ||
is.close(); | ||
} catch (Exception e) { | ||
// | ||
} | ||
|
||
} | ||
if (version == null) { | ||
version = current.getVersion(); | ||
} | ||
TypeDefinition parent = getOrCreateTypeDefinition(name, version, root, factory, currentTypeName); | ||
current.addSuperTypes(parent); | ||
} | ||
} | ||
|
||
private static void processTypeDefinition(TypeDefinition td, DeployUnit du, CtClass clazz, ContainerRoot root, KevoreeFactory factory) throws Exception { | ||
if (Modifier.isAbstract(clazz.getModifiers())) { | ||
td.setAbstract(true); | ||
} else { | ||
td.setAbstract(false); | ||
} | ||
td.setBean(clazz.getName()); | ||
td.addDeployUnits(du); | ||
|
||
try { | ||
checkParent(td, clazz.getSuperclass(), clazz, root, factory); | ||
} catch (NotFoundException e) { | ||
e.printStackTrace(); | ||
} | ||
try { | ||
for (CtClass interf : clazz.getInterfaces()) { | ||
checkParent(td, interf, clazz, root, factory); | ||
} | ||
} catch (NotFoundException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
public static TypeDefinition getOrCreateTypeDefinition(String name, String version, ContainerRoot root, KevoreeFactory factory, String typeName) { | ||
//TODO generate find multi Key in KMF | ||
for (TypeDefinition td : root.getTypeDefinitions()) { | ||
if (name.equals(td.getName()) && version.equals(td.getVersion())) { | ||
return td; | ||
} | ||
} | ||
TypeDefinition td = (TypeDefinition) factory.create(typeName); | ||
td.setVersion(version); | ||
td.setName(name); | ||
root.addTypeDefinitions(td); | ||
return td; | ||
} | ||
|
||
|
||
public static void process(Object elem, CtClass clazz, KevoreeFactory factory, DeployUnit du, ContainerRoot root) throws Exception { | ||
if (elem instanceof org.kevoree.annotation.GroupType) { | ||
TypeDefinition td = getOrCreateTypeDefinition(clazz.getSimpleName(), du.getVersion(), root, factory, metaClassName(elem)); | ||
processTypeDefinition(td, du, clazz, root, factory); | ||
deepFields(clazz, factory, td); | ||
} | ||
if (elem instanceof org.kevoree.annotation.ChannelType) { | ||
TypeDefinition td = getOrCreateTypeDefinition(clazz.getSimpleName(), du.getVersion(), root, factory, metaClassName(elem)); | ||
processTypeDefinition(td, du, clazz, root, factory); | ||
deepFields(clazz, factory, td); | ||
} | ||
if (elem instanceof org.kevoree.annotation.ComponentType) { | ||
TypeDefinition td = getOrCreateTypeDefinition(clazz.getSimpleName(), du.getVersion(), root, factory, metaClassName(elem)); | ||
processTypeDefinition(td, du, clazz, root, factory); | ||
deepFields(clazz, factory, td); | ||
deepMethods(clazz, factory, td); | ||
} | ||
if (elem instanceof org.kevoree.annotation.NodeType) { | ||
TypeDefinition td = getOrCreateTypeDefinition(clazz.getSimpleName(), du.getVersion(), root, factory, metaClassName(elem)); | ||
processTypeDefinition(td, du, clazz, root, factory); | ||
deepFields(clazz, factory, td); | ||
} | ||
if (elem instanceof org.kevoree.annotation.Library) { | ||
libraryCache = (org.kevoree.annotation.Library) elem; | ||
} | ||
} | ||
|
||
public static String metaClassName(Object elem) { | ||
if (elem instanceof org.kevoree.annotation.GroupType) { | ||
return GroupType.class.getName(); | ||
} | ||
if (elem instanceof org.kevoree.annotation.ChannelType) { | ||
return ChannelType.class.getName(); | ||
} | ||
if (elem instanceof org.kevoree.annotation.ComponentType) { | ||
return ComponentType.class.getName(); | ||
} | ||
if (elem instanceof org.kevoree.annotation.NodeType) { | ||
return org.kevoree.NodeType.class.getName(); | ||
} | ||
return null; | ||
} | ||
|
||
|
||
static org.kevoree.annotation.Library libraryCache = null; | ||
|
||
public static void postProcess(CtClass clazz, KevoreeFactory factory, DeployUnit du, ContainerRoot root) { | ||
if (libraryCache != null) { | ||
for (TypeDefinition typeDef : root.getTypeDefinitions()) { | ||
if (typeDef.getName().equals(clazz.getSimpleName()) && typeDef.getVersion().equals(du.getVersion())) { | ||
if (libraryCache.name() != null) { | ||
addLibrary(libraryCache.name(), typeDef, root, factory); | ||
} | ||
String[] libs = libraryCache.names(); | ||
if (libs != null) { | ||
for (int i = 0; i < libs.length; i++) { | ||
addLibrary(libs[i], typeDef, root, factory); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
libraryCache = null; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.