![JAR search and dependency download from the Maven repository](/logo.png)
xy.reflect.ui.control.swing.customizer.CustomizationToolsUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of custom-ui Show documentation
Show all versions of custom-ui Show documentation
Customizations editor for ReflectionUI
The newest version!
package xy.reflect.ui.control.swing.customizer;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.SwingUtilities;
import xy.reflect.ui.CustomizedUI;
import xy.reflect.ui.ReflectionUI;
import xy.reflect.ui.control.swing.renderer.SwingRenderer;
import xy.reflect.ui.control.swing.util.SwingRendererUtils;
import xy.reflect.ui.info.ColorSpecification;
import xy.reflect.ui.info.InfoCategory;
import xy.reflect.ui.info.ResourcePath;
import xy.reflect.ui.info.app.IApplicationInfo;
import xy.reflect.ui.info.custom.InfoCustomizations;
import xy.reflect.ui.info.custom.InfoCustomizations.AbstractCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.AbstractMemberCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.ColumnCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.ConversionMethodFinder;
import xy.reflect.ui.info.custom.InfoCustomizations.CustomTypeInfoFinder;
import xy.reflect.ui.info.custom.InfoCustomizations.CustomizationCategory;
import xy.reflect.ui.info.custom.InfoCustomizations.FieldCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.FieldTypeSpecificities;
import xy.reflect.ui.info.custom.InfoCustomizations.IMenuElementCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.IMenuItemContainerCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.ITypeInfoFinder;
import xy.reflect.ui.info.custom.InfoCustomizations.JavaClassBasedTypeInfoFinder;
import xy.reflect.ui.info.custom.InfoCustomizations.ListCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.Mapping;
import xy.reflect.ui.info.custom.InfoCustomizations.MethodCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.ParameterCustomization;
import xy.reflect.ui.info.custom.InfoCustomizations.TextualStorage;
import xy.reflect.ui.info.custom.InfoCustomizations.TypeConversion;
import xy.reflect.ui.info.custom.InfoCustomizations.TypeCustomization;
import xy.reflect.ui.info.field.IFieldInfo;
import xy.reflect.ui.info.menu.IMenuElementPosition;
import xy.reflect.ui.info.menu.MenuElementKind;
import xy.reflect.ui.info.method.IMethodInfo;
import xy.reflect.ui.info.method.InvocationData;
import xy.reflect.ui.info.method.MethodInfoProxy;
import xy.reflect.ui.info.parameter.IParameterInfo;
import xy.reflect.ui.info.type.ITypeInfo;
import xy.reflect.ui.info.type.enumeration.IEnumerationItemInfo;
import xy.reflect.ui.info.type.factory.InfoProxyFactory;
import xy.reflect.ui.info.type.source.JavaTypeInfoSource;
import xy.reflect.ui.info.type.source.SpecificitiesIdentifier;
import xy.reflect.ui.util.ClassUtils;
import xy.reflect.ui.util.MiscUtils;
import xy.reflect.ui.util.ReflectionUIError;
import xy.reflect.ui.util.ReflectionUIUtils;
/**
* This is a sub-class of {@link ReflectionUI} that generates the abstract UI
* model of customization tools.
*
* @author olitank
*
*/
public class CustomizationToolsUI extends CustomizedUI {
protected static final String IS_FIELD_TYPE_SPECIFICITIES_TYPE = CustomizationToolsUI.class.getName() + ".is"
+ FieldTypeSpecificities.class.getSimpleName();
protected final SwingCustomizer swingCustomizer;
public CustomizationToolsUI(InfoCustomizations infoCustomizations, SwingCustomizer swingCustomizer) {
super(infoCustomizations);
this.swingCustomizer = swingCustomizer;
}
@Override
protected ITypeInfo getTypeInfoBeforeCustomizations(ITypeInfo type) {
type = new InfoProxyFactory() {
@Override
public String toString() {
return "Before" + CustomizationTools.class.getName() + InfoProxyFactory.class.getSimpleName();
}
protected boolean isDerivedTypeInfo(ITypeInfo type, Class> baseClass) {
Class> clazz;
try {
clazz = ClassUtils.getCachedClassforName(type.getName());
} catch (ClassNotFoundException e) {
return false;
}
if (baseClass.isAssignableFrom(clazz)) {
return true;
}
return false;
}
@Override
protected String getCaption(IEnumerationItemInfo info, ITypeInfo parentEnumType) {
Object itemValue = info.getValue();
if (itemValue instanceof IMenuItemContainerCustomization) {
IMenuElementPosition position = ReflectionUIUtils.getMenuElementPosition(
swingCustomizer.getInfoCustomizations(), (IMenuItemContainerCustomization) itemValue);
if (position == null) {
return ((IMenuItemContainerCustomization) itemValue).getName();
}
List result = new ArrayList();
result.add(position.getElementName());
while (position.getParent() != null) {
position = position.getParent();
if (position.getElementKind() == MenuElementKind.MENU) {
result.add(0, position.getElementName());
} else if (position.getElementKind() == MenuElementKind.ITEM_CATEGORY) {
result.add(0, "(" + position.getElementName() + ")");
} else {
throw new ReflectionUIError();
}
}
return MiscUtils.stringJoin(result, " / ");
}
if (info.getValue() instanceof ResourcePath) {
ResourcePath resourcePath = (ResourcePath) itemValue;
return resourcePath.getDefaultSpecification();
}
return super.getCaption(info, parentEnumType);
}
@Override
protected boolean hasValueOptions(Object object, IFieldInfo field, ITypeInfo containingType) {
if ((object instanceof AbstractMemberCustomization) && field.getName().equals("categoryCaption")) {
return true;
} else if ((object instanceof MethodCustomization) && field.getName().equals("menuLocation")) {
return true;
} else {
return super.hasValueOptions(object, field, containingType);
}
}
@Override
protected Object[] getValueOptions(Object object, IFieldInfo field, ITypeInfo containingType) {
if ((object instanceof AbstractMemberCustomization) && field.getName().equals("categoryCaption")) {
List result = InfoCustomizations.getMemberCategoryCaptionOptions(
swingCustomizer.getInfoCustomizations(), (AbstractMemberCustomization) object);
return result.toArray();
} else if ((object instanceof MethodCustomization) && field.getName().equals("menuLocation")) {
TypeCustomization tc = InfoCustomizations.findParentTypeCustomization(
swingCustomizer.getInfoCustomizations(), (MethodCustomization) object);
List result = InfoCustomizations
.getAllMenuItemContainerCustomizations(tc);
return result.toArray();
} else {
return super.getValueOptions(object, field, containingType);
}
}
@Override
protected Map getSpecificProperties(ITypeInfo type) {
if (type.getName().equals(FieldTypeSpecificities.class.getName())) {
Map result = new HashMap(super.getSpecificProperties(type));
result.put(IS_FIELD_TYPE_SPECIFICITIES_TYPE, Boolean.TRUE);
return result;
}
return super.getSpecificProperties(type);
}
@Override
protected String getName(ITypeInfo type) {
if (type.getName().equals(FieldTypeSpecificities.class.getName())) {
return InfoCustomizations.class.getName();
}
return super.getName(type);
}
@Override
protected String getCaption(ITypeInfo type) {
if (type.getName().equals(FieldTypeSpecificities.class.getName())) {
return "";
}
return super.getCaption(type);
}
@Override
protected List getFields(ITypeInfo type) {
if (isDerivedTypeInfo(type, AbstractCustomization.class)) {
List result = new ArrayList();
for (IFieldInfo field : super.getFields(type)) {
if (field.getName().equals(InfoCustomizations.UID_FIELD_NAME)) {
continue;
}
if (field.getName().equals(InfoCustomizations.INITIAL_STATE_FIELD_NAME)) {
continue;
}
result.add(field);
}
return result;
} else {
return super.getFields(type);
}
}
@Override
protected List getMethods(ITypeInfo type) {
if (type.getName().equals(ListCustomization.class.getName())) {
List result = new ArrayList(super.getMethods(type));
result.add(getListItemTypeCustomizationDisplayMethod());
return result;
} else if (type.getName().equals(MethodCustomization.class.getName())) {
List result = new ArrayList(super.getMethods(type));
result.add(getLastInvocationDataStorageMethod());
return result;
} else {
return super.getMethods(type);
}
}
protected IMethodInfo getLastInvocationDataStorageMethod() {
return new MethodInfoProxy(IMethodInfo.NULL_METHOD_INFO) {
@Override
public String getSignature() {
return ReflectionUIUtils.buildMethodSignature(this);
}
@Override
public String getName() {
return "storeLastInvocationData";
}
@Override
public String getCaption() {
return "Store Last Invocation Data";
}
@Override
public Object invoke(Object object, InvocationData invocationData) {
MethodCustomization mc = (MethodCustomization) object;
InvocationData lastInvocationData = swingCustomizer.getLastInvocationDataByMethodSignature()
.get(mc.getMethodSignature());
if (lastInvocationData == null) {
throw new ReflectionUIError(
"Last invocation data not found for the method '" + mc.getMethodSignature() + "'");
}
List storages = new ArrayList(
mc.getSerializedInvocationDatas());
TextualStorage newStorage = new TextualStorage();
newStorage.save(lastInvocationData);
storages.add(newStorage);
mc.setSerializedInvocationDatas(storages);
return null;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public Runnable getNextInvocationUndoJob(final Object object, InvocationData invocationData) {
return new Runnable() {
@Override
public void run() {
MethodCustomization mc = (MethodCustomization) object;
List storages = new ArrayList(
mc.getSerializedInvocationDatas());
storages.remove(storages.size() - 1);
mc.setSerializedInvocationDatas(storages);
}
};
}
};
}
protected IMethodInfo getListItemTypeCustomizationDisplayMethod() {
return new MethodInfoProxy(IMethodInfo.NULL_METHOD_INFO) {
@Override
public String getSignature() {
return ReflectionUIUtils.buildMethodSignature(this);
}
@Override
public String getName() {
return "displayItemTypeCustomization";
}
@Override
public String getCaption() {
return "Display Item Type Customization";
}
@Override
public boolean isReadOnly() {
return true;
}
@Override
public Object invoke(final Object object, InvocationData invocationData) {
if (swingCustomizer.isCustomizationsEditorEnabled()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ListCustomization lc = (ListCustomization) object;
if (lc.getItemTypeName() == null) {
SwingRenderer renderer = swingCustomizer.getCustomizationTools()
.getToolsRenderer();
renderer.openInformationDialog(null, "The item type is not defined",
renderer.getObjectTitle(lc), renderer.getObjectIconImage(lc));
} else {
TypeCustomization t = InfoCustomizations.getTypeCustomization(
swingCustomizer.getInfoCustomizations(), lc.getItemTypeName());
swingCustomizer.getCustomizationTools().openCustomizationEditor(null, t);
}
}
});
}
return null;
}
};
}
@Override
protected String toString(ITypeInfo type, Object object) {
if (object instanceof TypeCustomization) {
return ((TypeCustomization) object).getTypeName();
} else if (object instanceof FieldCustomization) {
return ((FieldCustomization) object).getFieldName();
} else if (object instanceof MethodCustomization) {
return ((MethodCustomization) object).getMethodName();
} else if (object instanceof ParameterCustomization) {
return ((ParameterCustomization) object).getParameterName();
} else if (object instanceof ColumnCustomization) {
return ((ColumnCustomization) object).getColumnName();
} else if (object instanceof CustomizationCategory) {
return ((CustomizationCategory) object).getCaption();
} else if (object instanceof ResourcePath) {
String result = ((ResourcePath) object).getSpecification();
if (result.length() == 0) {
result = "";
}
return result;
} else if (object instanceof IMenuElementCustomization) {
return ((IMenuElementCustomization) object).getName();
} else if (object instanceof TypeConversion) {
String result = "To ";
ITypeInfoFinder newTypeFinder = ((TypeConversion) object).getNewTypeFinder();
if (MiscUtils.equalsOrBothNull(newTypeFinder, new TypeConversion().getNewTypeFinder())) {
result += "...";
} else {
result += "<" + ReflectionUIUtils.toString(CustomizationToolsUI.this, newTypeFinder) + ">";
}
return result;
} else if (object instanceof Mapping) {
String result = "Convert";
ConversionMethodFinder reverseConversion = ((Mapping) object).getReverseConversionMethodFinder();
if (reverseConversion != null) {
if (reverseConversion.getConversionMethodSignature() != null) {
String typeName = ReflectionUIUtils.extractMethodReturnTypeNameFromSignature(
reverseConversion.getConversionMethodSignature());
result += " From " + typeName;
}
}
ConversionMethodFinder conversion = ((Mapping) object).getConversionMethodFinder();
if (conversion != null) {
if (conversion.getConversionMethodSignature() != null) {
String typeName = ReflectionUIUtils.extractMethodReturnTypeNameFromSignature(
conversion.getConversionMethodSignature());
result += " To " + typeName;
}
}
result += "...";
return result;
} else if (object instanceof JavaClassBasedTypeInfoFinder) {
return ((JavaClassBasedTypeInfoFinder) object).getClassName();
} else if (object instanceof CustomTypeInfoFinder) {
return "Custom Type Implemented By " + ((CustomTypeInfoFinder) object).getImplementationClassName();
} else if (object instanceof TextualStorage) {
Object stored = ((TextualStorage) object).load();
String result = ReflectionUIUtils.toString(CustomizationToolsUI.this, stored);
if (stored != null) {
ITypeInfo storedType = CustomizationToolsUI.this
.buildTypeInfo(CustomizationToolsUI.this.getTypeInfoSource(stored));
result = "(" + storedType.getCaption() + ") " + result;
}
return result;
} else if (object instanceof FieldTypeSpecificities) {
return "";
} else {
return super.toString(type, object);
}
}
@Override
protected ITypeInfo getType(IFieldInfo field, ITypeInfo containingType) {
if (field.getType().getName().equals(ColorSpecification.class.getName())) {
return buildTypeInfo(new JavaTypeInfoSource(CustomizationToolsUI.this, Color.class,
new SpecificitiesIdentifier(containingType.getName(), field.getName())));
}
return super.getType(field, containingType);
}
@Override
protected Object getValue(Object object, IFieldInfo field, ITypeInfo containingType) {
if (field.getType().getName().equals(ColorSpecification.class.getName())) {
ColorSpecification colorSpec = (ColorSpecification) super.getValue(object, field, containingType);
if (colorSpec == null) {
return null;
}
return SwingRendererUtils.getColor(colorSpec);
} else {
return super.getValue(object, field, containingType);
}
}
@Override
protected void setValue(Object object, Object value, IFieldInfo field, ITypeInfo containingType) {
if (field.getType().getName().equals(ColorSpecification.class.getName())) {
Color color = (Color) value;
ColorSpecification colorSpec = null;
if (color != null) {
colorSpec = SwingRendererUtils.getColorSpecification(color);
}
super.setValue(object, colorSpec, field, containingType);
} else {
super.setValue(object, value, field, containingType);
}
}
}.wrapTypeInfo(type);
return type;
}
@Override
protected ITypeInfo getTypeInfoAfterCustomizations(ITypeInfo type) {
type = new InfoProxyFactory() {
@Override
public String toString() {
return "After" + CustomizationTools.class.getName() + InfoProxyFactory.class.getSimpleName();
}
@Override
protected List getFields(ITypeInfo type) {
if (Boolean.TRUE.equals(type.getSpecificProperties().get(IS_FIELD_TYPE_SPECIFICITIES_TYPE))) {
List result = new ArrayList<>(super.getFields(type));
for (Iterator it = result.iterator(); it.hasNext();) {
IFieldInfo field = it.next();
InfoCategory category = field.getCategory();
if (category != null) {
if (!Arrays.asList("Types", "Lists", "Enumerations").contains(category.getCaption())) {
it.remove();
}
}
}
return result;
}
return super.getFields(type);
}
@Override
protected String getOnlineHelp(IApplicationInfo appInfo) {
return fixOnlineHelp(super.getOnlineHelp(appInfo));
}
@Override
protected String getOnlineHelp(IFieldInfo field, ITypeInfo containingType) {
return fixOnlineHelp(super.getOnlineHelp(field, containingType));
}
@Override
protected String getOnlineHelp(IParameterInfo param, IMethodInfo method, ITypeInfo containingType) {
return fixOnlineHelp(super.getOnlineHelp(param, method, containingType));
}
@Override
protected String getOnlineHelp(ITypeInfo type) {
return fixOnlineHelp(super.getOnlineHelp(type));
}
@Override
protected String getOnlineHelp(IMethodInfo method, ITypeInfo containingType) {
return fixOnlineHelp(super.getOnlineHelp(method, containingType));
}
@Override
protected String getOnlineHelp(IEnumerationItemInfo info, ITypeInfo parentEnumType) {
return fixOnlineHelp(super.getOnlineHelp(info, parentEnumType));
}
/**
* @param onlineHelp Online help message.
* @return an improved online help message (see the class OnlineHelpFi)x.
*/
protected String fixOnlineHelp(String onlineHelp) {
if (onlineHelp == null) {
return null;
}
if (MiscUtils.isHTMLText(onlineHelp)) {
return onlineHelp;
}
return "" + OnlineHelpFix.adaptToHtml(onlineHelp) + "";
}
}.wrapTypeInfo(type);
return type;
}
@Override
public void logError(String msg) {
super.logError(msg);
}
/**
* This class is used to improve online help messages of customization tools by
* converting them to HTML. It is intended to be a temporary fix while updating
* the help messages.
*
* @author olitank
*
*/
public static class OnlineHelpFix {
protected static final List ALL_LEGACY_BULLET_CHARACTERS = Arrays.asList('-', '.');
public static String adaptToHtml(String onlineHelp) {
String result = onlineHelp;
result = MiscUtils.escapeHTML(result, false);
result = result.replace(" ", "");
result = convertBullets(result, ALL_LEGACY_BULLET_CHARACTERS);
return result;
}
protected static String convertBullets(String onlineHelp, List bulletCharacters) {
String result = onlineHelp;
if (bulletCharacters.size() == 0) {
throw new ReflectionUIError();
}
Character bulletCharacter = bulletCharacters.get(0);
String escapedBulletCharacter = MiscUtils.escapeRegex(Character.toString(bulletCharacter));
boolean bulletFound = false;
for (Pattern bulletPattern : Arrays.asList(
Pattern.compile("\\n\\s+" + escapedBulletCharacter + "(.*?)(?=(\\n\\s+" + escapedBulletCharacter
+ "|\\n[A-Za-z0-9]|$))", Pattern.DOTALL),
Pattern.compile("\\n" + escapedBulletCharacter + "(.*?)(?=(\\n" + escapedBulletCharacter + "|$))",
Pattern.DOTALL))) {
Matcher matcher = bulletPattern.matcher(result);
if (matcher.find()) {
bulletFound = true;
StringBuffer replacementResult = new StringBuffer();
StringBuffer headReplacementResult = new StringBuffer();
{
matcher.appendReplacement(headReplacementResult, "");
matcher.find(matcher.start());
}
replacementResult.append(processParagraph(headReplacementResult.toString()) + "");
do {
if (bulletCharacters.size() == 1) {
StringBuffer subReplacementResult = new StringBuffer();
matcher.appendReplacement(subReplacementResult, "$1");
if (headReplacementResult != null) {
replacementResult.append("- " + processParagraph(
subReplacementResult.toString().substring(headReplacementResult.length()))
+ "
");
} else {
replacementResult
.append("- " + processParagraph(subReplacementResult.toString()) + "
");
}
} else {
StringBuffer subReplacementResult = new StringBuffer();
subReplacementResult.append(result.substring(matcher.start(1), matcher.end(1)));
replacementResult.append("- " + convertBullets(subReplacementResult.toString(),
bulletCharacters.subList(1, bulletCharacters.size())) + "
");
// to make matcher.appendTail(replacementResult) work
matcher.appendReplacement(new StringBuffer(), "");
}
headReplacementResult = null;
} while (matcher.find());
replacementResult.append("
");
StringBuffer tailReplacementResult = new StringBuffer();
{
matcher.appendTail(tailReplacementResult);
}
replacementResult.append(processParagraph(tailReplacementResult.toString()));
result = replacementResult.toString();
}
}
result = result.replace("\n", " ");
if (!bulletFound) {
result = processParagraph(result);
}
return result;
}
protected static String processParagraph(String string) {
return "" + string + "
";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy