/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package de.cismet.cids.utils;
import Sirius.server.localserver.attribute.ClassAttribute;
import Sirius.server.localserver.attribute.MemberAttributeInfo;
import Sirius.server.middleware.types.MetaClass;
import org.openide.util.Lookup;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import de.cismet.tools.BlacklistClassloading;
/**
* DOCUMENT ME!
*
* @author stefan
* @version $Revision$, $Date$
*/
public class ClassloadingHelper {
//~ Static fields/initializers ---------------------------------------------
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ClassloadingHelper.class);
private static final ArrayList<String> packagePrefixes = new ArrayList<String>();
static {
final Collection<? extends ClassLoadingPackagePrefixProvider> c = Lookup.getDefault()
.lookupAll(ClassLoadingPackagePrefixProvider.class);
for (final ClassLoadingPackagePrefixProvider pp : c) {
packagePrefixes.add(pp.getClassLoadingPackagePrefix());
}
}
//~ Enums ------------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @version $Revision$, $Date$
*/
public enum CLASS_TYPE {
//~ Enum constants -----------------------------------------------------
ICON_FACTORY("treeicons", "IconFactory", "iconfactory"),
EXTENSION_FACTORY("extensionfactories", "ExtensionFactory", "extensionfactory"),
RENDERER("objectrenderer", "Renderer", "renderer"),
AGGREGATION_RENDERER("objectrenderer", "AggregationRenderer", "aggregationrenderer"),
TO_STRING_CONVERTER("tostringconverter", "ToStringConverter", "tostringconverter"),
EDITOR("objecteditors", "Editor", "editor"),
ATTRIBUTE_EDITOR("objecteditors", "AttributeEditor", "attributeeditor"),
FEATURE_RENDERER("featurerenderer", "FeatureRenderer", "featurerenderer"),
ACTION_PROVIDER("objectactions", "ActionsProvider", "actionsprovider"),
PERMISSION_PROVIDER("permissions", "PermissionProvider", "permissionprovider"),
CUSTOM_BEAN("beans", "CustomBean", "custombean");
//~ Instance fields ----------------------------------------------------
final String packagePrefix;
final String classNameSuffix;
final String overrideProperty;
//~ Constructors -------------------------------------------------------
/**
* Creates a new CLASS_TYPE object.
*
* @param packagePrefix DOCUMENT ME!
* @param classNameSuffix DOCUMENT ME!
* @param overrideProperty DOCUMENT ME!
*/
private CLASS_TYPE(final String packagePrefix, final String classNameSuffix, final String overrideProperty) {
this.packagePrefix = packagePrefix;
this.classNameSuffix = classNameSuffix;
this.overrideProperty = overrideProperty;
}
}
//~ Constructors -----------------------------------------------------------
/**
* Creates a new ClassloadingHelper object.
*
* @throws AssertionError DOCUMENT ME!
*/
private ClassloadingHelper() {
throw new AssertionError();
}
//~ Methods ----------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @param metaClass DOCUMENT ME!
* @param mai DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static List<String> getClassNames(final MetaClass metaClass,
final MemberAttributeInfo mai,
final CLASS_TYPE classType) {
final List<String> result = new ArrayList<String>();
final String domain = metaClass.getDomain().toLowerCase();
final String tableName = metaClass.getTableName().toLowerCase();
final String fieldName = mai.getFieldName().toLowerCase();
final String overrideClassName = System.getProperty(domain + "." + tableName + "." + fieldName + "."
+ classType.overrideProperty);
if (overrideClassName != null) {
result.add(overrideClassName);
}
for (final String masterPrefix : packagePrefixes) {
final StringBuilder plainClassNameBuilder = new StringBuilder(masterPrefix + "." + classType.packagePrefix);
plainClassNameBuilder.append(".").append(domain).append(".").append(tableName).append(".");
final StringBuilder camelCaseClassNameBuilder = new StringBuilder(plainClassNameBuilder);
plainClassNameBuilder.append(capitalize(fieldName)).append(classType.classNameSuffix);
camelCaseClassNameBuilder.append(camelize(fieldName)).append(classType.classNameSuffix);
//
result.add(plainClassNameBuilder.toString());
result.add(camelCaseClassNameBuilder.toString());
}
//
final String configurationClassName = ((mai == null) ? getClassNameByConfiguration(metaClass, classType)
: getClassNameByConfiguration(mai, classType));
if (configurationClassName != null) {
result.add(configurationClassName);
}
return result;
}
/**
* DOCUMENT ME!
*
* @param toCapitalize DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static String capitalize(final String toCapitalize) {
final StringBuilder result = new StringBuilder(toCapitalize.length());
result.append(toCapitalize.substring(0, 1).toUpperCase()).append(toCapitalize.substring(1).toLowerCase());
return result.toString();
}
/**
* DOCUMENT ME!
*
* @param metaClass DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static List<String> getClassNames(final MetaClass metaClass, final CLASS_TYPE classType) {
final List<String> result = new ArrayList<String>();
final String tableName = metaClass.getTableName().toLowerCase();
final String domain = metaClass.getDomain().toLowerCase();
final String overrideClassName = System.getProperty(domain + "." + tableName + "."
+ classType.overrideProperty);
if (overrideClassName != null) {
result.add(overrideClassName);
}
if (tableName.length() > 2) {
for (final String masterPrefix : packagePrefixes) {
final StringBuilder plainClassNameBuilder = new StringBuilder(masterPrefix + "."
+ classType.packagePrefix);
plainClassNameBuilder.append(".").append(domain).append(".");
final StringBuilder camelCaseClassNameBuilder = new StringBuilder(plainClassNameBuilder);
//
plainClassNameBuilder.append(capitalize(tableName)).append(classType.classNameSuffix);
camelCaseClassNameBuilder.append(camelize(tableName)).append(classType.classNameSuffix);
//
result.add(plainClassNameBuilder.toString());
result.add(camelCaseClassNameBuilder.toString());
}
//
final String configurationClassName = getClassNameByConfiguration(metaClass, classType);
if (configurationClassName != null) {
result.add(configurationClassName);
}
} else {
log.error("Invalid table name: " + tableName);
}
return result;
}
/**
* DOCUMENT ME!
*
* @param metaClass DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static String getClassNameByConfiguration(final MetaClass metaClass, final CLASS_TYPE classType) {
switch (classType) {
case TO_STRING_CONVERTER: {
return metaClass.getToString();
}
case RENDERER: {
return metaClass.getRenderer();
}
case EDITOR: {
return metaClass.getEditor();
}
case AGGREGATION_RENDERER: {
final String caCfg = getClassAttributeValue("AGGREGATION_RENDERER", metaClass); // NOI18N
if (caCfg == null) {
// for backwards-compatibility
return metaClass.getRenderer();
} else {
return caCfg;
}
}
case FEATURE_RENDERER: {
return getClassAttributeValue("FEATURE_RENDERER", metaClass); // NOI18N
}
case CUSTOM_BEAN: {
return getClassAttributeValue("CUSTOM_BEAN", metaClass); // NOI18N
}
case ACTION_PROVIDER: {
return getClassAttributeValue("ACTION_PROVIDER", metaClass); // NOI18N
}
case ICON_FACTORY: {
return getClassAttributeValue("ICON_FACTORY", metaClass); // NOI18N
}
default: {
return null;
}
}
}
/**
* DOCUMENT ME!
*
* @param mai DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static String getClassNameByConfiguration(final MemberAttributeInfo mai, final CLASS_TYPE classType) {
switch (classType) {
case TO_STRING_CONVERTER: {
return mai.getToString();
}
case RENDERER: {
return mai.getRenderer();
}
case EDITOR: {
return mai.getEditor();
}
case AGGREGATION_RENDERER: {
return mai.getRenderer();
}
default: {
return null;
}
}
}
/**
* DOCUMENT ME!
*
* @param metaClass DOCUMENT ME!
* @param mai DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static String getClassNameByConfiguration(final MetaClass metaClass,
final MemberAttributeInfo mai,
final CLASS_TYPE classType) {
switch (classType) {
case ATTRIBUTE_EDITOR: {
return mai.getEditor();
}
default: {
return getClassNameByConfiguration(metaClass, classType);
}
}
}
/**
* DOCUMENT ME!
*
* @param name DOCUMENT ME!
* @param mc DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private static String getClassAttributeValue(final String name, final MetaClass mc) {
final Collection cca = mc.getAttributeByName(name);
if (cca.size() > 0) {
final ClassAttribute ca = (ClassAttribute)(cca.toArray()[0]);
final Object valueObj = ca.getValue();
if (valueObj != null) {
return valueObj.toString();
}
}
return null;
}
/**
* DOCUMENT ME!
*
* @param tableName DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static String camelize(final String tableName) {
boolean upperCase = true;
final char[] result = new char[tableName.length()];
int resultPosition = 0;
for (int i = 0; i < tableName.length(); ++i) {
char current = tableName.charAt(i);
if (Character.isLetterOrDigit(current)) {
if (upperCase) {
current = Character.toUpperCase(current);
upperCase = false;
} else {
current = Character.toLowerCase(current);
}
result[resultPosition++] = current;
} else {
upperCase = true;
}
}
return String.valueOf(result, 0, resultPosition);
}
/**
* DOCUMENT ME!
*
* @param candidateClassNames DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Class<?> loadClassFromCandidates(final List<String> candidateClassNames) {
for (final String candidateClassName : candidateClassNames) {
final Class<?> result = BlacklistClassloading.forName(candidateClassName);
if (result != null) {
return result;
}
}
return null;
}
/**
* DOCUMENT ME!
*
* @param metaClass DOCUMENT ME!
* @param mai DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Class<?> getDynamicClass(final MetaClass metaClass,
final MemberAttributeInfo mai,
final CLASS_TYPE classType) {
final List<String> classNames = getClassNames(metaClass, mai, classType);
return loadClassFromCandidates(classNames);
}
/**
* DOCUMENT ME!
*
* @param metaClass DOCUMENT ME!
* @param classType DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Class<?> getDynamicClass(final MetaClass metaClass, final CLASS_TYPE classType) {
final List<String> classNames = getClassNames(metaClass, classType);
return loadClassFromCandidates(classNames);
}
}