All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.appdapter.gui.trigger.UtilityMenuOptions Maven / Gradle / Ivy

Go to download

Appdapter Maven project including Java and Scala, produces jar, not bundle. Excludes concrete SLF4J binding.

The newest version!
package org.appdapter.gui.trigger;

import java.awt.event.ActionEvent;
import java.beans.Customizer;
import java.beans.PropertyEditor;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;

import org.appdapter.api.trigger.AnyOper;
import org.appdapter.api.trigger.Box;
import org.appdapter.api.trigger.Trigger;
import org.appdapter.bind.rdf.jena.model.JenaModelUtils;
import org.appdapter.core.component.KnownComponent;
import org.appdapter.core.convert.ReflectUtils;
import org.appdapter.core.convert.TypeAssignable;
import org.appdapter.core.debug.UIAnnotations.Autoload;
import org.appdapter.core.debug.UIAnnotations.UISalient;
import org.appdapter.core.debug.UIAnnotations.UtilClass;
import org.appdapter.core.log.Debuggable;
import org.appdapter.core.store.dataset.RepoDatasetFactory;
import org.appdapter.gui.api.DisplayContext;
import org.appdapter.gui.api.ScreenBox;
import org.appdapter.gui.browse.Utility;
import org.appdapter.gui.demo.DemoBrowser;
import org.appdapter.gui.editors.ObjectPanel;
import org.appdapter.gui.repo.RepoManagerPanel;
import org.appdapter.gui.swing.ScreenBoxPanel;
import org.appdapter.gui.util.ClassFinder;
import org.appdapter.gui.util.PromiscuousClassUtilsA;
import org.appdapter.trigger.bind.jena.BoxImpl;
import org.appdapter.trigger.bind.jena.TriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.hpl.jena.rdf.model.ModelFactory;
// import com.hp.hpl.jena.shared.ReificationStyle;

@UISalient(NonPublicMethods = false)
abstract public class UtilityMenuOptions implements UtilClass {

	protected static Logger theLogger = LoggerFactory.getLogger(UtilityMenuOptions.class);

	public static boolean addPanelClasses = false;
	public static boolean addGlobalStatics = true;
	public static boolean allTriggersAreGlobal = true;
	public static boolean useBeanIcons = false;
	public static boolean usePropertyEditorManager = false;
	public static boolean separateSlowThreads = true;
	public static boolean scanForMissingScreenBoxPanels = false;
	public static boolean doErrorCheckScanForMissingScreenBoxPanels = false;

	public static void setAllFeatures(boolean tf) {
		scanForMissingScreenBoxPanels = tf;
		doErrorCheckScanForMissingScreenBoxPanels = tf;
		ClassFinder.DISABLE_CLASS_FINDER = !tf;
		if (tf) {
			Utility.RAN_FIRST_INIT_GUI = false;
			Utility.initGUI();
		}
	}

	interface VoidFunc2 {
		void call(A a, B b);
	}

	public static void findAndloadMissingUtilityClasses() throws IOException {
		Utility.addClassMethods(JenaModelUtils.class);
		VoidFunc2 fw = new VoidFunc2() {
			@Override public void call(Class cls, Class ancestor) {
				Utility.addClassMethods(cls);
			}
		};

		Utility.taskEqueue.setSynchronous(false);
		withSubclasses(KnownComponent.class, fw);
		withSubclasses(DemoBrowser.class, fw);
		withSubclasses(Box.class, fw);
		withSubclasses(Trigger.class, fw);
		withSubclasses(UtilClass.class, fw);
		withSubclasses(AnyOper.class, fw);
		withSubclasses(ModelFactory.class, fw);
		withSubclasses(RepoDatasetFactory.class, fw);
		useScannedClasses("com.hp.hpl.jena.rdf.model.", fw);
		
		// createEnumClass(ReificationStyle.class);

		Utility.taskEqueue.waitUntilLastJobComplete();
		loadAutoloads();
		Utility.addClassMethods(RepoManagerPanel.class);

		if (!scanForMissingScreenBoxPanels)
			return;

		withSubclasses(Customizer.class, fw, false);
		withSubclasses(PropertyEditor.class, fw, false);
		withSubclasses(ObjectPanel.class, fw, true);
		withSubclasses(ScreenBoxPanel.class, fw, true);
	}

	public static void ensurePanelsAllRegistered() {
		if (!doErrorCheckScanForMissingScreenBoxPanels)
			return;
		VoidFunc2 fw = new VoidFunc2() {
			@Override public void call(Class cls, Class parent) {
				if (!ReflectUtils.isCreatable(cls))
					return;
				if (!Utility.ensurePanelRegistered(cls)) {
					theLogger.warn("ERROR unregistered PANEL " + cls + " will be ignored");
				}
			}
		};

		withSubclasses(Customizer.class, fw, false);
		withSubclasses(PropertyEditor.class, fw, false);
		withSubclasses(ObjectPanel.class, fw, true);
		withSubclasses(ScreenBoxPanel.class, fw, true);
	}

	private static void createEnumClass(Class ec) {
		Utility.addClassMethods(ec);
	}

	private static  void withSubclasses(final Class ancestor, final VoidFunc2 func, final boolean onlyCore) {

		Utility.runTask(new Runnable() {

			@Override public void run() {
				Collection which = getSubClasses("", ancestor, onlyCore);
				for (Class cls : which) {
					try {
						func.call(cls, ancestor);
					} catch (Throwable t) {
						theLogger.error("With subclass " + cls + " of " + ancestor, t);
					}
				}
			}

			@Override public String toString() {
				return "With subclassof " + ancestor + " via " + func;
			}
		});
	}

	private static  Collection getSubClasses(String packagePrefix, Class ancestor, boolean onlyCore) {

		if (onlyCore) {
			if (packagePrefix == null || packagePrefix.length() == 0) {
				return (Collection) Utility.getCoreClasses(ancestor);
			} else {
				HashSet which = new HashSet();
				for (Class c : Utility.getCoreClasses(ancestor)) {
					if (("" + c).contains(packagePrefix)) {
						which.add(c);
					}
				}
				return which;
			}
		} else {
			try {
				return (Collection) ClassFinder.getClasses(packagePrefix, ancestor);
			} catch (IOException e) {
				e.printStackTrace();
				if (packagePrefix == null || packagePrefix.length() == 0) {
					return (Collection) PromiscuousClassUtilsA.getImplementingClasses(ancestor);
				} else {
					HashSet which = new HashSet();
					for (Class c : PromiscuousClassUtilsA.getImplementingClasses(ancestor)) {
						if (("" + c).contains(packagePrefix)) {
							which.add(c);
						}
					}
					return which;
				}

			}
		}
	}

	private static  void withSubclasses(Class ancestor, VoidFunc2 func) {
		withSubclasses(ancestor, func, true);
	}

	private static  void useScannedClasses(String packagePrefix, VoidFunc2 func) {

		final Class ancestor = Object.class;
		try {
			Collection which = getSubClasses(packagePrefix, ancestor, false);
			for (Class cls : which) {
				try {
					func.call((Class) cls, ancestor);
				} catch (Throwable t) {
					theLogger.error("With subclass " + cls + " of " + ancestor, t);
				}
			}
		} catch (Throwable e) {
			theLogger.error("With subclass " + packagePrefix + " of " + ancestor, e);
		}
	}

	static @UISalient() public void loadDemoObjects() {
		DemoBrowser.addMoreExamples();
		Utility.updateToolsMenu();
	}

	static @UISalient() public void loadAutoloads() {
		VoidFunc2 fw = new VoidFunc2() {
			@Override public void call(Class cls, Class ancestor) {
				if (!cls.isInterface())
					Utility.addClassMethods(cls);
			}
		};
		withSubclasses(Autoload.class, fw);
	}

	public static void findAndloadMissingTriggers() throws IOException {
		VoidFunc2 fw = new VoidFunc2() {
			@Override public void call(Class cls, Class ancestor) {
				if (!cls.isInterface())
					Utility.addClassMethods(cls);
			}
		};
		withSubclasses(Trigger.class, fw);
	}

	static private Set allBoxTypes = new HashSet();

	public static Collection getAllBoxTypes() throws IOException {
		synchronized (allBoxTypes) {
			if (allBoxTypes.size() == 0) {
				for (Class cls : Utility.getCoreClasses(Box.class)) {
					try {
						if (ReflectUtils.isCreatable(cls)) {
							allBoxTypes.add(cls);
						}
					} catch (Throwable t) {
						Debuggable.printStackTrace(t);
					}
				}
			}
		}
		return allBoxTypes;

	}

	static Trigger createTrigger(Class cls, Object... params) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException {
		for (Constructor c : cls.getDeclaredConstructors()) {
			Class[] pt = c.getParameterTypes();
			if (pt.length > 0 && pt.length == params.length) {
				return (Trigger) c.newInstance(params);
			}
		}
		return (Trigger) cls.getDeclaredConstructors()[0].newInstance();
	}

	static Collection skippedTypes = new HashSet() {
		{
			add(Box.class);
			add(ScreenBox.class);
			add(org.appdapter.gui.box.ScreenBoxImpl.class);
			add(BoxImpl.class);
			add(Trigger.class);
			add(TriggerImpl.class);
			add(Object.class);
			addAll(ReflectUtils.asList(TriggerImpl.class.getInterfaces()));
			addAll(ReflectUtils.asList(org.appdapter.gui.box.ScreenBoxImpl.class.getInterfaces()));
			add(java.io.Serializable.class);
		}
	};

	private static void addTriggerClass(final Class cls) {
		if (!ReflectUtils.isCreatable(cls))
			return;
		Class classOfBox;
		boolean hasNoSideEffects = false;
		Callable howto = new Callable() {
			public Trigger call() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException {
				return createTrigger(cls);
			}
		};
		String menuName = ReflectUtils.getCanonicalSimpleName(cls);
		if (menuName.endsWith("Trigger")) {
			menuName = menuName.substring(0, menuName.length() - 7);
		}
		Member member;
		final boolean isDeclNonStatic0 = true;

		try {
			// checks for some type and claims this will be good for it
			if (TriggerForClass.class.isAssignableFrom(cls)) {
				Utility.addTriggerForClassInst((TriggerForClass) cls.newInstance());
				return;
			}
		} catch (Throwable e) {
			// otherwise look for another registration method
		}

		try {
			// checks for a static final field of some type and claims this will be good for it
			classOfBox = (Class) cls.getField("boxTargetClass").get(null);
			member = classOfBox.getDeclaredConstructors()[0];
			addTriggerForClass(menuName, classOfBox, member, howto, isDeclNonStatic0, hasNoSideEffects);
			return;
		} catch (Throwable e) {
			// otherwise look for another registration method
		}

		try {
			// checks for a fire(WhatNotBox box) and claims this will be good for it
			Method method = ReflectUtils.getDeclaredMethod(cls, "fire", false, false, 1);
			if (method != null) {
				classOfBox = ReflectUtils.getTypeClass(method.getGenericParameterTypes()[0], null, new ArrayList(skippedTypes));
				if (classOfBox != null) {
					member = method;
					addTriggerForClass(menuName, classOfBox, member, howto, isDeclNonStatic0, hasNoSideEffects);
					return;
				}
			}
		} catch (Throwable e) {
			// otherwise look for another registration method
		}

		try {
			// checks for a SomeTrigger(WhatNot classOfBox) and claims this will be good for it
			Constructor method = ReflectUtils.getDeclaredConstructor(cls, TypeAssignable.ANY, 1);
			if (method != null) {
				classOfBox = ReflectUtils.getTypeClass(method.getGenericParameterTypes()[0], null, new ArrayList(skippedTypes));
				if (classOfBox != null) {
					member = method;
					addTriggerForClass(menuName, classOfBox, member, howto, isDeclNonStatic0, hasNoSideEffects);
					return;
				}
			}
		} catch (Throwable e) {
			// otherwise look for another registration method
		}

		try {
			// checks for some type and claims this will be good for it
			classOfBox = ReflectUtils.getTypeClass(cls.getTypeParameters(), null, new ArrayList(skippedTypes));
			if (classOfBox != null) {
				member = classOfBox.getDeclaredConstructors()[0];
				//@todo ?
				addTriggerForClass(menuName, classOfBox, member, howto, isDeclNonStatic0, hasNoSideEffects);
			}
		} catch (Throwable e) {
			// otherwise look for another registration method
		}

		theLogger.warn("Unable to register triggers from: " + cls);
	}

	private static void addTriggerForClass(final String menuName, final Class classOfBox, final Member member, final Callable valueOf, final boolean isDeclNonStatic0,
			final boolean hasNoSideEffects) {

		Utility.addTriggerForClassInst(new TriggerForClass() {

			@Override public boolean isSideEffectSafe() {
				return false;
			}

			@Override public boolean isFavorited() {
				return true;
			}

			@Override public Object getIdentityObject() {
				return member;
			}

			@Override public String toString() {
				return Debuggable.toInfoStringF(this);
			}

			@Override public KMCTrigger createTrigger(String menuFmt, DisplayContext ctx, Object poj) {
				return new KMCTriggerImpl(menuName, ctx, classOfBox, poj, member, isDeclNonStatic0, null, hasNoSideEffects) {
					@Override public void fire(Box targetBox) {
						super.fire(targetBox);
					}

					@Override public Object getIdentityObject() {
						return member;
					}

					@Override public Object valueOf(Box targetBox, ActionEvent actevt, boolean wantSideEffect, boolean isPaste) throws InvocationTargetException {
						try {
							if (!wantSideEffect)
								return null;
							valueOf.call().fire(targetBox);
							return null;
						} catch (InvocationTargetException ite) {
							throw ite;
						} catch (Exception e) {
							throw new InvocationTargetException(e);
						}
					}
				};
			}

			@Override public boolean appliesTarget(Class cls, Object anyObject) {
				return ReflectUtils.convertsTo(anyObject, cls, classOfBox);
			}

			@Override public String getMenuPath() {
				return "" + member;
			}

		});
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy