All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.milyn.javabean.pojogen.JClass Maven / Gradle / Ivy
/*
Milyn - Copyright (C) 2006 - 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (version 2.1) as published by the Free Software
Foundation.
This library 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:
http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.javabean.pojogen;
import org.milyn.assertion.AssertArgument;
import org.milyn.util.FreeMarkerTemplate;
import org.milyn.io.StreamUtils;
import java.io.Serializable;
import java.util.*;
import java.io.Writer;
import java.io.IOException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CannotCompileException;
/**
* Java POJO model.
* @author bardl
* @author [email protected]
*/
public class JClass {
private String uniqueId;
private String packageName;
private String className;
private Set rawImports = new LinkedHashSet();
private Set implementTypes = new LinkedHashSet();
private Set extendTypes = new LinkedHashSet();
private Set annotationTypes = new LinkedHashSet();
private Class> skeletonClass;
private List properties = new ArrayList();
private List constructors = new ArrayList();
private List methods = new ArrayList();
private boolean fluentSetters = true;
private boolean serializable = false;
private boolean finalized = false;
private static FreeMarkerTemplate template;
static {
try {
template = new FreeMarkerTemplate(StreamUtils.readStreamAsString(JClass.class.getResourceAsStream("JavaClass.ftl")));
} catch (IOException e) {
throw new IllegalStateException("Failed to load JavaClass.ftl FreeMarker template.", e);
}
}
public JClass(String packageName, String className) {
this(packageName, className, UUID.randomUUID().toString());
}
public JClass(String packageName, String className, String uniqueId) {
AssertArgument.isNotNull(packageName, "packageName");
AssertArgument.isNotNull(className, "className");
AssertArgument.isNotNull(uniqueId, "uniqueId");
this.packageName = packageName;
this.className = className;
this.uniqueId = uniqueId;
}
public String getPackageName() {
return packageName;
}
public String getClassName() {
return className;
}
public String getUniqueId() {
return uniqueId;
}
public Set getRawImports() {
return rawImports;
}
public Set getImplementTypes() {
return implementTypes;
}
public Set getExtendTypes() {
return extendTypes;
}
public Set getAnnotationTypes() {
return annotationTypes;
}
public void setFluentSetters(boolean fluentSetters) {
this.fluentSetters = fluentSetters;
}
public Class> getSkeletonClass() {
if(skeletonClass == null) {
String skeletonClassName = packageName + "." + className;
try {
skeletonClass = Thread.currentThread().getContextClassLoader().loadClass(skeletonClassName);
} catch (ClassNotFoundException e) {
ClassPool pool = new ClassPool(true);
CtClass cc = pool.makeClass(skeletonClassName);
try {
skeletonClass = cc.toClass();
} catch (CannotCompileException ee) {
throw new IllegalStateException("Unable to create runtime skeleton class for class '" + skeletonClassName + "'.", ee);
} finally {
cc.detach();
}
}
}
return skeletonClass;
}
public JClass setSerializable() {
this.serializable = true;
implementTypes.add(new JType(Serializable.class));
return this;
}
public boolean isSerializable() {
return serializable;
}
public void addProperty(JNamedType property) {
AssertArgument.isNotNull(property, "property");
assertPropertyUndefined(property);
properties.add(property);
}
public JClass addBeanProperty(JNamedType property) {
addProperty(property);
String propertyName = property.getName();
String capitalizedPropertyName = Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
// Add property getter method...
JMethod getterMethod = new JMethod(property.getType(), "get" + capitalizedPropertyName);
getterMethod.appendToBody("return " + property.getName() + ";");
methods.add(getterMethod);
// Add property setter method...
if(fluentSetters) {
JMethod setterMethod = new JMethod(new JType(getSkeletonClass()), "set" + capitalizedPropertyName);
setterMethod.addParameter(property);
setterMethod.appendToBody("this." + property.getName() + " = " + property.getName() + "; return this;");
methods.add(setterMethod);
} else {
JMethod setterMethod = new JMethod("set" + capitalizedPropertyName);
setterMethod.addParameter(property);
setterMethod.appendToBody("this." + property.getName() + " = " + property.getName() + ";");
methods.add(setterMethod);
}
return this;
}
public List getProperties() {
return properties;
}
public List getConstructors() {
return constructors;
}
public List getMethods() {
return methods;
}
public JMethod getDefaultConstructor() {
for(JMethod constructor : constructors) {
if(constructor.getParameters().isEmpty()) {
return constructor;
}
}
JMethod constructor = new JMethod(getClassName());
constructors.add(constructor);
return constructor;
}
public Set> getImports() {
Set> importSet = new LinkedHashSet>();
addImports(importSet, implementTypes);
addImports(importSet, extendTypes);
addImports(importSet, annotationTypes);
for(JNamedType property : properties) {
property.getType().addImports(importSet, new String[] {"java.lang", packageName});
}
addMethodImportData(constructors, importSet);
addMethodImportData(methods, importSet);
addImports(importSet, rawImports);
return importSet;
}
private void addImports(Set> importSet, Collection types) {
for(JType property : types) {
property.addImports(importSet, new String[] {"java.lang", packageName});
}
}
private void addMethodImportData(List methodList, Set> importSet) {
for(JMethod method : methodList) {
method.getReturnType().addImports(importSet, new String[] {"java.lang", packageName});
for(JNamedType param : method.getParameters()) {
param.getType().addImports(importSet, new String[] {"java.lang", packageName});
}
for(JType exception : method.getExceptions()) {
exception.addImports(importSet, new String[] {"java.lang", packageName});
}
}
}
public String getImplementsDecl() {
return PojoGenUtil.getTypeDecl("implements", implementTypes);
}
public String getExtendsDecl() {
return PojoGenUtil.getTypeDecl("extends", extendTypes);
}
public void writeClass(Writer writer) throws IOException {
Map contextObj = new HashMap();
contextObj.put("class", this);
writer.write(template.apply(contextObj));
// Finalize all the methods... allowing them to be GC'd...
finalizeMethods(constructors);
finalizeMethods(methods);
finalized = true;
}
public boolean isFinalized() {
return finalized;
}
private void finalizeMethods(List methodList) {
for(JMethod method : methodList) {
method.finalizeMethod();
}
}
private void assertPropertyUndefined(JNamedType property) {
if(hasProperty(property.getName())) {
throw new IllegalArgumentException("Property '" + property.getName() + "' already defined.");
}
}
public boolean hasProperty(String propertyName) {
for(JNamedType definedProperty : properties) {
if(definedProperty.getName().equals(propertyName)) {
return true;
}
}
return false;
}
}