Package net.sf.robocode.host

Source Code of net.sf.robocode.host.JavaHost

/**
* Copyright (c) 2001-2014 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*/
package net.sf.robocode.host;


import net.sf.robocode.host.security.RobotClassLoader;
import net.sf.robocode.host.proxies.*;
import net.sf.robocode.peer.IRobotStatics;
import net.sf.robocode.repository.IRobotItem;
import net.sf.robocode.repository.RobotType;
import static net.sf.robocode.io.Logger.logError;
import net.sf.robocode.io.Logger;
import net.sf.robocode.peer.IRobotPeer;
import net.sf.robocode.security.HiddenAccess;
import robocode.Droid;
import robocode.Robot;
import robocode.BorderSentry;
import robocode.control.RobotSpecification;
import robocode.robotinterfaces.*;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.*;
import java.security.AccessControlException;
import java.lang.reflect.Method;


/**
* @author Pavel Savara (original)
*/
public class JavaHost implements IHost {
  public IRobotClassLoader createLoader(IRobotItem robotItem) {
    return new RobotClassLoader(robotItem.getClassPathURL(), robotItem.getFullClassName());
  }

  public IHostingRobotProxy createRobotProxy(IHostManager hostManager, RobotSpecification robotSpecification, IRobotStatics statics, IRobotPeer peer) {
    IHostingRobotProxy robotProxy;
    final IRobotItem specification = (IRobotItem) HiddenAccess.getFileSpecification(robotSpecification);

    if (specification.isTeamRobot()) {
      robotProxy = new TeamRobotProxy(specification, hostManager, peer, (RobotStatics) statics);
    } else if (specification.isAdvancedRobot()) {
      robotProxy = new AdvancedRobotProxy(specification, hostManager, peer, (RobotStatics) statics);
    } else if (specification.isStandardRobot()) {
      robotProxy = new StandardRobotProxy(specification, hostManager, peer, (RobotStatics) statics);
    } else if (specification.isJuniorRobot()) {
      robotProxy = new JuniorRobotProxy(specification, hostManager, peer, (RobotStatics) statics);
    } else {
      throw new AccessControlException("Unknown robot type");
    }
    return robotProxy;
  }

  public String[] getReferencedClasses(IRobotItem robotItem) {
    IRobotClassLoader loader = null;

    try {
      loader = createLoader(robotItem);
      loader.loadRobotMainClass(true);
      return loader.getReferencedClasses();

    } catch (ClassNotFoundException e) {
      Logger.logError(e);
      return new String[0];
    } finally {
      if (loader != null) {
        loader.cleanup();
      }
    }
  }

  public RobotType getRobotType(IRobotItem robotItem, boolean resolve, boolean message) {
    IRobotClassLoader loader = null;

    try {
      loader = createLoader(robotItem);
      Class<?> robotClass = loader.loadRobotMainClass(resolve);

      if (robotClass == null || java.lang.reflect.Modifier.isAbstract(robotClass.getModifiers())) {
        // this class is not robot
        return RobotType.INVALID;
      }
      return checkInterfaces(robotClass, robotItem);

    } catch (Throwable t) {
      if (message) {
        logError("Got an error with " + robotItem.getFullClassName() + ": " + t); // just message here
        if (t.getMessage() != null && t.getMessage().contains("Bad version number in .class file")) {
          logError("Maybe you run robocode with Java 1.5 and robot was compiled for later Java version ?");
        }
      }
      return RobotType.INVALID;
    } finally {
      if (loader != null) {
        loader.cleanup();
      }
    }
  }

  private RobotType checkInterfaces(Class<?> robotClass, IRobotItem robotItem) {
    boolean isJuniorRobot = false;
    boolean isStandardRobot = false;
    boolean isInteractiveRobot = false;
    boolean isPaintRobot = false;
    boolean isAdvancedRobot = false;
    boolean isTeamRobot = false;
    boolean isDroid = false;
    boolean isSentryRobot = false;

    if (IAdvancedRobot.class.isAssignableFrom(robotClass)) { // Note: must be checked first
      isAdvancedRobot = true;
    }
    if (Robot.class.isAssignableFrom(robotClass) && !isAdvancedRobot) {
      isStandardRobot = true;
    }
    if (IJuniorRobot.class.isAssignableFrom(robotClass)) { // Note: Must be checked before checking for standard robot
      isJuniorRobot = true;
      if (isAdvancedRobot) {
        throw new AccessControlException(
            robotItem.getFullClassName() + ": Junior robot should not implement IAdvancedRobot interface.");
      }
    }
    if (IBasicRobot.class.isAssignableFrom(robotClass)) {
      if (!(isAdvancedRobot || isJuniorRobot)) {
        isStandardRobot = true;
      }
    }
    if (ITeamRobot.class.isAssignableFrom(robotClass)) {
      isTeamRobot = true;
    }
    if (Droid.class.isAssignableFrom(robotClass)) {
      isDroid = true;
    }
    if (BorderSentry.class.isAssignableFrom(robotClass)) {
      isSentryRobot = true;
    }

    if (IInteractiveRobot.class.isAssignableFrom(robotClass)) {
      // in this case we make sure that robot don't waste time
      if (checkMethodOverride(robotClass, Robot.class, "getInteractiveEventListener")
          || checkMethodOverride(robotClass, Robot.class, "onKeyPressed", KeyEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onKeyReleased", KeyEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onKeyTyped", KeyEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseClicked", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseEntered", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseExited", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMousePressed", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseReleased", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseMoved", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseDragged", MouseEvent.class)
          || checkMethodOverride(robotClass, Robot.class, "onMouseWheelMoved", MouseWheelEvent.class)
          ) {
        isInteractiveRobot = true;
      }
    }

    if (IPaintRobot.class.isAssignableFrom(robotClass)) {
      if (checkMethodOverride(robotClass, Robot.class, "getPaintEventListener")
          || checkMethodOverride(robotClass, Robot.class, "onPaint", Graphics2D.class)
          ) {
        isPaintRobot = true;
      }
    }

    return new RobotType(isJuniorRobot, isStandardRobot, isInteractiveRobot, isPaintRobot, isAdvancedRobot,
        isTeamRobot, isDroid, isSentryRobot);
  }

  private boolean checkMethodOverride(Class<?> robotClass, Class<?> knownBase, String name, Class<?>... parameterTypes) {
    if (knownBase.isAssignableFrom(robotClass)) {
      final Method getInteractiveEventListener;

      try {
        getInteractiveEventListener = robotClass.getMethod(name, parameterTypes);
      } catch (NoSuchMethodException e) {
        return false;
      }
      if (getInteractiveEventListener.getDeclaringClass().equals(knownBase)) {
        return false;
      }
    }
    return true;
  }
 
}
TOP

Related Classes of net.sf.robocode.host.JavaHost

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.