added support for mote interface requirements in SupportedArguments annotation

NativeIPGateway plugin now requires an IP address mote interface
This commit is contained in:
Fredrik Osterlind 2012-06-05 14:45:16 +02:00
parent 49b949f9db
commit b322eda91a
3 changed files with 57 additions and 25 deletions

View file

@ -69,18 +69,21 @@ import org.jdom.Element;
import se.sics.cooja.ClassDescription; import se.sics.cooja.ClassDescription;
import se.sics.cooja.GUI; import se.sics.cooja.GUI;
import se.sics.cooja.GUI.RunnableInEDT;
import se.sics.cooja.Mote; import se.sics.cooja.Mote;
import se.sics.cooja.MotePlugin; import se.sics.cooja.MotePlugin;
import se.sics.cooja.PluginType; import se.sics.cooja.PluginType;
import se.sics.cooja.Simulation; import se.sics.cooja.Simulation;
import se.sics.cooja.SupportedArguments;
import se.sics.cooja.VisPlugin; import se.sics.cooja.VisPlugin;
import se.sics.cooja.GUI.RunnableInEDT;
import se.sics.cooja.dialogs.CompileContiki; import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList; import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.SerialPort; import se.sics.cooja.interfaces.SerialPort;
@ClassDescription("Open Native IP Gateway") @ClassDescription("Open Native IP Gateway")
@PluginType(PluginType.MOTE_PLUGIN) @PluginType(PluginType.MOTE_PLUGIN)
@SupportedArguments(moteInterfaces = {IPAddress.class})
public class NativeIPGateway extends VisPlugin implements MotePlugin { public class NativeIPGateway extends VisPlugin implements MotePlugin {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(NativeIPGateway.class); private static Logger logger = Logger.getLogger(NativeIPGateway.class);
@ -238,7 +241,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
} }
/* Detect selected network interface */ /* Detect selected network interface */
NetworkInterfaceW intf = NetworkInterfaceW intf =
(NetworkInterfaceW) ((JComboBox)e.getSource()).getSelectedItem(); (NetworkInterfaceW) ((JComboBox)e.getSource()).getSelectedItem();
if (networkInterface == intf) { if (networkInterface == intf) {
/* Already selected */ /* Already selected */
@ -546,7 +549,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
final JDialog progressDialog; final JDialog progressDialog;
if (GUI.isVisualized()) { if (GUI.isVisualized()) {
progressDialog = new JDialog( progressDialog = new JDialog(
(Window)GUI.getTopParentContainer(), (Window)GUI.getTopParentContainer(),
"Starting Native IP Gateway plugin" "Starting Native IP Gateway plugin"
); );
} else { } else {
@ -564,7 +567,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
progressDialog.getContentPane().add(BorderLayout.NORTH, progressBar); progressDialog.getContentPane().add(BorderLayout.NORTH, progressBar);
progressDialog.getContentPane().add(BorderLayout.CENTER, new JScrollPane(output)); progressDialog.getContentPane().add(BorderLayout.CENTER, new JScrollPane(output));
progressDialog.setSize(350, 150); progressDialog.setSize(350, 150);
progressDialog.setLocationRelativeTo((Window)GUI.getTopParentContainer()); progressDialog.setLocationRelativeTo(GUI.getTopParentContainer());
progressDialog.setVisible(true); progressDialog.setVisible(true);
GUI.setProgressMessage("Compiling hello-world.minimal-net (Native IP Gateway)"); GUI.setProgressMessage("Compiling hello-world.minimal-net (Native IP Gateway)");
return true; return true;
@ -613,7 +616,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
} }
}); });
Runtime.getRuntime().addShutdownHook(shutdownHook); Runtime.getRuntime().addShutdownHook(shutdownHook);
/* Waiting some time - otherwise pcap may not discover the new interface */ /* Waiting some time - otherwise pcap may not discover the new interface */
Thread.sleep(250); Thread.sleep(250);
@ -622,7 +625,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
logger.fatal("Error when creating tap0: " + e.getMessage()); logger.fatal("Error when creating tap0: " + e.getMessage());
logger.fatal("Try using an already existing network interface"); logger.fatal("Try using an already existing network interface");
} }
/* Hide progress bar */ /* Hide progress bar */
if (GUI.isVisualized()) { if (GUI.isVisualized()) {
new RunnableInEDT<Boolean>() { new RunnableInEDT<Boolean>() {
@ -1007,7 +1010,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
} }
deleteTunInterface(); deleteTunInterface();
if (shutdownHook != null) { if (shutdownHook != null) {
Runtime.getRuntime().removeShutdownHook(shutdownHook); Runtime.getRuntime().removeShutdownHook(shutdownHook);
shutdownHook = null; shutdownHook = null;

View file

@ -2031,30 +2031,54 @@ public class GUI extends Observable {
menuItem.putClientProperty("class", motePluginClass); menuItem.putClientProperty("class", motePluginClass);
menuItem.putClientProperty("mote", mote); menuItem.putClientProperty("mote", mote);
/* Check if mote plugin depends on any particular type of mote */ /* Check mote plugin requirements */
boolean enableMenuItem = true; boolean enableMenuItem = true;
if (motePluginClass.getAnnotation(SupportedArguments.class) != null) { if (motePluginClass.getAnnotation(SupportedArguments.class) != null) {
enableMenuItem = false; /* Check mote interfaces */
Class<? extends Mote>[] motes = motePluginClass.getAnnotation(SupportedArguments.class).motes(); boolean moteInterfacesOK = true;
StringBuilder sb = new StringBuilder(); Class<? extends MoteInterface>[] moteInterfaces = motePluginClass.getAnnotation(SupportedArguments.class).moteInterfaces();
sb.append( StringBuilder moteTypeInterfacesError = new StringBuilder();
"<html><pre>This plugin:\n" + moteTypeInterfacesError.append(
motePluginClass.getName() + "The plugin:\n" +
"\ndoes not support motes of type:\n" + getDescriptionOf(motePluginClass) +
mote.getClass().getName() + "\nrequires the following mote interfaces:\n"
"\n\nIt only supports motes of types:\n"
); );
for (Class<? extends Object> o: motes) { for (Class<? extends MoteInterface> requiredMoteInterface: moteInterfaces) {
sb.append(o.getName() + "\n"); moteTypeInterfacesError.append(getDescriptionOf(requiredMoteInterface) + "\n");
if (o.isAssignableFrom(mote.getClass())) { if (mote.getInterfaces().getInterfaceOfType(requiredMoteInterface) == null) {
enableMenuItem = true; moteInterfacesOK = false;
break;
} }
} }
sb.append("</html>");
if (!enableMenuItem) { /* Check mote type */
menuItem.setToolTipText(sb.toString()); boolean moteTypeOK = false;
Class<? extends Mote>[] motes = motePluginClass.getAnnotation(SupportedArguments.class).motes();
StringBuilder moteTypeError = new StringBuilder();
moteTypeError.append(
"The plugin:\n" +
getDescriptionOf(motePluginClass) +
"\ndoes not support motes of type:\n" +
getDescriptionOf(mote) +
"\n\nIt only supports motes of types:\n"
);
for (Class<? extends Mote> supportedMote: motes) {
moteTypeError.append(getDescriptionOf(supportedMote) + "\n");
if (supportedMote.isAssignableFrom(mote.getClass())) {
moteTypeOK = true;
}
} }
if (!moteInterfacesOK) {
menuItem.setToolTipText(
"<html><pre>" + moteTypeInterfacesError + "</html>"
);
}
if (!moteTypeOK) {
menuItem.setToolTipText(
"<html><pre>" + moteTypeError + "</html>"
);
}
enableMenuItem = moteInterfacesOK && moteTypeOK;
} }
menuItem.setEnabled(enableMenuItem); menuItem.setEnabled(enableMenuItem);

View file

@ -61,4 +61,9 @@ public @interface SupportedArguments {
* @return List of accepted radio medium classes. * @return List of accepted radio medium classes.
*/ */
Class<? extends RadioMedium>[] radioMediums() default { RadioMedium.class }; Class<? extends RadioMedium>[] radioMediums() default { RadioMedium.class };
/**
* @return List of required mote interfaces.
*/
Class<? extends MoteInterface>[] moteInterfaces() default { MoteInterface.class };
} }