package org.jvnet.jaxb2_commons.util; import java.util.Iterator; import com.sun.codemodel.JClass; import com.sun.codemodel.JClassAlreadyExistsException; import com.sun.codemodel.JClassContainer; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JExpr; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; import com.sun.codemodel.JPackage; import com.sun.codemodel.JPrimitiveType; import com.sun.codemodel.JResourceFile; import com.sun.codemodel.JStatement; import com.sun.codemodel.JType; import com.sun.codemodel.fmt.JPropertyFile; import com.sun.tools.xjc.outline.ClassOutline; /** * Property file utilities. * * @author valikov */ public class CodeModelUtils { private CodeModelUtils() { } /** * Returns a property file (created if necessary). * * @param thePackage * package to create property file * @param name * property file name. * @return Property file. */ public static JPropertyFile getOrCreatePropertyFile(JPackage thePackage, String name) { JPropertyFile propertyFile = null; for (Iterator<JResourceFile> iterator = thePackage.propertyFiles(); iterator .hasNext() && (null == propertyFile);) { final JResourceFile resourceFile = (JResourceFile) iterator.next(); if (resourceFile instanceof JPropertyFile && name.equals(resourceFile.name())) { propertyFile = (JPropertyFile) resourceFile; } } if (null == propertyFile) { propertyFile = new JPropertyFile(name); thePackage.addResourceFile(propertyFile); } return propertyFile; } // public static boolean doesImplement(JDefinedClass theClass, JClass // theInterface) // { // theClass._i // } public static String getClassName(final JClass theClass) { return (theClass.outer() == null ? theClass.fullName() : getClassName(theClass.outer()) + "$" + theClass.name()); } public static String getLocalClassName(final JClass theClass) { return (theClass.outer() == null ? theClass.name() : getLocalClassName(theClass.outer()) + "$" + theClass.name()); } public static String getDottedLocalClassName(final JClass theClass) { return (theClass.outer() == null ? theClass.name() : getDottedLocalClassName(theClass.outer()) + "." + theClass.name()); } public static String getPackagedClassName(final JClass theClass) { return (theClass.outer() == null ? theClass.fullName() : getPackagedClassName(theClass.outer()) + "$" + theClass.name()); } public static JClass box(JType t) { if (t instanceof JClass) return (JClass) t; else return ((JPrimitiveType) t).boxify(); } public static JDefinedClass getOrCreateClass(JClassContainer container, int flags, String name) { try { return container._class(flags, name); } catch (JClassAlreadyExistsException jcaeex) { return jcaeex.getExistingClass(); } } public static JDefinedClass getOrCreateClass(JCodeModel codeModel, int flags, String fullClassName) { final String packageName; final String className; final int lastDotIndex = fullClassName.lastIndexOf('.'); if (lastDotIndex >= 0) { packageName = fullClassName.substring(0, lastDotIndex); className = fullClassName.substring(lastDotIndex + 1); } else { packageName = ""; className = fullClassName; } final JPackage thePackage = codeModel._package(packageName); return getOrCreateClass(thePackage, flags, className); } public static JStatement split(JDefinedClass theClass, JStatement[] statements, String prefix, int start, int length, int threshold) { final JMethod method = theClass.method(JMod.PRIVATE + JMod.STATIC, theClass.owner().VOID, prefix); if (length < threshold) { for (int index = start; (index - start) < length; index++) { final JStatement statement = statements[index]; method.body().add(statement); } } else { method.body().add( split(theClass, statements, prefix + "_0", start, length / 2, threshold)); method.body().add( split(theClass, statements, prefix + "_1", start + length / 2, length - (length / 2), threshold)); } return JExpr.invoke(method); } public static JMethod getMethod(JDefinedClass theClass, String name, JType[] arguments) { final JMethod method = theClass.getMethod(name, arguments); if (method != null) { return method; } else { final JClass draftSuperClass = theClass._extends(); if (draftSuperClass == null || !(draftSuperClass instanceof JDefinedClass)) { return null; } else { final JDefinedClass superClass = (JDefinedClass) draftSuperClass; return getMethod(superClass, name, arguments); } } } public static JMethod getMethod(final JDefinedClass theClass, final String name) { for (JMethod method : theClass.methods()) { if (method.name().equals(name)) return method; } return null; } public static JMethod getMethod(final ClassOutline classOutline, final String name) { final JDefinedClass ref = classOutline.ref; final JMethod method = getMethod(ref, name); if (method != null) { return method; } else { final ClassOutline superClassOutline = classOutline.getSuperClass(); if (superClassOutline == null) { return null; } else { return getMethod(superClassOutline, name); } } } public static JCodeModel getCodeModel(ClassOutline classOutline) { return classOutline.ref.owner(); } public static JType ref(JCodeModel codeModel, String className) { try { // try the context class loader first return codeModel.ref(Thread.currentThread().getContextClassLoader() .loadClass(className)); } catch (ClassNotFoundException e) { // fall through } // then the default mechanism. try { return codeModel.ref(Class.forName(className)); } catch (ClassNotFoundException e1) { // fall through } { JDefinedClass _class = _getClass(codeModel, className); if (_class != null) { return _class; } } return codeModel.ref(className.replace('$', '.')); } public static JDefinedClass _getClass(JCodeModel codeModel, String fullyQualifiedName) { final int idx = fullyQualifiedName.lastIndexOf('.'); if (idx < 0) { return codeModel.rootPackage()._getClass(fullyQualifiedName); } else { final String packageName = fullyQualifiedName.substring(0, idx); for (Iterator<JPackage> iterator = codeModel.packages(); iterator .hasNext();) { final JPackage _package = iterator.next(); if (packageName.equals(_package.name())) { return _getClass(_package, fullyQualifiedName.substring(idx + 1)); } } return null; } } public static JDefinedClass _getClass(JPackage _package, String name) { final int idx = name.lastIndexOf('$'); if (idx < 0) { return _package._getClass(name); } else { final String parentClassName = name.substring(0, idx); final JDefinedClass parentClass = _package ._getClass(parentClassName); if (parentClass == null) { return null; } else { return _getClass(parentClass, name.substring(idx + 1)); } } } public static JDefinedClass _getClass(JDefinedClass _class, String name) { final int idx = name.lastIndexOf('$'); if (idx < 0) { for (Iterator<JDefinedClass> nestedClasses = _class.classes(); nestedClasses .hasNext();) { final JDefinedClass nestedClass = nestedClasses.next(); if (nestedClass.name().equals(name)) { return nestedClass; } } return null; } else { final JDefinedClass nestedClass = _getClass(_class, name.substring(0, idx)); if (nestedClass == null) { return null; } else { return _getClass(nestedClass, name.substring(idx + 1)); } } } }