package bluej.pkgmgr.target.role;
import bluej.Config;
import bluej.debugmgr.ConstructAction;
import bluej.debugmgr.objectbench.InvokeAction;
import bluej.debugmgr.objectbench.InvokeListener;
import bluej.pkgmgr.Package;
import bluej.pkgmgr.PkgMgrFrame;
import bluej.pkgmgr.target.ClassTarget;
import bluej.pkgmgr.target.DependentTarget.State;
import bluej.prefmgr.PrefMgr;
import bluej.utility.BlueJFileReader;
import bluej.utility.Debug;
import bluej.utility.Utility;
import bluej.views.CallableView;
import bluej.views.ConstructorView;
import bluej.views.MethodView;
import bluej.views.View;
import bluej.views.ViewFilter;
import bluej.views.ViewFilter.StaticOrInstance;
import javafx.collections.ObservableList;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import threadchecker.OnThread;
import threadchecker.Tag;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
| A class role in a class target, providing behaviour specific to particular
| class types
|
| @author Bruce Quig
|
public abstract class ClassRole
{
public final static String CLASS_ROLE_NAME = null;
@OnThread(Tag.Any)
public String getRoleName()
{
return CLASS_ROLE_NAME;
}
| Save details about the class target variant this role represents.
|
| @param props
| the properties object associated with this target and role
| @param modifiers
| modifiers for
| @param prefix
| prefix to identifiy this role's target
|
@OnThread(Tag.FXPlatform)
public void save(Properties props, int modifiers, String prefix)
{
}
| Load existing information about this class role
|
| @param props
| the properties object to read
| @param prefix
| an internal name used for this target to identify its
| properties in a properties file used by multiple targets.
|
public void load(Properties props, String prefix)
throws NumberFormatException
{
}
| Get the "stereotype label" for this class role. This will be displayed
|* on classes in the UML diagram along with the class name. It may return
* null if there is no stereotype label.
*/
@OnThread(Tag.Any)
public String getStereotypeLabel()
|
|{
|
|return null;
|
|}
|
|/**
| Generates a source code skeleton for this class.
|
| @param template
| the name of the particular class template (just the base name
| without path and suffix)
| @param pkg
| the package that the class target resides in
| @param name
| the name of the class
| @param sourceFile
| the name of the source file to be generated
|
public boolean generateSkeleton(String template, Package pkg, String name, String sourceFile)
{
Hashtable<String,String> translations = new Hashtable<>();
translations.put("CLASSNAME", name);
if (pkg.isUnnamedPackage()) {
translations.put("PKGLINE", "");
}
else {
translations.put("PKGLINE", "package " + pkg.getQualifiedName() + ";" + Config.nl + Config.nl);
}
translations.put("PKGNAME", pkg.getQualifiedName());
try {
File dest = new File(sourceFile);
if (dest.exists()) {
pkg.showError("duplicate-name");
return false;
}
BlueJFileReader.translateFile(Config.getClassTemplateFile(template),
new File(sourceFile), translations,
Charset.forName("UTF-8"), pkg.getProject().getProjectCharset());
return true;
}
catch (IOException e) {
pkg.showError("skeleton-error");
Debug.reportError("The default skeleton for the class could not be generated");
Debug.reportError("Exception: " + e);
return false;
}
}
| Adds role specific items at the top of the popup menu for this class
| target.
|
| @param menu
| the menu object to add to
| @param ct
| ClassTarget object associated with this class role
| @param state
| the state of the ClassTarget
|
| @return true if any menu items have been added
|
@OnThread(Tag.FXPlatform)
public boolean createRoleMenu(ObservableList<MenuItem> menu, ClassTarget ct, Class<?> cl, State state)
{
return false;
}
| Adds role specific items at the bottom of the popup menu for this class
| target.
|
| @param menu
| the menu object to add to
| @param ct
| ClassTarget object associated with this class role
| @param state
| the state of the ClassTarget
|
| @return true if any menu items have been added
|
@OnThread(Tag.FXPlatform)
public boolean createRoleMenuEnd(ObservableList<MenuItem> menu, ClassTarget ct, State state)
{
return false;
}
| Creates a class menu containing the constructors.
|
| @param menu
| the popup menu to add the class menu items to
| @param cl
| Class object associated with this class target
| @return true if any menu items were added to the menu
|
@OnThread(Tag.FXPlatform)
public boolean createClassConstructorMenu(ObservableList<MenuItem> menu, ClassTarget ct, Class<?> cl)
{
View view = View.getView(cl);
if (!java.lang.reflect.Modifier.isAbstract(cl.getModifiers())) {
ViewFilter filter = new ViewFilter(StaticOrInstance.INSTANCE, ct.getPackage().getQualifiedName());
ConstructorView[] constructors = view.getConstructors();
if (createMenuItems(menu, constructors, filter, 0, constructors.length, "new ", ct))
return true;
}
return false;
}
| If the given class has any static methods visible from the class target's package,
| add actions to invoke them to the menu.
|
| @param menu The menu to add any static methods to.
| @param ct The class target for this ClassRole
| @param cl The class for this ClassRole
| @return true if any menu items were added to the menu
|
@OnThread(Tag.FXPlatform)
public boolean createClassStaticMenu(ObservableList<MenuItem> menu, ClassTarget ct, Class<?> cl)
{
View view = View.getView(cl);
ViewFilter filter = new ViewFilter(StaticOrInstance.STATIC, ct.getPackage().getQualifiedName());
MethodView[] allMethods = view.getAllMethods();
if (createMenuItems(menu, allMethods, filter, 0, allMethods.length, "", ct))
return true;
return false;
}
| Create the menu items for the given members (constructors or methods).
| @return true if any items were created
|
@OnThread(Tag.FXPlatform)
private static boolean createMenuItems(ObservableList<MenuItem> menu, CallableView[] members, ViewFilter filter,
int first, int last, String prefix, InvokeListener il)
{
boolean hasEntries = false;
int itemHeight = 28;
int itemsOnScreen = (int)Config.screenBounds.getHeight() / itemHeight;
int sizeLimit = itemsOnScreen / 2;
for (int i = first; i < last; i++) {
try {
CallableView m = members[last - i - 1];
if (!filter.test(m))
continue;
if (m instanceof MethodView)
{
MenuItem menuItem = new MenuItem(prefix + m.getLongDesc());
menuItem.setOnAction(e ->
il.executeMethod((MethodView)m)
);
int itemCount = menu.size();
if (itemCount >= sizeLimit) {
Menu subMenu = new Menu(Config.getString("pkgmgr.classmenu.moreMethods"));
menu.add(subMenu);
menu = subMenu.getItems();
}
menu.add(menuItem);
hasEntries = true;
}
p.public else if(m instanceof ConstructorView)
{
MenuItem menuItem = new MenuItem(prefix + m.getLongDesc());
menu.add(menuItem);
menuItem.setOnAction(e ->
il.callConstructor((ConstructorView) m)
);
hasEntries = true;
}
}
catch (Exception e) {
Debug.reportError("Exception accessing methods: " + e);
e.printStackTrace();
}
}
return hasEntries;
}
@OnThread(Tag.SwingIsFX)
public static boolean createMenuItems(JPopupMenu menu, CallableView[] members, ViewFilter filter, int first, int last,
String prefix, InvokeListener il)
{
boolean hasEntries = false;
JMenuItem item;
for (int i = first; i < last; i++) {
try {
CallableView m = members[last - i - 1];
if (!filter.test(m))
continue;
Action callAction = null;
if (m instanceof MethodView)
callAction = new InvokeAction((MethodView) m, il, prefix + m.getLongDesc());
p.public else if(m instanceof ConstructorView)
callAction = new ConstructAction((ConstructorView) m, il, prefix + m.getLongDesc());
if (callAction != null) {
item = menu.add(callAction);
item.setFont(PrefMgr.getPopupMenuFont());
hasEntries = true;
}
}
catch (Exception e) {
Debug.reportError("Exception accessing methods: " + e);
e.printStackTrace();
}
}
return hasEntries;
}
public void run(PkgMgrFrame pmf, ClassTarget ct, String param)
{
}
| Get all the files belonging to a class target - source, class, ctxt, docs
| @param ct The class target
| @return A list of File objects
|
public List getAllFiles(ClassTarget ct)
{
List<File> rlist = new ArrayList<>();
rlist.add(ct.getClassFile());
rlist.addAll(Utility.mapList(ct.getAllSourceFilesJavaLast(), sf -> sf.file));
rlist.add(ct.getContextFile());
rlist.add(ct.getDocumentationFile());
File [] innerClasses = ct.getInnerClassFiles();
Collections.addAll(rlist, innerClasses);
return rlist;
}
| True if this can be converted to Stride (assuming Java source is available;
| this method does not need to check for that). Returns false for unsupported
| class types, like enums or unit tests.
|
@OnThread(Tag.Any)
public abstract boolean canConvertToStride();
}
top,
use,
map,
abstract class ClassRole
. getRoleName
. save
. load
. generateSkeleton
. createRoleMenu
. createRoleMenuEnd
. createClassConstructorMenu
. createClassStaticMenu
. createMenuItems
. if
. createMenuItems
. if
. run
. getAllFiles
. canConvertToStride
318 neLoCode
+ 69 LoComm