- *
+ *
* @see edu.csus.ecs.pc2.Starter
* @author pc2@ecs.csus.edu
* @version $Id$
@@ -78,50 +78,99 @@ public interface IInternalController {
/**
* Submit a Judge Run to the server.
- *
+ *
* @param problem the {@link Problem} for which the Submission applies
* @param language the {@link Language} used in the Submission
* @param mainFileName the name of the file containing the main program source code
* @param otherFiles an array of {@link SerializedFile}s containing additional source files being submitted with the Run
- *
+ *
* @throws Exception if an error occurs while attempting to send the Run to the Server
*/
void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles) throws Exception;
/**
* Submit a Judge Run to the server.
- *
+ *
* @param problem the {@link Problem} for which the Submission applies
* @param language the {@link Language} used in the Submission
* @param mainFileName the name of the file containing the main program source code
* @param otherFiles an array of {@link SerializedFile}s containing additional source files being submitted with the Run
- * @param overrideSubmissionTimeMS a value which, if non-zero, is to be used as the submission time of the Judge Run;
+ * @param overrideStopOnFailure if true, then do not stop judging on first failure. if false, use the setting for the problem
+ *
+ * @throws Exception if an error occurs while attempting to send the Run to the Server
+ */
+ void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles, boolean overrideStopOnFailure) throws Exception;
+
+ /**
+ * Submit a Judge Run to the server.
+ *
+ * @param problem the {@link Problem} for which the Submission applies
+ * @param language the {@link Language} used in the Submission
+ * @param mainFileName the name of the file containing the main program source code
+ * @param otherFiles an array of {@link SerializedFile}s containing additional source files being submitted with the Run
+ * @param overrideSubmissionTimeMS a value which, if non-zero, is to be used as the submission time of the Judge Run;
* only has effect when Contest Information "CCS Test Mode" is true
* @param overrideRunId a value which, if non-zero, is to be used as the RunId for the submission instead of any
* internally-assigned RunId; only has effect when Contest Information "CCS Test Mode" is true
- *
+ *
* @throws Exception if an error occurs while attempting to send the Run to the Server
*/
- void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
+ void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
long overrideSubmissionTimeMS, long overrideRunId) throws Exception;
/**
* Submit a Judge Run to the server.
- *
+ *
+ * @param problem the {@link Problem} for which the Submission applies
+ * @param language the {@link Language} used in the Submission
+ * @param mainFileName the name of the file containing the main program source code
+ * @param otherFiles an array of {@link SerializedFile}s containing additional source files being submitted with the Run
+ * @param overrideSubmissionTimeMS a value which, if non-zero, is to be used as the submission time of the Judge Run;
+ * only has effect when Contest Information "CCS Test Mode" is true
+ * @param overrideRunId a value which, if non-zero, is to be used as the RunId for the submission instead of any
+ * internally-assigned RunId; only has effect when Contest Information "CCS Test Mode" is true
+ * @param overrideStopOnFailure if true, then do not stop judging on first failure. if false, use the setting for the problem
+ *
+ * @throws Exception if an error occurs while attempting to send the Run to the Server
+ */
+ void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception;
+
+ /**
+ * Submit a Judge Run to the server.
+ *
* @param problem the {@link Problem} for which the Submission applies
* @param language the {@link Language} used in the Submission
* @param mainFile a {@link SerializedFile} containing the main program source code
* @param otherFiles an array of {@link SerializedFile}s containing additional source files being submitted with the Run
- * @param overrideSubmissionTimeMS a value which, if non-zero, is to be used as the submission time of the Judge Run;
+ * @param overrideSubmissionTimeMS a value which, if non-zero, is to be used as the submission time of the Judge Run;
* only has effect when Contest Information "CCS Test Mode" is true
* @param overrideRunId a value which, if non-zero, is to be used as the RunId for the submission instead of any
* internally-assigned RunId; only has effect when Contest Information "CCS Test Mode" is true
- *
+ *
* @throws Exception if an error occurs while attempting to send the Run to the Server
*/
- void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
+ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
long overrideSubmissionTimeMS, long overrideRunId) throws Exception;
+ /**
+ * Submit a Judge Run to the server.
+ *
+ * @param problem the {@link Problem} for which the Submission applies
+ * @param language the {@link Language} used in the Submission
+ * @param mainFile a {@link SerializedFile} containing the main program source code
+ * @param otherFiles an array of {@link SerializedFile}s containing additional source files being submitted with the Run
+ * @param overrideSubmissionTimeMS a value which, if non-zero, is to be used as the submission time of the Judge Run;
+ * only has effect when Contest Information "CCS Test Mode" is true
+ * @param overrideRunId a value which, if non-zero, is to be used as the RunId for the submission instead of any
+ * internally-assigned RunId; only has effect when Contest Information "CCS Test Mode" is true
+ * @param overrideStopOnFailure if true, then do not stop judging on first failure. if false, use the setting for the problem
+ *
+ * @throws Exception if an error occurs while attempting to send the Run to the Server
+ */
+ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception;
+
void setSiteNumber(int i);
@@ -129,21 +178,21 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send to client (or server), if necessary forward to another server.
- *
+ *
* @param packet
*/
void sendToClient(Packet packet);
/**
* Send to all logged in servers.
- *
+ *
* @param packet
*/
void sendToServers(Packet packet);
/**
* Send to a remote server.
- *
+ *
* @param siteNumber
* @param packet
*/
@@ -151,49 +200,49 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send to all judges on local site.
- *
+ *
* @param packet
*/
void sendToJudges(Packet packet);
/**
* Send to all administrators on local site.
- *
+ *
* @param packet
*/
void sendToAdministrators(Packet packet);
/**
* Send to all scoreboard on local site.
- *
+ *
* @param packet
*/
void sendToScoreboards(Packet packet);
/**
* Send to all teams on local site.
- *
+ *
* @param packet
*/
void sendToTeams(Packet packet);
/**
* Send to all spectator/API clients
- *
+ *
* @param packet
*/
void sendToSpectators(Packet packet);
/**
* Start InternalController with command line arguments.
- *
+ *
* @param stringArray
*/
void start(String[] stringArray);
/**
* Login to server, start MainUI.
- *
+ *
* @param loginName
* @param password
*/
@@ -201,7 +250,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Login to server, wait for login
- *
+ *
* @param loginName
* @param password
* @return
@@ -211,23 +260,23 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Logoff a client.
- *
+ *
* Logs this client off, or sends request to log client off.
- *
+ *
* @param clientId
*/
void logoffUser(ClientId clientId);
/**
* Start the UI for the input client.
- *
+ *
* @param clientId
*/
void startMainUI(ClientId clientId);
/**
* Request a run from the server.
- *
+ *
* @param run
* - the run to retrieve
* @param readOnly
@@ -239,14 +288,14 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Request to checkout a judged run, to rejudge the run.
- *
+ *
* @param theRun
*/
void checkOutRejudgeRun(Run theRun);
/**
* Submit judgement from run to judge.
- *
+ *
* @param run
* @param judgementRecord
*/
@@ -254,7 +303,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Cancel selected run.
- *
+ *
* @param run
*/
void cancelRun(Run run);
@@ -262,21 +311,21 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
void addNewSite(Site site);
void addNewProblem(Problem problem, ProblemDataFiles problemDataFiles);
-
+
void addNewProblem(Problem [] problem, ProblemDataFiles [] problemDataFiles);
void addProblem(Problem problem);
/**
* Add a new Judgement.
- *
+ *
* @param judgement
*/
void addNewJudgement(Judgement judgement);
/**
* Replace judgement list with new judgement list.
- *
+ *
* @param judgementList
*/
void setJudgementList(Judgement[] judgementList);
@@ -286,13 +335,13 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
void updateRun(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles);
void sendServerLoginRequest(int inSiteNumber) throws Exception;
-
+
/**
- * Is this controller using GUI.
+ * Is this controller using GUI.
* @return true if using GUI, false if using text only
*/
boolean isUsingGUI();
-
+
/**
* Is this controller suppressing display of Connections grids.
* @return true if GUIs using this controller should suppress display of Connections grids.
@@ -314,10 +363,10 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
void updateProblem(Problem problem);
void updateProblem(Problem problem, ProblemDataFiles problemDataFiles);
-
+
/**
* Send packet to local server to switch profile.
- *
+ *
* @param currentProfile profile to switch from
* @param switchToProfile profile to switch to
*/
@@ -325,7 +374,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Clone profile (and potentially switch to the new profile).
- *
+ *
* @param profile current profile
* @param settings set of changes to clone
* @param switchNow true means switch to new profile now
@@ -336,14 +385,14 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Get contest log.
- *
+ *
* @return
*/
Log getLog();
/**
* Send message to server that needs attention/resolution.
- *
+ *
* @param event
* optional event
* @param message
@@ -355,7 +404,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Generate new accounts on a server.
- *
+ *
* @param clientTypeName
* @param siteNumber
* site number to generate accounts.
@@ -367,7 +416,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Generate new accounts for current site.
- *
+ *
* @param clientTypeName
* @param count
* @param startNumber
@@ -377,7 +426,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Submit a clarification.
- *
+ *
* @param problem
* @param question
*/
@@ -385,7 +434,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Request clarification to answer.
- *
+ *
* @param clarification
* @param readOnly
*/
@@ -393,23 +442,23 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Cancel requested clarification.
- *
+ *
* @param clarification
*/
void cancelClarification(Clarification clarification);
/**
* Answer a clarification.
- *
+ *
* @param clarification
*/
void submitClarificationAnswer(Clarification clarification);
/**
* Force connection off.
- *
+ *
* Remove local connection, or send to server to remove connection.
- *
+ *
* @param connectionHandlerID
*/
void forceConnectionDrop(ConnectionHandlerID connectionHandlerID);
@@ -440,13 +489,13 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
void addNewLanguage(Language language);
void addNewLanguages(Language[] languages);
-
+
void updateLanguage(Language language);
void updateLanguages(Language[] languages);
void addNewGroup(Group group);
-
+
void addNewGroups(Group[] groups);
void updateGroup(Group group);
@@ -467,14 +516,14 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Load contest settings from disk and initialize InternalContest.
- * @param contest
- *
+ * @param contest
+ *
* @throws FileSecurityException
* @throws ClassNotFoundException
* @throws IOException
*/
void initializeServer(IInternalContest contest) throws IOException, ClassNotFoundException, FileSecurityException;
-
+
void initializeStorage (IStorage storage);
void addNewClientSettings(ClientSettings newClientSettings);
@@ -483,7 +532,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Get Security Level.
- *
+ *
* @return current security level
*/
int getSecurityLevel();
@@ -492,38 +541,38 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send packet to server.
- *
+ *
* Also can be used to send a packet from this
* server to this server as a consistent interface
* to the server (esp from classes like ServerView)
- *
+ *
* @param packet
*/
void sendToLocalServer(Packet packet);
/**
* Get name of host contacted.
- *
+ *
* On server, gets name of host where listener listens.
- *
+ *
* @return name of host server
*/
String getHostContacted();
/**
* Get port number of host contacted.
- *
+ *
* On server, gets port where listening.
- *
+ *
* @return
*/
int getPortContacted();
/**
* Gets a run from the server.
- *
+ *
* Does not checkout run, simply requests the run info. Security note: only a non-team client can request runs.
- *
+ *
* @param run
* @throws FileSecurityException
* @throws ClassNotFoundException
@@ -533,21 +582,21 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send a compiling message to the Server.
- *
+ *
* @param run
*/
void sendCompilingMessage(Run run);
/**
* Send a executing message to the Server.
- *
+ *
* @param run
*/
void sendExecutingMessage(Run run);
/**
* Send a validating message to the Server.
- *
+ *
* @param run
*/
void sendValidatingMessage(Run run);
@@ -558,21 +607,21 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Reset contest.
- *
+ *
* @param clientResettingContest
*/
void resetContest(ClientId clientResettingContest, boolean eraseProblems, boolean eraseLanguages);
/**
* Update existing judgement.
- *
+ *
* @param newJudgement
*/
void updateJudgement(Judgement newJudgement);
/**
* Update current Profile information.
- *
+ *
* @param profile
*/
void updateProfile(Profile profile);
@@ -581,21 +630,21 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Register a plugin.
- *
+ *
* @param plugin
*/
void register(UIPlugin plugin);
-
+
/**
* Get list of plugins.
- *
+ *
* @return
*/
UIPlugin[] getPluginList();
/**
* Update/replace contest and controller for all registered UI Plugins.
- *
+ *
* @param inContest
* @param inController
*/
@@ -604,16 +653,16 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
void addPacketListener(IPacketListener packetListener);
void removePacketListener(IPacketListener packetListener);
-
+
void incomingPacket (Packet packet);
-
+
void outgoingPacket (Packet packet);
-
+
/**
* Start Log Window.
- *
+ *
* Only starts if {@link #isUsingGUI()} returns true;
- *
+ *
* @param contest
*/
ILogWindow startLogWindow(IInternalContest contest);
@@ -623,7 +672,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
* @param showWindow set LogWindow visible.
*/
void showLogWindow(boolean showWindow);
-
+
boolean isLogWindowVisible();
/**
@@ -635,10 +684,10 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send Sync Submissions packet.
- *
+ *
* Send a packet to tell all servers to sync up their
* submission and other local data with all servers.
- *
+ *
* @param profile
*/
void syncProfileSubmissions(Profile profile);
@@ -650,30 +699,30 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send shutdown server packet.
- *
+ *
* @param siteNumber site number to shut down.
*/
void sendShutdownSite(int siteNumber);
/**
* Shutdown this server.
- *
+ *
* @param requestor
*/
void shutdownServer(ClientId requestor);
/**
* Shutdown all remote servers.
- *
+ *
* Sends packet to all servers to shutdown.
- *
+ *
* @param requestor
*/
void shutdownRemoteServers(ClientId requestor);
/**
* Shutdown remove server (Server).
- *
+ *
* @param requestor
* @param siteNumber
*/
@@ -681,17 +730,17 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Update Finalize data
- * @param data
+ * @param data
*/
void updateFinalizeData(FinalizeData data);
-
+
/**
* Using GUI?.
- *
+ *
* @param usingGUI true means show GUI message, false means do not show GUI messages.
*/
void setUsingGUI(boolean usingGUI);
-
+
void updateCategories(Category[] categories);
void updateCategory(Category newCategory);
@@ -699,7 +748,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
void addNewCategory(Category newCategory);
void startPlayback(PlaybackInfo playbackInfo);
-
+
/**
* Send submitted run to Run Submission Interface.
* @param run
@@ -714,10 +763,10 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Send to all logged in Judges, Admins, Boards and optionally to other sites.
- *
- * This sends all sorts of packets to all logged in clients (except teams).
+ *
+ * This sends all sorts of packets to all logged in clients (except teams).
* Typically sendToServers is set if this is the originating site, if not done then a nasty circular path will occur.
- *
+ *
* @param packet
* @param sendToServers if true then send to other server.
*/
@@ -725,16 +774,16 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Override the connection manager.
- *
+ *
* @see ITransportManager
* @param connectionManager
*/
void setConnectionManager(ITransportManager connectionManager);
-
+
/**
* Creates an {@link AutoStarter} if none exists, and then instructs the AutoStarter to update its Scheduled Start Task to correspond to the Scheduled Start Time information in the
* {@link ContestInformation} object in the received {@link IInternalContest}.
- *
+ *
* @param aContest
* - the Contest (Model) containing the Scheduled Start Time information
* @param aController
@@ -750,7 +799,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Submit a run to the server for a different client.
- *
+ *
* @param submitter - override submitter, if used the logged in client must have Permission.Type.SHADOW_PROXY_TEAM selected.
* @param problem
* @param language
@@ -763,7 +812,7 @@ void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile,
/**
* Submit a run to the server for a different client with entry_point
- *
+ *
* @param submitter - override submitter, if used the logged in client must have Permission.Type.SHADOW_PROXY_TEAM selected.
* @param problem
* @param language
diff --git a/src/edu/csus/ecs/pc2/core/InternalController.java b/src/edu/csus/ecs/pc2/core/InternalController.java
index 41ff0d853..c4b46c823 100644
--- a/src/edu/csus/ecs/pc2/core/InternalController.java
+++ b/src/edu/csus/ecs/pc2/core/InternalController.java
@@ -1,4 +1,4 @@
-// Copyright (C) 1989-2022 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
+// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
package edu.csus.ecs.pc2.core;
import java.io.File;
@@ -95,7 +95,7 @@
/**
* Implementation of InternalContest InternalController.
- *
+ *
* Run Flow, submit run.
*
- *
+ *
* @author pc2@ecs.csus.edu
*/
public class InternalController implements IInternalController, ITwoToOne, IBtoA {
-
+
private boolean haltOnFatalError = true;
/**
@@ -161,27 +161,27 @@ public class InternalController implements IInternalController, ITwoToOne, IBtoA
private Log log;
private Ini ini = new Ini();
-
+
private boolean suppressConnectionsPaneDisplay = false;
private boolean suppressLoginsPaneDisplay = false;
/**
* The port that the server will listen on.
- *
+ *
* This is the port where all clients will contact this server/site.
*/
private static int port;
/**
* The host/IP for a client or server to contact.
- *
+ *
* Both client and server who are connecting a server use this host as the host to contact.
*/
private String remoteHostName = "127.0.0.1";
/**
* The port for a client or server to login to/contact.
- *
+ *
* Both client and server who are connecting a server use this port as the portt to contact.
*/
private int remoteHostPort;
@@ -249,7 +249,7 @@ public class InternalController implements IInternalController, ITwoToOne, IBtoA
private String loginClassName = LOGIN_UI_GUI_CLASSNAME;
private String startupDialogClassName = STARTUP_DIALOG_GUI_CLASS;
-
+
private String countdownClassName = COUNTDOWN_UI_CLASSNAME;
private IStartupContestDialog startDialog;
@@ -261,7 +261,7 @@ public class InternalController implements IInternalController, ITwoToOne, IBtoA
/**
* Flag indicating whether Roman Numeral shutdown is done.
- *
+ *
* If set to false, then will trigger/send the event
*/
private boolean clientAutoShutdown = true;
@@ -276,20 +276,20 @@ public class InternalController implements IInternalController, ITwoToOne, IBtoA
private ILogWindow logWindow = null;
private RunSubmitterInterfaceManager runSubmitterInterfaceManager = new RunSubmitterInterfaceManager();
-
+
/**
* The object used to control contest auto-starting.
*/
private AutoStarter autoStarter;
-
+
private AutoStopContestClockThread autoStopContestClockThread = null;
-
+
/**
* Packets which should be sent to multiple instances of logins (for example, a "RUN_SUBMSSION_CONFIRMATION"
* packet should be sent to every instance of a given team client login when multiple team logins are allowed).
* Listing an element of {@link PacketType.Type} in this EnumSet causes packets of that type to be duplicated
* and sent to every login instance for the destination client specified in the packet.
- *
+ *
* @author John Clevenger, PC2 Development Team (pc2@ecs.csus.edu)
*
*/
@@ -297,8 +297,8 @@ public class InternalController implements IInternalController, ITwoToOne, IBtoA
PacketType.Type.RUN_SUBMISSION_CONFIRM,
PacketType.Type.RUN_JUDGEMENT,
// PacketType.Type.RUN_JUDGEMENT_UPDATE, //this seems to only be sent to judges/admins/boards to update run status, but not teams
- PacketType.Type.CLARIFICATION_SUBMISSION_CONFIRM,
- PacketType.Type.CLARIFICATION_UPDATE,
+ PacketType.Type.CLARIFICATION_SUBMISSION_CONFIRM,
+ PacketType.Type.CLARIFICATION_UPDATE,
PacketType.Type.CLARIFICATION_ANSWER,
PacketType.Type.CLARIFICATION_ANSWER_UPDATE
);
@@ -308,6 +308,7 @@ public InternalController(IInternalContest contest) {
setContest(contest);
}
+ @Override
public void sendToLocalServer(Packet packet) {
if (isThisServer(packet.getSourceId()) && isServer()) {
@@ -357,10 +358,11 @@ private void sendToClient(ConnectionHandlerID connectionHandlerID, Packet packet
}
/**
- *
+ *
* @param inSiteNumber site number for client to send to
* @param packet info to send
*/
+ @Override
public void sendToRemoteServer(int inSiteNumber, Packet packet) {
if (packet.getSourceId() != null && (packet.getOriginalSourceId().getSiteNumber() == inSiteNumber)) {
@@ -369,9 +371,9 @@ public void sendToRemoteServer(int inSiteNumber, Packet packet) {
}
Site remoteSite = lookupRemoteServer(inSiteNumber);
int siteNumber = remoteSite.getSiteNumber();
-
+
ClientId clientId = new ClientId(siteNumber, Type.SERVER, 0);
-
+
ConnectionHandlerID connectionHandlerID = getConnectionHandleID(clientId);
info("sendToRemoteServer " + clientId + " at "+siteNumber+" " + packet + " " + connectionHandlerID);
@@ -397,7 +399,7 @@ public void sendToRemoteServer(int inSiteNumber, Packet packet) {
}
protected ConnectionHandlerID getConnectionHandleID(ClientId clientId) {
-
+
ClientId[] ids = contest.getLocalLoggedInClients(clientId.getClientType());
for (ClientId id : ids) {
if (id.equals(clientId)){
@@ -407,12 +409,13 @@ protected ConnectionHandlerID getConnectionHandleID(ClientId clientId) {
return null;
}
+ @Override
public void sendToClient(Packet packet) {
info("sendToClient b4 to " + packet.getDestinationId() + " " + packet);
ClientId toClientId = packet.getDestinationId();
- //this method should never be called with a packet containing a destination ClientId containing a null ConnectionHandlerID;
+ //this method should never be called with a packet containing a destination ClientId containing a null ConnectionHandlerID;
// however, the addition of "multiple login" support may have left some place where this is inadvertently true.
//The following is an effort to catch/identify such situations.
if (toClientId.getConnectionHandlerID()==null) {
@@ -423,14 +426,14 @@ public void sendToClient(Packet packet) {
if (isThisSite(toClientId.getSiteNumber())) {
if (contest.isLocalLoggedIn(toClientId)) {
-
+
ConnectionHandlerID connectionHandlerID = toClientId.getConnectionHandlerID();
info("sendToClient " + packet.getDestinationId() + " @ " + connectionHandlerID);
sendToClient(connectionHandlerID, packet);
-
+
//certain packets should also be sent to any other logged in clients (e.g. logins for the same team)
sendToDuplicateClients(packet);
-
+
} else {
try {
packetArchiver.writeNextPacket(packet);
@@ -461,37 +464,37 @@ public void sendToClient(Packet packet) {
info("sendToClient af to " + packet.getDestinationId() + " " + packet);
}
-
+
/**
* Examines the specified packet to determine if there duplicate client logins to which the packet should be sent
* (for example, in the case where multiple team clients for the same team have been allowed to login); sends the
* specified packet to any duplicate login clients.
- *
+ *
* @param packet the packet to be sent to any duplicate login clients.
*/
private void sendToDuplicateClients(Packet packet) {
//determine what client the packet was initially sent to (it is assumed that the caller took care of the initial send)
ClientId toClientId = packet.getDestinationId();
-
+
//see if the packet is one of the types that should be duplicated (sent to all logins for the client)
if (DuplicatePacketTypes.contains(packet.getType()) ) {
-
+
//see if the destination for the packet is a team
if (toClientId.getClientType()==ClientType.Type.TEAM) {
-
+
//get a list of all logged-in team clients
ClientId[] clientList = contest.getAllLoggedInClients(ClientType.Type.TEAM);
-
+
//check every logged-in team client
for (ClientId clientId : clientList) {
-
+
//see if the current logged-in team client is the same team as the original intended destination
if (clientId.equals(toClientId)) {
-
+
//same team; make sure it's a DIFFERENT connection (we assume the caller already sent the packet to the original dest)
if (!clientId.getConnectionHandlerID().equals(toClientId.getConnectionHandlerID())) {
-
+
//it's a different connection for the same team; send a duplicate of the packet
ConnectionHandlerID connectionHandlerID = clientId.getConnectionHandlerID();
info("sendToClient " + packet.getDestinationId() + " @ " + connectionHandlerID);
@@ -527,15 +530,26 @@ protected void sendToServersAndAdmins(Packet packet) {
/**
* {@inheritDoc}
- * Calling this method is equivalent to calling
+ * Calling this method is equivalent to calling
* {@link #submitJudgeRun(Problem, Language, String, SerializedFile[], long, long)}
* with zeroes as the last two parameters.
*/
- @Override
+ @Override
public void submitJudgeRun(Problem problem, Language language, String filename, SerializedFile[] otherFiles) throws Exception {
submitJudgeRun(problem, language, filename, otherFiles, 0, 0);
}
-
+
+ /**
+ * {@inheritDoc}
+ * Calling this method is equivalent to calling
+ * {@link #submitJudgeRun(Problem, Language, String, SerializedFile[], long, long, boolean)}
+ * with zeroes as the last two parameters.
+ */
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, String filename, SerializedFile[] otherFiles, boolean overrideStopOnFailure) throws Exception {
+ submitJudgeRun(problem, language, filename, otherFiles, 0, 0, overrideStopOnFailure);
+ }
+
/**
* {@inheritDoc}
* Calling this method is equivalent to calling
@@ -543,29 +557,58 @@ public void submitJudgeRun(Problem problem, Language language, String filename,
* with a {@link SerializedFile} containing the main source code file contents.
*/
@Override
- public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
+ public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception {
+
+ SerializedFile serializedMainFile = new SerializedFile(mainFileName);
+
+ submitJudgeRun(problem, language, serializedMainFile, otherFiles, overrideSubmissionTimeMS, overrideRunId, overrideStopOnFailure);
+ }
+
+ /**
+ * {@inheritDoc}
+ * Calling this method is equivalent to calling
+ * {@link #submitJudgeRun(Problem, Language, SerializedFile, SerializedFile[], long, long, false)}
+ * with a {@link SerializedFile} containing the main source code file contents.
+ */
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
long overrideSubmissionTimeMS, long overrideRunId) throws Exception {
SerializedFile serializedMainFile = new SerializedFile(mainFileName);
- submitJudgeRun(problem, language, serializedMainFile, otherFiles, overrideSubmissionTimeMS, overrideRunId);
+ submitJudgeRun(problem, language, serializedMainFile, otherFiles, overrideSubmissionTimeMS, overrideRunId, false);
}
/**
* {@inheritDoc}
+ * Calling this method is equivalent to calling
+ * {@link #submitJudgeRun(Problem, Language, SerializedFile, SerializedFile[], long, long, false)}
+ * with a {@link SerializedFile} containing the main source code file contents.
*/
@Override
- public void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
+ public void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
long overrideSubmissionTimeMS, long overrideRunId) throws Exception {
+ submitJudgeRun(problem, language, mainFile, otherFiles, overrideSubmissionTimeMS, overrideRunId, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception {
+
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Run run = new Run(contest.getClientId(), language, problem);
RunFiles runFiles = new RunFiles(run, mainFile, otherFiles);
- Packet packet = PacketFactory.createSubmittedRun(contest.getClientId(), serverClientId, run, runFiles, overrideSubmissionTimeMS, overrideRunId);
+ Packet packet = PacketFactory.createSubmittedRun(contest.getClientId(), serverClientId, run, runFiles, overrideSubmissionTimeMS, overrideRunId, overrideStopOnFailure);
sendToLocalServer(packet);
}
+ @Override
public void requestChangePassword(String oldPassword, String newPassword) {
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
@@ -576,7 +619,7 @@ public void requestChangePassword(String oldPassword, String newPassword) {
/**
* Return int for input string
- *
+ *
* @param s
* @return zero if error, otherwise returns value.
*/
@@ -590,7 +633,7 @@ private static int getIntegerValue(String s) {
/**
* returns true if .ini file exists and key is present in file.
- *
+ *
* @see IniFile#getValue(String)
* @param key
* @return true if key found and ini file exists.
@@ -605,7 +648,7 @@ private static boolean containsINIKey(String key) {
/**
* Get value from .ini file if it exists.
- *
+ *
* @param key
* @return
*/
@@ -713,15 +756,16 @@ protected String stripChar(String s, char ch) {
/**
* Login to contest server.
- *
+ *
* @param id
* the login name.
* @param password
* the password for the id.
- * @throws SecurityException
+ * @throws SecurityException
* if a login is attempted when the contest is not running or if the login is from a server
* and this is a Client (servers can only log in to other servers)
*/
+ @Override
public void login(String id, String password) {
if (!isStarted) {
@@ -765,13 +809,13 @@ public void login(String id, String password) {
}
info("Contacted using connection id " + remoteServerConnectionHandlerID);
-
+
boolean loggingInSiteRequestsToBeProxy = getBooleanValue(getINIValue(AppConstants.PROXY_ME_SERVER_KEY), false);
-
+
if (parseArguments.isOptPresent(AppConstants.PROXYME_OPTION_STRING)){
loggingInSiteRequestsToBeProxy = true;
}
-
+
sendLoginRequestFromServerToServer(connectionManager, remoteServerConnectionHandlerID, clientId, password, loggingInSiteRequestsToBeProxy, 0);
} else {
@@ -802,12 +846,12 @@ public void login(String id, String password) {
sendLoginRequest(connectionManager, clientId, id, password);
}
}
-
+
/**
* For input string return boolean value.
- *
+ *
* Does a trim and case in-sensitive match on the list: yes, no, true, false
- *
+ *
* @param string true/false string/value
* @param defaultBoolean if matches none in list returns this values
*/
@@ -833,9 +877,9 @@ public boolean getBooleanValue(String string, boolean defaultBoolean) {
/**
* This is a very temporary kludge class.
- *
+ *
* This is used with clientLogin, as a
- *
+ *
* @author pc2@ecs.csus.edu
* @version $Id$
*/
@@ -850,15 +894,17 @@ protected class TemporaryClientUI implements UIPlugin, ILoginListener {
private SecurityException securityException = null;
/**
- *
+ *
*/
private static final long serialVersionUID = 8735788359720905862L;
+ @Override
public void setContestAndController(IInternalContest inContest, IInternalController inController) {
contest = inContest;
controller = inController;
}
+ @Override
public String getPluginTitle() {
return "TemporaryClientUI";
}
@@ -883,25 +929,30 @@ public void setController(IInternalController controller) {
this.controller = controller;
}
+ @Override
public void loginAdded(LoginEvent event) {
// no action
}
+ @Override
public void loginRemoved(LoginEvent event) {
// no action
}
+ @Override
public void loginDenied(LoginEvent event) {
securityException = new SecurityException("Login denied " + event.getMessage());
}
+ @Override
public void loginRefreshAll(LoginEvent event) {
// no action
}
}
+ @Override
public IInternalContest clientLogin(IInternalContest internalContest, String loginName, String password) throws Exception {
if (!isStarted) {
@@ -964,12 +1015,14 @@ public IInternalContest clientLogin(IInternalContest internalContest, String log
}
}
+ @Override
public void initializeStorage(IStorage storage) {
contest.setStorage(storage);
packetArchiver = new PacketArchiver(storage, getBaseProfileDirectoryName("packets"));
}
+ @Override
public void initializeServer(IInternalContest inContest) throws IOException, ClassNotFoundException, FileSecurityException {
if (inContest.getSites().length == 0) {
@@ -1038,7 +1091,7 @@ public void initializeServer(IInternalContest inContest) throws IOException, Cla
inContest.initializeStartupData(inContest.getSiteNumber());
inContest.initializeSubmissions(inContest.getSiteNumber());
-
+
if (inContest.getGeneralProblem() == null) {
inContest.setGeneralProblem(new Problem("General"));
}
@@ -1048,24 +1101,24 @@ public void initializeServer(IInternalContest inContest) throws IOException, Cla
}
info("initialized controller Site " + inContest.getSiteNumber());
-
+
handleCDPLoad(true);
-
+
if (contest.getJudgements().length == 0) {
- // judgements not loaded from yaml, cdp config - load from ./reject.ini
+ // judgements not loaded from yaml, cdp config - load from ./reject.ini
String result = JudgementLoader.loadJudgements(inContest, false, ".");
getLog().info(result);
}
-
+
if (contest.getJudgements().length == 0) {
- // judgements not loaded from cdp, yaml or ./reject.ini
+ // judgements not loaded from cdp, yaml or ./reject.ini
JudgementLoader.loadDefaultJudgements(contest);
getLog().info("Loaded default judgements");
}
-
+
dumpAutoStartInformation(contest.getContestInformation());
-
+
try {
manager.mergeProfiles(inContest);
} catch (Exception e) {
@@ -1106,9 +1159,9 @@ public void initializeServer(IInternalContest inContest) throws IOException, Cla
} catch (Exception e) {
getLog().log(Log.WARNING, "Exception creating evals.log ", e);
}
-
+
updateAutoStartInformation(inContest, this);
-
+
updateAutoStopClockThread();
}
@@ -1139,14 +1192,14 @@ private void insureProfileDirectory(Profile profile) {
/**
* Loads reject.ini file contents into Judgements.
- *
+ *
* If finds reject.ini file, reads file. Adds Yes judgement, then prepends "No - " onto each entry from the reject.ini file and returns true.
- *
+ *
* Reads judge acronyms if present, if file contains a AC judgement then will use that
* text for the Yes judgement.
- *
+ *
* Returns false if cannot read reject.ini file or reject.ini file is empty (perhaps only containing comments).
- *
+ *
* @return true if loaded, false if could not read file.
*/
protected boolean loadedJudgementsFromIni(String filename) {
@@ -1160,17 +1213,17 @@ protected boolean loadedJudgementsFromIni(String filename) {
protected void loadDefaultJudgements() {
String[] judgementNames = { //
- "Yes", //
- "No - Compilation Error", //
- "No - Run-time Error", //
- "No - Time Limit Exceeded", //
- "No - Wrong Answer", //
- "No - Excessive Output", //
- "No - Output Format Error", //
+ "Yes", //
+ "No - Compilation Error", //
+ "No - Run-time Error", //
+ "No - Time Limit Exceeded", //
+ "No - Wrong Answer", //
+ "No - Excessive Output", //
+ "No - Output Format Error", //
"No - Other - Contact Staff" //
};
String [] judgementAcronyms = {
- Judgement.ACRONYM_ACCEPTED, //
+ Judgement.ACRONYM_ACCEPTED, //
Judgement.ACRONYM_COMPILATION_ERROR, //
Judgement.ACRONYM_RUN_TIME_ERROR, //
Judgement.ACRONYM_TIME_LIMIT_EXCEEDED, //
@@ -1179,7 +1232,7 @@ protected void loadDefaultJudgements() {
Judgement.ACRONYM_OUTPUT_FORMAT_ERROR, //
Judgement.ACRONYM_OTHER_CONTACT_STAFF, //
};
-
+
int i = 0;
for (String judgementName : judgementNames) {
Judgement judgement = new Judgement(judgementName, judgementAcronyms[i]);
@@ -1243,11 +1296,11 @@ private Site createFirstSite(int siteNumber, String hostName, int portNumber) {
/**
* Reads .ini file and sets server and port.
- *
+ *
* Sets the server and port for client.
- *
+ *
* @param portString
- *
+ *
*/
private void setClientServerAndPort(String portString) {
@@ -1344,9 +1397,9 @@ private void setServerPort(String portString) {
/**
* Send login request from server to another server.
- *
+ *
* Send login request directly to connectionHandlerId.
- *
+ *
* @param manager
* transmission manager
* @param targetConnectionHandlerID
@@ -1359,8 +1412,8 @@ private void setServerPort(String portString) {
* @param targetSiteNumber the target/destination site number for this login request
*/
private void sendLoginRequestFromServerToServer(ITransportManager manager, ConnectionHandlerID targetConnectionHandlerID, ClientId clientId, String password, boolean proxyMe,
- int targetSiteNumber) {
-
+ int targetSiteNumber) {
+
try {
info("sendLoginRequestFromServerToServer ConId start - sending from " + clientId);
ClientId serverClientId = new ClientId(targetSiteNumber, Type.SERVER, 0);
@@ -1371,8 +1424,8 @@ private void sendLoginRequestFromServerToServer(ITransportManager manager, Conne
} catch (TransportException e) {
info("Exception sendLoginRequestFromServerToServer ", e);
}
-
-
+
+
// info("sendLoginRequestFromServerToServer ConId start - sending from " + clientId + " proxyMe = " + proxyMe);
// ClientId serverClientId = new ClientId(0, Type.SERVER, 0);
// String joeLoginName = password;
@@ -1386,7 +1439,7 @@ private void sendLoginRequestFromServerToServer(ITransportManager manager, Conne
/**
* Send login request to server as a login.
- *
+ *
* @param manager
* @param clientId
* @param password
@@ -1401,9 +1454,10 @@ private void sendLoginRequest(ITransportManager manager, ClientId clientId, Stri
/**
* Server receives Packet from client or server.
- *
+ *
* @see edu.csus.ecs.pc2.core.transport.ITwoToOne#receiveObject(java.io.Serializable, edu.csus.ecs.pc2.core.transport.ConnectionHandlerID)
*/
+ @Override
public void receiveObject(Serializable object, ConnectionHandlerID connectionHandlerID) {
// SOMEDAY SECURITY code check the input connection to insure they are valid connection
@@ -1415,7 +1469,7 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
Packet packet = (Packet) object;
ClientId clientId = packet.getSourceId();
-
+
clientId.setConnectionHandlerID(connectionHandlerID);
info("receiveObject " + packet);
@@ -1439,20 +1493,20 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
}
} else if (packet.getType().equals(PacketType.Type.LOGIN_REQUEST)) {
-
+
if (packetHandler.forwardedToProxy((packet))) {
-
+
// Handled proxy packets (send/receive), no additional action necesary in this method.
return;
}
-
+
String password = PacketFactory.getStringValue(packet, PacketFactory.PASSWORD);
boolean requestProxy = false;
Boolean requestedProxy = PacketFactory.getBooleanValue(packet, PacketFactory.REQUEST_LOGIN_AS_PROXY);
if (requestedProxy != null) {
requestProxy = requestedProxy.booleanValue();
}
-
+
try {
/**
@@ -1462,15 +1516,15 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
packetArchiver.writeNextPacket(packet);
if (clientId.getSiteNumber() == ClientId.UNSET) {
-
+
info("LOGIN_REQUEST packet contains clientId object with site number of " + ClientId.UNSET + "; replacing with my site number (" + contest.getSiteNumber() + ")");
-
+
ConnectionHandlerID connHID = clientId.getConnectionHandlerID();
clientId = new ClientId(contest.getSiteNumber(), clientId.getClientType(), clientId.getClientNumber());
clientId.setConnectionHandlerID(connHID);
}
attemptToLogin(clientId, password, connectionHandlerID);
-
+
if (requestProxy){
if (isServer(packet.getSourceId())){
/**
@@ -1479,7 +1533,7 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
sendSiteUpdateSetProxy (packet.getSourceId(), contest.getSiteNumber());
}
}
-
+
sendLoginSuccess(clientId, connectionHandlerID);
// Send login notification to users.
@@ -1539,16 +1593,16 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
// securityCheck(packet, connectionHandlerID);
processPacket(packet, connectionHandlerID);
} else {
-
+
if (clientId.getClientType().equals(Type.SERVER)) {
// Packet from a server.
if (packet.getType() == PacketType.Type.LOGIN_FAILED) {
-
+
handleServerLoginFailure(packet);
-
+
} else if (packet.getType().equals(PacketType.Type.LOGIN_SUCCESS)) {
-
+
/**
* The current server has successfully logged into a remote server.
*/
@@ -1560,14 +1614,14 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
// Add the other (server we logged into) into our local logged in list.
loginServer(clientId, connectionHandlerID);
-
+
/**
* Since this module is not logged in, this packet should only be a LOGIN_SUCCESS from a server we initially logged into,
- * aka the remoteServer.
+ * aka the remoteServer.
*/
-
+
if (connectionHandlerID.equals(remoteServerConnectionHandlerID)){
-
+
/**
* Only accept/change config data on this site if the login success is from the server that this site connected to initially.
*/
@@ -1575,42 +1629,42 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
// Add data from packet into contest and sync all runs
processPacket(packet, connectionHandlerID);
-
+
} else {
-
+
/**
* This should happen when a server logs into another server that is not its remoeteServer (initial server logged into).
- *
+ *
* This is where the remote site's data is synced on this server.
*/
-
+
info("Updating this server's settings from remote server specific settings from " + clientId + " @ " + connectionHandlerID);
-
+
packetHandler.loadSettingsFromRemoteServer(new ContestLoader(), packet, connectionHandlerID);
-
+
info("Sending this server's settings to remote server " + packet.getSourceId() + " @ " + connectionHandlerID);
// Send settings packet to the server we logged into
sendToClient(packetHandler.createContestSettingsPacket(packet.getSourceId()));
-
+
info("Sending a request for all run files to remote server " + packet.getSourceId() + " @ " + connectionHandlerID);
packetHandler.sendRequestForRunfFiles (packet, packet.getSourceId().getSiteNumber());
-
+
}
} else if (contest.isLocalLoggedIn(clientId) && packet.getType().equals(PacketType.Type.LOGIN)) {
/**
- * A user has logged into another remote server
+ * A user has logged into another remote server
*/
// on site 2 login to site 1, site 2 reports LOGIN on login to site1
processPacket(packet, connectionHandlerID);
} else if (packet.getType().equals(PacketType.Type.LOGIN) && contest.getSite(contest.getSiteNumber()).hasProxy() && packet.getDestinationId().getSiteNumber() == 0) {
/**
- * This is probably coming from our proxy
+ * This is probably coming from our proxy
*/
processPacket(packet, connectionHandlerID);
} else if (contest.isLocalLoggedIn(packet.getDestinationId()) && contest.getSite(contest.getSiteNumber()).getMyProxy() == packet.getDestinationId().getSiteNumber()) {
/**
- * This is coming from our proxy
+ * This is coming from our proxy
*/
processPacket(packet, connectionHandlerID);
} else if (contest.isRemoteLoggedIn(packet.getSourceId()) && packet.getSourceId().getClientType() == ClientType.Type.SERVER) {
@@ -1648,18 +1702,18 @@ public void receiveObject(Serializable object, ConnectionHandlerID connectionHan
/**
* Assign proxy, send updated Site to all connected sites.
- *
+ *
* @param siteToBeProxied client/site to be proxied
* @param proxySiteNumber proxy site for siteToBeProxied
*/
private void sendSiteUpdateSetProxy(ClientId siteToBeProxied, int proxySiteNumber) {
-
- // assign proxy
+
+ // assign proxy
Site site = contest.getSite(siteToBeProxied.getSiteNumber());
site.setMyProxy(proxySiteNumber);
-
+
updateSite(site);
-
+
}
private String[] removeFirstElement(String[] stringArray) {
@@ -1670,7 +1724,7 @@ private String[] removeFirstElement(String[] stringArray) {
/**
* Handle client attempt to auto register.
- *
+ *
* @param packet
* @param connectionHandlerID
*/
@@ -1711,6 +1765,7 @@ private void handleAutoRegistration(Packet packet, ConnectionHandlerID connectio
}
}
+ @Override
public void sendToJudgesAndOthers(Packet packet, boolean sendToServers) {
if (isServer()) {
@@ -1741,7 +1796,7 @@ private boolean isEnableAutoRegistration() {
/**
* Creates and saves a ClientSettings.
- *
+ *
* @param clientId
* @return
*/
@@ -1769,7 +1824,7 @@ private ClientSettings getClientSettings(ClientId clientId) {
/**
* This logs server into local logins and out of remote logins, if needed.
- *
+ *
* @param clientId
* @param connectionHandlerID
*/
@@ -1828,7 +1883,7 @@ private void securityCheck(Packet packet, ConnectionHandlerID connectionHandlerI
/**
* Handle incoming invalid login and message.
- *
+ *
* @param packet
*/
private void handleServerLoginFailure(Packet packet) {
@@ -1861,7 +1916,7 @@ private void handleServerLoginFailure(Packet packet) {
/**
* Looks up site number based on password.
- *
+ *
* @param password
* @return site number or throws SecurityException if nothing matches.
*/
@@ -1913,7 +1968,7 @@ public static boolean matchOverride(String password) {
}
return false;
}
-
+
/**
* Returns true if the password matches the hash for the override password.
*/
@@ -1955,9 +2010,9 @@ protected boolean validAccountAndMatchOverride(ClientId clientId, String passwor
/**
* Attempt to login, if login success add to login list.
- *
+ *
* If login fails will throw SecurityException.
- *
+ *
* @param newClientId the new client attempting to log in.
* @param password the new client's password.
* @param connectionHandlerID the ConnectionHandlerID associated with the newly connecting client.
@@ -1965,13 +2020,13 @@ protected boolean validAccountAndMatchOverride(ClientId clientId, String passwor
private void attemptToLogin(ClientId newClientId, String password, ConnectionHandlerID connectionHandlerID) {
info("ClientID=" + newClientId);
-
+
if (newClientId.getClientType().equals(Type.SERVER)) {
// Server login request
int newSiteNumber = getServerSiteNumber(newClientId.getSiteNumber(), password);
-
- info("Logging in new server; newSiteNumber = " + newSiteNumber);
+
+ info("Logging in new server; newSiteNumber = " + newSiteNumber);
info("My site number = " + contest.getSiteNumber());
if (newSiteNumber == contest.getSiteNumber()) {
@@ -1992,24 +2047,24 @@ private void attemptToLogin(ClientId newClientId, String password, ConnectionHan
} else {
// Client login request
-
+
//check if the account and password are valid
if (validAccountAndMatchOverride(newClientId, password) || contest.isValidLoginAndPassword(newClientId, password)) {
//valid acct and pw; see if the account is already logged in
if (contest.isLocalLoggedIn(newClientId)) {
-
+
//already logged in; see if the current login(s) should be forced off
if (newClientId.getClientType()!=ClientType.Type.TEAM || (!contest.getContestInformation().isAllowMultipleLoginsPerTeam())) {
-
+
//not a team, or is a team but multiple team logins not allowed; force off all clients matching the new client
forceOffAllClientsMatching(newClientId);
}
}
-
+
contest.addLocalLogin(newClientId, connectionHandlerID);
info("LOGIN logged in " + newClientId + " at " + connectionHandlerID);
-
+
} else {
//invalid account or bad password
info("attemptToLogin FAILED logged on: " + newClientId);
@@ -2019,46 +2074,46 @@ private void attemptToLogin(ClientId newClientId, String password, ConnectionHan
}
}
}
-
+
/**
- * Searches the list of currently logged-in clients and forces a logoff for any client matching
+ * Searches the list of currently logged-in clients and forces a logoff for any client matching
* the specified ClientId (that is, any client of the same type, number, and site).
- *
+ *
* @param clientId the ClientId for which matching client logins are to be forced logged-off.
*/
private void forceOffAllClientsMatching(ClientId clientId) {
// get a list of all logged in clients of the same type as the specified client
ClientId[] loggedInClientsOfSameType = contest.getLocalLoggedInClients(clientId.getClientType());
-
+
//check every logged in client in the list
for (ClientId nextLoggedInClientId : loggedInClientsOfSameType) {
-
+
//see if the next logged in client "matches" the specified incoming client.
//(note that ClientId.equals() compares type, number, and site (only))
if (nextLoggedInClientId.equals(clientId)) {
-
+
//yes, matches; force the existing client to logoff
forceLogoff(nextLoggedInClientId);
}
}
}
-
+
/**
* This method forces a logoff of the specified Client.
- *
+ *
* @param clientId the client that is to be forced logged off.
*/
private void forceLogoff(ClientId clientId) {
-
+
// Already logged in, log them off
log.info("login - " + clientId + " already logged in at connection " + clientId.getConnectionHandlerID() + "; forcing logoff " );
-
+
// old code: only removes login from local contest but doesn't notify Admins or Servers
// // this updates the model contest-wide
// contest.removeLogin(clientId);
-
+
//new code: calls contest.removeLogin(clientId) as above, but also calls forceConnectionDrop() and sends LOGOFF packets to Admins and Servers
logoffUser(clientId);
@@ -2070,7 +2125,7 @@ private void forceLogoff(ClientId clientId) {
log.log(Log.WARNING, "Exception on canceling runs/clars for " + clientId, e);
}
}
-
+
// old code; not needed now because the call to logoffUser() (above) calls forceConnectionDrop()
// //this is what actually causes the connection to be dropped/disconnected
// forceConnectionDrop(connHandlerID);
@@ -2085,7 +2140,7 @@ private void forceLogoff(ClientId clientId) {
/**
* Can this user checkout clars and runs.
- *
+ *
* @param theClient
* @return
*/
@@ -2095,11 +2150,11 @@ protected boolean canCheckoutRunsAndClars(ClientId theClient) {
/**
* Process all packets.
- *
+ *
* Assumes that the packet is from an authenticated user.
- *
+ *
* Process packets when user is logged in.
- *
+ *
* @param packet
* @param connectionHandlerID
*/
@@ -2176,7 +2231,7 @@ private void processPacket(Packet packet, ConnectionHandlerID connectionHandlerI
/**
* Send login failure packet back to non-logged in user, via ConnectionHandlerID.
- *
+ *
* @param destinationId
* @param connectionHandlerID
* @param message
@@ -2188,7 +2243,7 @@ private void sendLoginFailure(ClientId destinationId, ConnectionHandlerID connec
/**
* Send Login Success packet to client.
- *
+ *
* @param clientId
* @param connectionHandlerID
*/
@@ -2197,6 +2252,7 @@ private void sendLoginSuccess(ClientId clientId, ConnectionHandlerID connectionH
sendToClient(packetHandler.createLoginSuccessPacket(clientId, contest.getContestPassword()));
}
+ @Override
public void connectionEstablished(ConnectionHandlerID connectionHandlerID) {
info("connectionEstablished: " + connectionHandlerID);
contest.connectionEstablished(connectionHandlerID);
@@ -2208,9 +2264,10 @@ public void connectionEstablished(ConnectionHandlerID connectionHandlerID) {
/**
* Connection to client lost.
- *
+ *
* @throws IOException
*/
+ @Override
public void connectionDropped(ConnectionHandlerID connectionHandlerID) {
// getLog().log(Log.INFO, "connection Dropped for " + connectionHandlerID, new Exception("connection Dropped for " + connectionHandlerID));
@@ -2258,7 +2315,7 @@ protected void cancelAllClarsByThisJudge(ClientId judgeId) throws ContestSecurit
/**
* Cancel all checked out runs and clarifications by this client.
- *
+ *
* @param judgeId
* @throws ContestSecurityException
* @throws FileSecurityException
@@ -2296,6 +2353,7 @@ protected void cancelAllRunsByThisJudge(ClientId judgeId) {
/**
* @throws IllegalArgumentException if the specified ClientId contains a null ConnectionHandlerID.
*/
+ @Override
public void logoffUser(ClientId clientId) {
if (isServer() && contest.isLocalLoggedIn(clientId)) {
@@ -2307,7 +2365,7 @@ public void logoffUser(ClientId clientId) {
ConnectionHandlerID connectionHandlerID = clientId.getConnectionHandlerID();
- //this method should never be called with a clientId having a null ConnectionHandlerID; however, the addition of
+ //this method should never be called with a clientId having a null ConnectionHandlerID; however, the addition of
// "multiple login" support may have left some place where this is inadvertently true.
//The following is an effort to catch/identify such situations.
if (connectionHandlerID==null) {
@@ -2316,7 +2374,7 @@ public void logoffUser(ClientId clientId) {
logException("InternalController.logoffUser() called null ConnectionHandlerID in ClientId " + clientId, e);
throw e;
}
-
+
contest.removeLogin(clientId);
@@ -2335,6 +2393,7 @@ public void logoffUser(ClientId clientId) {
}
+ @Override
public void connectionError(Serializable object, ConnectionHandlerID connectionHandlerID, String causeDescription) {
// SOMEDAY code create a packet and send it to servers and admins
@@ -2346,9 +2405,10 @@ public void connectionError(Serializable object, ConnectionHandlerID connectionH
/**
* Client receive object.
- *
+ *
* @see edu.csus.ecs.pc2.core.transport.IBtoA#receiveObject(java.io.Serializable)
*/
+ @Override
public void receiveObject(Serializable object) {
info(" receiveObject(S) start got " + object);
@@ -2363,14 +2423,14 @@ public void receiveObject(Serializable object) {
// SOMEDAY code put the server's connection handler id as 4th parameter
packetHandler.handlePacket(packet, null);
-
+
} else {
info("receiveObject(S) Unsupported class received: " + object.getClass().getName());
}
} catch (Exception e) {
-
+
error(e.toString(),e);
-
+
if (loginUI != null) {
loginUI.regularCursor();
}
@@ -2381,6 +2441,7 @@ public void receiveObject(Serializable object) {
/**
* This client lost connection.
*/
+ @Override
public void connectionDropped() {
// Connection dropped, countdown and halt client
@@ -2401,19 +2462,19 @@ public void connectionDropped() {
contest.connectionDropped(null);
}
}
-
+
public void setCountdownClassName(String countdownClassName) {
this.countdownClassName = countdownClassName;
}
-
+
public String getCountdownClassName() {
return countdownClassName;
}
-
+
public void setLoginClassName(String loginClassName) {
this.loginClassName = loginClassName;
}
-
+
public String getLoginClassName() {
return loginClassName;
}
@@ -2424,7 +2485,7 @@ public void setStartupDialogClassName(String startupDialogClassName) {
public String getStartupDialogClassName() {
return startupDialogClassName;
- }
+ }
private void shutdown() {
@@ -2442,7 +2503,7 @@ private void shutdown() {
*/
countDownMessage = new TextCountDownMessage();
}
-
+
if (contest.getClientId() != null) {
info("connectionDropped: shutting down " + contest.getClientId());
countDownMessage.setTitle("Shutting down PC^2 " + contest.getClientId().getClientType() + " " + contest.getTitle());
@@ -2452,13 +2513,13 @@ private void shutdown() {
}
countDownMessage.setExitOnClose(true);
countDownMessage.start("Shutting down PC^2 in ", 10);
-
+
/**
- * This is needed to allow the countdown timer threads to
- * actually run, otherwise the JVM ends before the timer starts.
+ * This is needed to allow the countdown timer threads to
+ * actually run, otherwise the JVM ends before the timer starts.
*/
sleep (12);
-
+
}
/**
@@ -2466,22 +2527,22 @@ private void shutdown() {
* @param secs
*/
private void sleep(int secs) {
-
+
try {
Thread.sleep(secs * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
-
+
}
-
+
public void info(String message) {
if (! isUsingGUI()){
System.out.println(message);
}
log.log(Log.INFO, message);
}
-
+
public void error(String message, Exception ex){
if (! isUsingGUI()){
System.err.println(message+" exception "+ex.getMessage());
@@ -2490,7 +2551,7 @@ public void error(String message, Exception ex){
}
public void info(String message, Exception exception) {
-
+
if (! isUsingGUI()){
System.out.println(message);
}
@@ -2501,10 +2562,12 @@ public void info(String message, Exception exception) {
log.log(Log.INFO, message, exception);
}
+ @Override
public void setSiteNumber(int number) {
contest.setSiteNumber(number);
}
+ @Override
public void setContestTime(ContestTime contestTime) {
if (contest.getContestTime() != null) {
contest.updateContestTime(contestTime);
@@ -2513,6 +2576,7 @@ public void setContestTime(ContestTime contestTime) {
}
}
+ @Override
public void sendToServers(Packet packet) {
// do remotes first, for proxies this mean they are shutdown before the server
@@ -2550,25 +2614,25 @@ public void sendToServers(Packet packet) {
/**
* Send packet to all clients logged into this site that are a particular clienttype.
- *
+ *
* @param packet
* @param type client type
*/
private void sendPacketToClients(Packet packet, ClientType.Type type) {
ClientId[] clientIds = contest.getLocalLoggedInClients(type);
-
+
List badClients = new ArrayList();
-
+
for (ClientId clientId : clientIds) {
-
+
if (isThisSite(clientId.getSiteNumber())) {
-
+
ConnectionHandlerID connectionHandlerID = null;
try {
connectionHandlerID = clientId.getConnectionHandlerID();
-
- //there should never be localLoggedInClients with null ConnectionHandlerIDs; however, the addition of
+
+ //there should never be localLoggedInClients with null ConnectionHandlerIDs; however, the addition of
// "multiple login" support may have left some place where this is inadvertently true.
//The following is an effort to catch/identify such situations.
if (connectionHandlerID==null) {
@@ -2576,13 +2640,13 @@ private void sendPacketToClients(Packet packet, ClientType.Type type) {
badClients.add(clientId);
} else {
//good clientId; send the packet to the client
- sendToClient(connectionHandlerID, packet);
+ sendToClient(connectionHandlerID, packet);
}
} catch (Exception e) {
getLog().log(Level.WARNING, "Exception attempting to send packet to client " + clientId + "at connectionHandlerId " + connectionHandlerID
+ ": " + packet + ": "+ e.getMessage(), e);
}
-
+
//check if we got any bad clientIds
if (badClients.size()>0) {
//yes, build a comma-separated list of bad clientIds
@@ -2599,7 +2663,7 @@ private void sendPacketToClients(Packet packet, ClientType.Type type) {
e.printStackTrace();
throw e;
}
-
+
}
}
}
@@ -2610,29 +2674,34 @@ private boolean isThisSite(int siteNumber) {
/**
* Send to judges and spectators clients.
- *
+ *
*/
+ @Override
public void sendToJudges(Packet packet) {
sendPacketToClients(packet, ClientType.Type.JUDGE);
sendPacketToClients(packet, ClientType.Type.SPECTATOR);
}
+ @Override
public void sendToSpectators(Packet packet) {
sendPacketToClients(packet, ClientType.Type.SPECTATOR);
}
+ @Override
public void sendToAdministrators(Packet packet) {
sendPacketToClients(packet, ClientType.Type.ADMINISTRATOR);
}
+ @Override
public void sendToScoreboards(Packet packet) {
sendPacketToClients(packet, ClientType.Type.SCOREBOARD);
}
-
+
public void sendToFeeders(Packet packet) {
sendPacketToClients(packet, ClientType.Type.FEEDER);
}
+ @Override
public void sendToTeams(Packet packet) {
Properties properties = (Properties) packet.getContent();
@@ -2681,10 +2750,11 @@ private int getPortForSite(int inSiteNumber) {
/**
* Client has successfully logged in, show them UI.
- *
+ *
* @param clientId
* new client id
*/
+ @Override
public void startMainUI(ClientId clientId) {
try {
@@ -2739,7 +2809,7 @@ public void startMainUI(ClientId clientId) {
info("Loaded UI class " + uiClassName);
}
}
-
+
uiPlugin.setContestAndController(contest, this);
if (loginUI != null) {
@@ -2770,95 +2840,95 @@ public void startMainUI(ClientId clientId) {
* @param allowedToLoadConfig if true will overwrite config with CDP, else does nothing.
*/
protected void handleCDPLoad(boolean allowedToLoadConfig) {
-
+
/**
* Name of CDP dir or file to be loaded.
*/
String entryLocation = contest.getCommandLineOptionValue(AppConstants.LOAD_OPTION_STRING);
-
+
if (contest.isCommandLineOptionPresent(AppConstants.LOAD_OPTION_STRING)){
-
+
if (allowedToLoadConfig){
-
+
IContestLoader loader = new ContestSnakeYAMLLoader();
info("Loading CDP from " + entryLocation);
-
+
try {
-
+
// Load Configuration from CDP
-
+
loader.initializeContest(contest, new File(entryLocation));
-
+
info("Loaded CDP/config values from " + entryLocation);
-
+
File cdpConfigDir = loader.findCDPConfigDirectory(new File(entryLocation));
-
+
if (contest.getJudgements().length == 0) {
// judgements not loaded from yaml nor config/reject.ini
// load from "."
JudgementLoader.loadJudgements(contest, false, ".");
}
-
-
-
+
+
+
if (saveCofigurationToDisk) {
// save newly merged profiles
contest.storeConfiguration(getLog());
}
-
+
// Load Submissions from CDP
-
+
String submissionsDir = entryLocation + File.separator + IContestLoader.SUBMISSIONS_DIRNAME;
-
- String eventFeedDirectory = entryLocation + File.separator + IContestLoader.EVENT_FEED_DIRNAME;
+
+ String eventFeedDirectory = entryLocation + File.separator + IContestLoader.EVENT_FEED_DIRNAME;
String eventFeedfilename = eventFeedDirectory + File.separator + IContestLoader.EVENT_FEED_XML_FILENAME;
-
-
+
+
if (new File(submissionsDir).isDirectory()){
-
+
if (new File(eventFeedfilename).isFile()){
-
+
info("Loading event feed runs... ");
info("Event feed file is "+eventFeedfilename);
-
+
LoadRuns loadRuns = new LoadRuns();
-
+
List eventFeedRuns = loadRuns.loadRunsFromEventFeed(eventFeedfilename);
-
+
info("Found "+eventFeedRuns.size()+" runs.");
-
+
info("Validating event feed runs");
-
+
loadRuns.validateEventFeedRuns(contest, eventFeedRuns);
-
+
info("Validated "+eventFeedRuns.size()+" event feed runs.");
-
+
info("Loading "+eventFeedRuns.size()+" event feed runs.");
-
+
boolean addRuneJudgementsFromEventFeed = contest.isCommandLineOptionPresent(AppConstants.LOAD_EF_JUDGEMENTS_OPTION_STRING);
-
+
loadRuns.updateContestFromEFRuns(contest, eventFeedRuns, cdpConfigDir.getParent(), addRuneJudgementsFromEventFeed);
-
+
info("Loaded "+eventFeedRuns.size()+" event feed runs.");
if (addRuneJudgementsFromEventFeed){
info("Loaded judgments for "+eventFeedRuns.size()+" event feed runs.");
} else {
info("No judgements were added for "+eventFeedRuns.size()+" event feed runs, all are 'new' runs.");
}
-
+
eventFeedRuns = null;
loadRuns = null;
-
+
} else {
info("No submissions loaded, no event feed at "+eventFeedfilename);
}
-
+
} else {
info("No submissions loaded, no submissions at "+submissionsDir);
}
-
-
-
+
+
+
} catch (Exception e) {
String szMsg = e.getMessage();
if(szMsg == null) {
@@ -2869,17 +2939,17 @@ protected void handleCDPLoad(boolean allowedToLoadConfig) {
loader = null;
}
} else {
-
+
info("** Not loading (" + AppConstants.LOAD_OPTION_STRING + ") CDP from " + entryLocation+" contest config ALREADY exists. **");
- System.err.println ("Warning: contest configuration already exists; ignoring " + AppConstants.LOAD_OPTION_STRING + " option");
-
+ System.err.println ("Warning: contest configuration already exists; ignoring " + AppConstants.LOAD_OPTION_STRING + " option");
+
}
}
}
/**
* Dump Auto Start information to log.
- *
+ *
* @param contestInformation
*/
private void dumpAutoStartInformation(ContestInformation contestInformation) {
@@ -2898,19 +2968,20 @@ private void dumpAutoStartInformation(ContestInformation contestInformation) {
/**
* Start the UI.
*/
+ @Override
public void start(String[] stringArray) {
/**
* Saved exception.
- *
+ *
* If TransportException thrown before UI has been created, save the exception and present it on the UI later.
*/
TransportException savedTransportException = null;
- String[] requireArgumentArgs = { //
- AppConstants.LOGIN_OPTION_STRING,
+ String[] requireArgumentArgs = { //
+ AppConstants.LOGIN_OPTION_STRING,
AppConstants.PASSWORD_OPTION_STRING,
- AppConstants.MAIN_UI_OPTION_STRING,
+ AppConstants.MAIN_UI_OPTION_STRING,
AppConstants.REMOTE_SERVER_OPTION_STRING, //
AppConstants.PORT_OPTION_STRING, //
AppConstants.LOAD_OPTION_STRING, //
@@ -2919,7 +2990,7 @@ public void start(String[] stringArray) {
AppConstants.CONTEST_PASSWORD_OPTION_STRING, //
AppConstants.CONTEST_ID_OPTION_STRING,
AppConstants.FILE_OPTION_STRING };
-
+
/**
* This will not catch unknown options, that is done below after logging is set up
* We scan the arguments twice. First time to allow logging to be set up
@@ -2931,24 +3002,24 @@ public void start(String[] stringArray) {
// mostly catches "IllegalArgumentException" and informs the user
fatalError(e.getMessage(), e);
}
-
+
/**
* usingGUI should be set early no matter what, since we do not want to pop-up
* GUI message boxes on errors, if NO_GUI_OPTION_STRING was specified.
* Validation of NO_GUI_OPTION_STRING is handled in handleCommandLineOptions().
* That is, currently, NO_GUI_OPTION_STRING is only allowed for AJ and server.
- * We don't care about that at this point in time though.
+ * We don't care about that at this point in time though.
*/
if (parseArguments.isOptPresent(AppConstants.NO_GUI_OPTION_STRING)) {
usingGUI = false;
}
-
+
if (parseArguments.isOptPresent(AppConstants.DEBUG_OPTION_STRING)){
parseArguments.dumpArgs(System.out);
}
-
+
contest.setCommandLineArguments(parseArguments);
-
+
if (parseArguments.isOptPresent(AppConstants.SERVER_OPTION_STRING)) {
if (!isContactingRemoteServer()) {
theProfile = getCurrentProfile();
@@ -2961,7 +3032,7 @@ public void start(String[] stringArray) {
} else {
startLog(null, "pc2.startup."+System.currentTimeMillis(), null, null);
}
-
+
// make sure supplied arguments are recognized (allowed)
try {
// this is the second scan of the argument list where accepted options are checked.
@@ -2986,7 +3057,7 @@ public void start(String[] stringArray) {
/**
* if (args DOES NOT contains login/pwd) { String s; if (args contains LoginUI ) { s = args login UI } else { s = pc2 LoginFrame } UIPlugin l = classloader (s); l.setModelAndListener (contest,
* this); } else { this.login (login,password)
- *
+ *
*/
log.info("Starting ConnectionManager...");
@@ -3022,7 +3093,7 @@ public void start(String[] stringArray) {
fatalError("Cannot start PC^2, " + iniName + " cannot be read (" + exception.getMessage() + ")", exception);
}
//the following line was deleted when InternalController was updated per b_1564_integrate_API_work
-// IniFile.setHashtable(ini.getHashmap());
+// IniFile.setHashtable(ini.getHashmap());
}
contest.setSiteNumber(0);
@@ -3061,7 +3132,7 @@ public void start(String[] stringArray) {
try {
setServerPort(parseArguments.getOptValue(AppConstants.PORT_OPTION_STRING));
} catch (NumberFormatException numException) {
- savedTransportException = new TransportException("Unable to parse value after " +
+ savedTransportException = new TransportException("Unable to parse value after " +
AppConstants.PORT_OPTION_STRING + "'" + parseArguments.getOptValue(AppConstants.PORT_OPTION_STRING) + "'");
log.log(Log.WARNING, "Exception parsing " + AppConstants.PORT_OPTION_STRING, numException);
}
@@ -3176,7 +3247,7 @@ private UIPlugin loadUIClass(String className) {
/**
* Get current profile, create one if needed.
- *
+ *
* @return
*/
private Profile getCurrentProfile() {
@@ -3218,7 +3289,7 @@ private void handleCommandLineOptions() {
"[" + AppConstants.FIRST_SERVER_OPTION_STRING + "] " + //
"[" + AppConstants.LOGIN_OPTION_STRING + " ] " + //
"[" + AppConstants.PASSWORD_OPTION_STRING + " ]", //
- " " +
+ " " +
"[" + AppConstants.LOAD_OPTION_STRING + " | ] " + //
"[" + AppConstants.SKIP_INI_OPTION_STRING + "] " + //
"[" + AppConstants.INI_FILENAME_OPTION_STRING + " INIfilename] " + //
@@ -3230,11 +3301,11 @@ private void handleCommandLineOptions() {
" " +
"[" + AppConstants.NOLOGGING_OPTION_STRING + "] " + //
"[" + AppConstants.NO_GUI_OPTION_STRING + "] " + //
- "[" + AppConstants.NOSTANDINGS_OPTION_STRING + "] " +
- "[" + AppConstants.NO_CONNECTIONS_PANE_OPTION_STRING + "] " +
+ "[" + AppConstants.NOSTANDINGS_OPTION_STRING + "] " +
+ "[" + AppConstants.NO_CONNECTIONS_PANE_OPTION_STRING + "] " +
"[" + AppConstants.NO_LOGINS_PANE_OPTION_STRING + "]", //
"", //
- "See https://github.com/pc2ccs/pc2v9/wiki/Command-Line-Arguments for more information", //
+ "See https://github.com/pc2ccs/pc2v9/wiki/Command-Line-Arguments for more information", //
};
for (String string : usage) {
System.out.println(string);
@@ -3259,7 +3330,7 @@ private void handleCommandLineOptions() {
fatalError("Unable to read file " + propertiesFileName, e);
}
}
-
+
if (parseArguments.isOptPresent(AppConstants.NOSTANDINGS_OPTION_STRING)) {
Utilities.setShowStandingsPanes(false);
}
@@ -3297,7 +3368,7 @@ private void handleCommandLineOptions() {
} else if (isScoreboard(client)){
overRideUIName = "edu.csus.ecs.pc2.ui.board.ScoreboardModule";
} else if (isEventFeeder(client)) {
- overRideUIName = "edu.csus.ecs.pc2.services.eventFeed.EventFeederModule";
+ overRideUIName = "edu.csus.ecs.pc2.services.eventFeed.EventFeederModule";
} else {
fatalError(AppConstants.NO_GUI_OPTION_STRING + " can only be used with a judge, server, scoreboard or event feed login, login '" + loginName + "' is not one of those.");
}
@@ -3359,18 +3430,18 @@ private boolean isEventFeeder(ClientId clientId) {
/**
* Print debug message to stdout.
- *
+ *
* @param string
*/
protected void printDebug(String message) {
System.out.println("debug: "+message);
-
+
}
private boolean isJudge(ClientId clientId) {
return clientId.getClientType().equals(ClientType.Type.JUDGE);
}
-
+
private boolean isScoreboard(ClientId clientId) {
return clientId.getClientType().equals(ClientType.Type.SCOREBOARD);
}
@@ -3382,9 +3453,9 @@ private ClientId getServerClientId() {
/**
* Return working directory.
- *
+ *
* File.separator has already been appended as needed.
- *
+ *
* @param dirname
* @return profile directory if server, else return "";
*/
@@ -3399,9 +3470,9 @@ private String getBaseProfileDirectoryName(String dirname) {
/**
* Start new Log for client/server.
- *
+ *
* This new a new Log(logFileName), sets up the StaticLog, and prints basic info to the log. If loginName is not null a Login: line is printed.
- *
+ *
* @param directoryName
* if null will use the profile/* directory.
* @param logFileName
@@ -3435,12 +3506,14 @@ private void startLog(String directoryName, String logFileName, String loginName
}
}
+ @Override
public void checkOutRun(Run run, boolean readOnly, boolean computerJudge) {
ClientId clientId = contest.getClientId();
Packet packet = PacketFactory.createRunRequest(clientId, getServerClientId(), run, clientId, readOnly, computerJudge);
sendToLocalServer(packet);
}
+ @Override
public void checkOutRejudgeRun(Run run) {
ClientId clientId = contest.getClientId();
Packet packet = PacketFactory.createRunRejudgeRequest(clientId, getServerClientId(), run, clientId);
@@ -3450,6 +3523,7 @@ public void checkOutRejudgeRun(Run run) {
/**
* Send run judgement to server.
*/
+ @Override
public void submitRunJudgement(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles) {
ClientId clientId = contest.getClientId();
Packet packet = PacketFactory.createRunJudgement(clientId, getServerClientId(), run, judgementRecord, runResultFiles);
@@ -3459,6 +3533,7 @@ public void submitRunJudgement(Run run, JudgementRecord judgementRecord, RunResu
/**
* Send cancel run to server.
*/
+ @Override
public void cancelRun(Run run) {
ClientId clientId = contest.getClientId();
Packet packet = PacketFactory.createUnCheckoutRun(clientId, getServerClientId(), run, clientId);
@@ -3467,11 +3542,12 @@ public void cancelRun(Run run) {
/**
* Add a new site into contest, send update to other servers.
- *
+ *
* @throws FileSecurityException
* @throws ClassNotFoundException
* @throws IOException
*/
+ @Override
public void addNewSite(Site site) {
if (isServer()) {
contest.addSite(site);
@@ -3511,6 +3587,7 @@ public void modifySite(Site site) {
sendToServers(packet);
}
+ @Override
public void sendServerLoginRequest(int inSiteNumber) throws Exception {
if (isServer()) {
@@ -3525,7 +3602,7 @@ public void sendServerLoginRequest(int inSiteNumber) throws Exception {
}
Site remoteSite = lookupRemoteServer(inSiteNumber);
-
+
Site localSite = contest.getSite(contest.getSiteNumber());
String localPassword = localSite.getPassword();
@@ -3554,7 +3631,7 @@ public void sendServerLoginRequest(int inSiteNumber) throws Exception {
info("Contacted Site " + inSiteNumber + " (via " + remoteSite.getSiteNumber() + ") using connection id " + connectionHandlerID);
sendLoginRequestFromServerToServer(connectionManager, connectionHandlerID, getServerClientId(), localPassword, false, inSiteNumber);
-
+
} else if (contest.isAllowed(Permission.Type.ALLOWED_TO_RECONNECT_SERVER)) {
// Send the reconnection request to our server
@@ -3571,9 +3648,9 @@ public void sendServerLoginRequest(int inSiteNumber) throws Exception {
/**
* Determine which site to send this packet to.
- *
+ *
* This handles packets sent via proxy.
- *
+ *
* @param inSiteNumber destination site
* @return site to send packet to.
*/
@@ -3584,8 +3661,8 @@ protected Site lookupRemoteServer(int inSiteNumber) {
*/
Site site = contest.getSite(inSiteNumber);
Site mySite = contest.getSite(contest.getSiteNumber());
-
- // if the destination has a proxy
+
+ // if the destination has a proxy
if (site.hasProxy()) {
/**
@@ -3599,14 +3676,14 @@ protected Site lookupRemoteServer(int inSiteNumber) {
} else if (mySite.hasProxy()) {
site = contest.getSite(mySite.getMyProxy());
}// else no proxys, send to site
-
+
// System.out.println("debug lookupRemoteServer for site "+inSiteNumber+" use site "+site);
return site;
}
/**
* Contacting remote server (joining contest).
- *
+ *
* @return true if joining contest, false if first server
*/
public boolean isContactingRemoteServer() {
@@ -3619,9 +3696,9 @@ public void setContactingRemoteServer(boolean contactingRemoteServer) {
/**
* Will main UI be invoked/displayed ?
- *
+ *
* This includes Login UI as well as Main UI.
- *
+ *
* @return true - shows main UI, false - does not show main UI.
*/
public boolean isUsingMainUI() {
@@ -3640,6 +3717,7 @@ public void setUiPlugin(UIPlugin uiPlugin) {
this.uiPlugin = uiPlugin;
}
+ @Override
public void updateSite(Site site) {
if (isServer()) {
@@ -3670,7 +3748,7 @@ public void updateSite(Site site) {
/**
* Returns true if this client is a server.
- *
+ *
* @return true if logged in client is a server.
*/
private boolean isServer() {
@@ -3681,21 +3759,25 @@ private boolean isServer(ClientId clientId) {
return clientId.getClientType().equals(ClientType.Type.SERVER);
}
+ @Override
public final Log getLog() {
return log;
}
+ @Override
public void generateNewAccounts(String clientTypeName, int siteNumber, int count, int startNumber, boolean active) {
ClientType.Type type = ClientType.Type.valueOf(clientTypeName);
Packet packet = PacketFactory.createGenerateAccounts(contest.getClientId(), getServerClientId(), siteNumber, type, count, startNumber, active);
sendToLocalServer(packet);
}
+ @Override
public void generateNewAccounts(String clientTypeName, int count, int startNumber, boolean active) {
generateNewAccounts(clientTypeName, contest.getSiteNumber(), count, startNumber, active);
}
+ @Override
public void submitClarification(Problem problem, String question) {
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
@@ -3706,27 +3788,31 @@ public void submitClarification(Problem problem, String question) {
sendToLocalServer(packet);
}
+ @Override
public void checkOutClarification(Clarification clarification, boolean readOnly) {
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Packet packet = PacketFactory.createClarificationRequest(contest.getClientId(), serverClientId, clarification.getElementId(), contest.getClientId());
sendToLocalServer(packet);
}
+ @Override
public void cancelClarification(Clarification clarification) {
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Packet packet = PacketFactory.createUnCheckoutClarification(contest.getClientId(), serverClientId, clarification);
sendToLocalServer(packet);
}
+ @Override
public void submitClarificationAnswer(Clarification clarification) {
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Packet packet = PacketFactory.createAnsweredClarification(contest.getClientId(), serverClientId, clarification, clarification.getAnswer());
sendToLocalServer(packet);
}
+ @Override
public void forceConnectionDrop(ConnectionHandlerID connectionHandlerID) {
- //this method should never be called with a null ConnectionHandlerID; however, the addition of
+ //this method should never be called with a null ConnectionHandlerID; however, the addition of
// "multiple login" support may have left some place where this is inadvertently true.
//The following is an effort to catch/identify such situations.
if (connectionHandlerID==null) {
@@ -3735,7 +3821,7 @@ public void forceConnectionDrop(ConnectionHandlerID connectionHandlerID) {
logException("InternalController.forceConnectionDrop() called with null ConnectionHandlerID", e);
throw e;
}
-
+
if (isServer()) {
if (contest.isConnected(connectionHandlerID)) {
@@ -3755,40 +3841,48 @@ public void forceConnectionDrop(ConnectionHandlerID connectionHandlerID) {
}
}
+ @Override
public void addNewProblem(Problem problem, ProblemDataFiles problemDataFiles) {
Packet updateProblemPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), problem, problemDataFiles);
sendToLocalServer(updateProblemPacket);
}
+ @Override
public void addNewProblem(Problem[] problem, ProblemDataFiles[] problemDataFiles) {
Packet updateProblemPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), problem, problemDataFiles);
sendToLocalServer(updateProblemPacket);
}
+ @Override
public void updateRun(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles) {
Packet updateRunPacket = PacketFactory.createRunUpdated(contest.getClientId(), getServerClientId(), run, judgementRecord, runResultFiles, contest.getClientId());
sendToLocalServer(updateRunPacket);
}
+ @Override
public void addProblem(Problem problem) {
Packet updateProblemPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), problem, null);
sendToLocalServer(updateProblemPacket);
}
+ @Override
public void updateProblem(Problem problem) {
Packet updateProblemPacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), problem, null);
sendToLocalServer(updateProblemPacket);
}
+ @Override
public void updateProblem(Problem problem, ProblemDataFiles problemDataFiles) {
Packet updateProblemPacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), problem, problemDataFiles);
sendToLocalServer(updateProblemPacket);
}
+ @Override
public ProblemDataFiles getProblemDataFiles(Problem problem) {
return contest.getProblemDataFile(problem);
}
+ @Override
public void shutdownTransport() {
connectionManager.shutdownTransport();
}
@@ -3796,6 +3890,7 @@ public void shutdownTransport() {
/**
* Removes connection from list and sends packet.
*/
+ @Override
public void removeConnection(ConnectionHandlerID connectionHandlerID) {
contest.connectionDropped(connectionHandlerID);
@@ -3809,6 +3904,7 @@ public void removeConnection(ConnectionHandlerID connectionHandlerID) {
/**
* Removed login from system and sends packet.
*/
+ @Override
public void removeLogin(ClientId clientId) {
contest.removeLogin(clientId);
@@ -3825,66 +3921,79 @@ public void removeLogin(ClientId clientId) {
}
}
+ @Override
public void startContest(int inSiteNumber) {
Packet packet = PacketFactory.createStartContestClock(contest.getClientId(), getServerClientId(), inSiteNumber, contest.getClientId());
sendToLocalServer(packet);
}
+ @Override
public void stopContest(int inSiteNumber) {
Packet packet = PacketFactory.createStopContestClock(contest.getClientId(), getServerClientId(), inSiteNumber, contest.getClientId());
sendToLocalServer(packet);
}
+ @Override
public void startAllContestTimes() {
Packet packet = PacketFactory.createStartAllClocks(contest.getClientId(), getServerClientId(), contest.getClientId());
sendToLocalServer(packet);
}
+ @Override
public void stopAllContestTimes() {
Packet packet = PacketFactory.createStopAllClocks(contest.getClientId(), getServerClientId(), contest.getClientId());
sendToLocalServer(packet);
}
+ @Override
public void addNewLanguage(Language language) {
Packet addLanguagePacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), language);
sendToLocalServer(addLanguagePacket);
}
+ @Override
public void addNewJudgement(Judgement judgement) {
Packet addJudgementPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), judgement);
sendToLocalServer(addJudgementPacket);
}
+ @Override
public void updateLanguage(Language language) {
Packet updateLanguagePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), language);
sendToLocalServer(updateLanguagePacket);
}
+ @Override
public void updateJudgement(Judgement judgement) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), judgement);
sendToLocalServer(updatePacket);
}
+ @Override
public void updateAccount(Account account) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), account);
sendToLocalServer(updatePacket);
}
+ @Override
public void updateAccounts(Account[] accounts) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), accounts);
sendToLocalServer(updatePacket);
}
+ @Override
public void updateCategories(Category[] categories) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), categories);
sendToLocalServer(updatePacket);
}
+ @Override
public void addNewAccount(Account account) {
Packet addAccountPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), account);
sendToLocalServer(addAccountPacket);
}
+ @Override
public void addNewAccounts(Account[] accounts) {
Packet addAccountPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), accounts);
sendToLocalServer(addAccountPacket);
@@ -3892,9 +4001,9 @@ public void addNewAccounts(Account[] accounts) {
/**
* Read Configuration.
- *
+ *
* Halt if configuration is corrupt.
- *
+ *
* @param siteNum
* @return true if config file read
*/
@@ -3904,15 +4013,15 @@ public boolean readConfigFromDisk(int siteNum) {
if (saveCofigurationToDisk) {
try {
loadedConfiguration = contest.readConfiguration(siteNum, getLog());
-
+
} catch (FileNotFoundException fnf){
// This is expected
loadedConfiguration = false;
-
+
} catch (Exception e) {
logException(e);
-
- // Bug 879 -If there is a problem reading the config then exit and show a message.
+
+ // Bug 879 -If there is a problem reading the config then exit and show a message.
fatalError("Halting server - configuration file corrupt", e);
return false;
}
@@ -3920,36 +4029,43 @@ public boolean readConfigFromDisk(int siteNum) {
return loadedConfiguration;
}
+ @Override
public void addNewClientSettings(ClientSettings clientSettings) {
Packet addClientSettingsPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), clientSettings);
sendToLocalServer(addClientSettingsPacket);
}
+ @Override
public void updateClientSettings(ClientSettings clientSettings) {
Packet updateClientSettingsPacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), clientSettings);
sendToLocalServer(updateClientSettingsPacket);
}
+ @Override
public void updateContestInformation(ContestInformation contestInformation) {
Packet contestInfoPacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), contestInformation);
sendToLocalServer(contestInfoPacket);
}
+ @Override
public void setJudgementList(Judgement[] judgementList) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), judgementList);
sendToLocalServer(updatePacket);
}
+ @Override
public void removeJudgement(Judgement judgement) {
Packet deleteJudgmentPacket = PacketFactory.createDeleteSetting(contest.getClientId(), getServerClientId(), judgement);
sendToLocalServer(deleteJudgmentPacket);
}
+ @Override
public void addNewBalloonSettings(BalloonSettings newBalloonSettings) {
Packet newBalloonSettingsPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), newBalloonSettings);
sendToLocalServer(newBalloonSettingsPacket);
}
+ @Override
public void updateBalloonSettings(BalloonSettings balloonSettings) {
Packet balloonSettingsPacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), balloonSettings);
sendToLocalServer(balloonSettingsPacket);
@@ -3959,32 +4075,37 @@ public int getSiteNumber() {
return contest.getSiteNumber();
}
+ @Override
public void updateContestTime(ContestTime newContestTime) {
Packet newContestTimePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), newContestTime);
sendToLocalServer(newContestTimePacket);
}
+ @Override
public void addNewGroup(Group group) {
Packet newGroupPacket = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), group);
sendToLocalServer(newGroupPacket);
}
+ @Override
public void updateGroup(Group group) {
Packet groupPacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), group);
sendToLocalServer(groupPacket);
}
+ @Override
public int getSecurityLevel() {
return securityLevel;
}
+ @Override
public void setSecurityLevel(int securityLevel) {
this.securityLevel = securityLevel;
}
/**
* Server send out security packet.
- *
+ *
*/
public void sendSecurityMessageFromServer(ContestSecurityException contestSecurityException, ConnectionHandlerID connectionHandlerID, Packet packet) {
Packet violationPacket = PacketFactory.createSecurityMessagePacket(contest.getClientId(), PacketFactory.ALL_SERVERS, contestSecurityException.getSecurityMessage(), null, connectionHandlerID,
@@ -3997,20 +4118,24 @@ public void sendSecurityMessageFromServer(ContestSecurityException contestSecuri
}
+ @Override
public void sendSecurityMessage(String event, String message, ContestSecurityException contestSecurityException) {
Packet securityMessagePacket = PacketFactory.createSecurityMessagePacket(contest.getClientId(), getServerClientId(), event, contestSecurityException.getClientId(),
contestSecurityException.getConnectionHandlerID(), contestSecurityException, null);
sendToLocalServer(securityMessagePacket);
}
+ @Override
public String getHostContacted() {
return remoteHostName;
}
+ @Override
public int getPortContacted() {
return remoteHostPort;
}
+ @Override
public void fetchRun(Run run) throws IOException, ClassNotFoundException, FileSecurityException {
RunFiles runFiles = contest.getRunFiles(run);
@@ -4030,42 +4155,51 @@ private void sendStatusMessge(Run run, RunExecutionStatus status) {
}
}
+ @Override
public void sendCompilingMessage(Run run) {
sendStatusMessge(run, RunExecutionStatus.COMPILING);
}
+ @Override
public void sendExecutingMessage(Run run) {
sendStatusMessge(run, RunExecutionStatus.EXECUTING);
}
+ @Override
public void sendValidatingMessage(Run run) {
sendStatusMessge(run, RunExecutionStatus.VALIDATING);
}
+ @Override
public boolean isClientAutoShutdown() {
return clientAutoShutdown;
}
+ @Override
public void setClientAutoShutdown(boolean clientAutoShutdown) {
this.clientAutoShutdown = clientAutoShutdown;
}
+ @Override
public void resetContest(ClientId clientResettingContest, boolean eraseProblems, boolean eraseLanguages) {
Profile currentProfile = contest.getProfile();
Packet sendPacket = PacketFactory.createResetAllSitesPacket(contest.getClientId(), getServerClientId(), clientResettingContest, currentProfile, eraseProblems, eraseLanguages);
sendToLocalServer(sendPacket);
}
+ @Override
public void cloneProfile(Profile profile, ProfileCloneSettings settings, boolean switchNow) {
Packet sendPacket = PacketFactory.createCloneProfilePacket(contest.getClientId(), getServerClientId(), profile, settings, switchNow);
sendToLocalServer(sendPacket);
}
+ @Override
public void switchProfile(Profile currentProfile, Profile switchToProfile, String contestPassword) {
Packet sendPacket = PacketFactory.createSwitchProfilePacket(contest.getClientId(), getServerClientId(), currentProfile, switchToProfile, contestPassword);
sendToLocalServer(sendPacket);
}
+ @Override
public void updateProfile(Profile profile) {
Packet updateProfilePackert = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), profile);
sendToLocalServer(updateProfilePackert);
@@ -4094,12 +4228,12 @@ private void showErrorMessage(String message, String title) {
/**
* Fatal error - log error and show user message before exiting.
- *
+ *
* @param message
* @param ex
*/
protected void fatalError(String message, Exception ex) {
-
+
if (log != null) {
if (ex != null) {
log.log(Log.SEVERE, message, ex);
@@ -4131,11 +4265,11 @@ protected void fatalError(String message, Exception ex) {
if (haltOnFatalError) {
System.exit(4);
}
-
+
}
/**
- *
+ *
* @see #fatalError(String, Exception)
* @param message
*/
@@ -4143,6 +4277,7 @@ private void fatalError(String message) {
fatalError(message, null);
}
+ @Override
public void setContest(IInternalContest newContest) {
this.contest = newContest;
contest.setCommandLineArguments(parseArguments);
@@ -4150,10 +4285,12 @@ public void setContest(IInternalContest newContest) {
runSubmitterInterfaceManager.setContestAndController(newContest, this);
}
+ @Override
public void register(UIPlugin plugin) {
pluginList.register(plugin);
}
+ @Override
public UIPlugin[] getPluginList() {
return pluginList.getList();
}
@@ -4170,6 +4307,7 @@ private void firePacketListener(PacketEvent packetEvent) {
}
}
+ @Override
public void updateContestController(IInternalContest inContest, IInternalController inController) {
setContest(inContest);
@@ -4250,19 +4388,23 @@ private void logException(String message, Exception e) {
}
}
+ @Override
public void addPacketListener(IPacketListener packetListener) {
packetListenerList.addElement(packetListener);
}
+ @Override
public void removePacketListener(IPacketListener packetListener) {
packetListenerList.removeElement(packetListener);
}
+ @Override
public void incomingPacket(Packet packet) {
PacketEvent event = new PacketEvent(Action.RECEIVED, packet);
firePacketListener(event);
}
+ @Override
public void outgoingPacket(Packet packet) {
PacketEvent event = new PacketEvent(Action.SENT, packet);
firePacketListener(event);
@@ -4272,18 +4414,22 @@ public void setLog(Log log) {
this.log = log;
}
+ @Override
public boolean isUsingGUI() {
return usingGUI;
}
+ @Override
public boolean isSuppressConnectionsPaneDisplay() {
return suppressConnectionsPaneDisplay;
}
+ @Override
public boolean isSuppressLoginsPaneDisplay() {
return suppressLoginsPaneDisplay;
}
+ @Override
public ILogWindow startLogWindow(IInternalContest inContest) {
if (!isUsingGUI()) {
@@ -4305,11 +4451,12 @@ public ILogWindow startLogWindow(IInternalContest inContest) {
return logWindow;
}
- private String noLogWindowAvailableMsg =
- "Log Window is null or invalid; cannot show log."
+ private String noLogWindowAvailableMsg =
+ "Log Window is null or invalid; cannot show log."
+ "\n (Log Windows were temporarily disabled in certain Clients (see Issue https://github.com/pc2ccs/pc2v9/pull/555);"
- + "\n you may be running a version of PC^2 which still includes this patch...)";
+ + "\n you may be running a version of PC^2 which still includes this patch...)";
+ @Override
public void showLogWindow(boolean showWindow) {
if (isUsingGUI()) {
@@ -4322,6 +4469,7 @@ public void showLogWindow(boolean showWindow) {
}
}
+ @Override
public boolean isLogWindowVisible() {
if (isUsingGUI()) {
if (logWindow != null && logWindow instanceof ILogWindow) {
@@ -4340,6 +4488,7 @@ public void logWarning(String string) {
System.err.println("Warning: " + string);
}
+ @Override
public void logWarning(String string, Exception e) {
log.log(Log.WARNING, string, e);
System.err.println("Warning: " + string);
@@ -4367,24 +4516,28 @@ private void printStackTraceTop(Throwable throwable, PrintStream printStream, in
}
}
+ @Override
public void syncProfileSubmissions(Profile profile) {
Packet packet = PacketFactory.createSwitchSynchronizePacket(contest.getClientId(), getServerClientId(), profile);
sendToLocalServer(packet);
}
+ @Override
public void sendShutdownAllSites() {
Packet packet = PacketFactory.createShutdownAllServersPacket(contest.getClientId(), getServerClientId());
sendToLocalServer(packet);
}
+ @Override
public void sendShutdownSite(int siteNumber) {
Packet packet = PacketFactory.createShutdownPacket(contest.getClientId(), getServerClientId(), siteNumber);
sendToLocalServer(packet);
}
/**
- *
+ *
*/
+ @Override
public void shutdownServer(ClientId requestor) {
if (isServer()) {
@@ -4418,6 +4571,7 @@ public void shutdownServer(ClientId requestor) {
}
}
+ @Override
public void shutdownRemoteServers(ClientId requestor) {
if (contest.isAllowed(requestor, Permission.Type.SHUTDOWN_ALL_SERVERS)) {
@@ -4434,6 +4588,7 @@ public void shutdownRemoteServers(ClientId requestor) {
}
}
+ @Override
public void shutdownServer(ClientId requestor, int siteNumber) {
if (contest.isAllowed(requestor, Permission.Type.SHUTDOWN_ALL_SERVERS) || contest.isAllowed(requestor, Permission.Type.SHUTDOWN_SERVER)) {
@@ -4476,30 +4631,36 @@ protected ClientId getServerClientId(int siteNumber) {
return new ClientId(siteNumber, Type.SERVER, 0);
}
+ @Override
public void updateFinalizeData(FinalizeData data) {
Packet updateFinalizePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), data);
sendToLocalServer(updateFinalizePacket);
}
+ @Override
public void setUsingGUI(boolean usingGUI) {
this.usingGUI = usingGUI;
}
+ @Override
public void updateCategory(Category newCategory) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), newCategory);
sendToLocalServer(updatePacket);
}
+ @Override
public void addNewCategory(Category newCategory) {
Packet addNewCategory = PacketFactory.createAddSetting(contest.getClientId(), getServerClientId(), newCategory);
sendToLocalServer(addNewCategory);
}
+ @Override
public void startPlayback(PlaybackInfo playbackInfo) {
Packet startPacket = PacketFactory.createStartPlayback(contest.getClientId(), getServerClientId(), playbackInfo);
sendToLocalServer(startPacket);
}
+ @Override
public void sendRunToSubmissionInterface(Run run, RunFiles runFiles) {
try {
runSubmitterInterfaceManager.sendRun(run, runFiles);
@@ -4520,15 +4681,16 @@ public void addConsoleLogging() {
System.err.println("Unable to add console logging, log is null");
}
}
-
+
public Profile getTheProfile() {
return theProfile;
}
-
+
public void setTheProfile(Profile theProfile) {
this.theProfile = theProfile;
}
-
+
+ @Override
public void autoRegister(String loginName) {
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
@@ -4541,11 +4703,11 @@ public void autoRegister(String loginName) {
public void setConnectionManager(ITransportManager connectionManager) {
this.connectionManager = connectionManager;
}
-
+
public void setHaltOnFatalError(boolean haltOnFatalError) {
this.haltOnFatalError = haltOnFatalError;
}
-
+
public boolean isHaltOnFatalError() {
return haltOnFatalError;
}
@@ -4573,18 +4735,19 @@ public void updateGroups(Group[] groups) {
Packet updatePacket = PacketFactory.createUpdateSetting(contest.getClientId(), getServerClientId(), groups);
sendToLocalServer(updatePacket);
}
-
+
/**
* Creates an {@link AutoStarter} if none exists, and then instructs the AutoStarter to update its Scheduled Start Task to correspond to the Scheduled Start Time information in the
* {@link ContestInformation} object in the received {@link IInternalContest}.
- *
+ *
* @param theContest
* - the Contest (Model) containing the Scheduled Start Time information
* @param theController
* - the Controller to which this request applies
*/
+ @Override
public void updateAutoStartInformation(IInternalContest theContest, IInternalController theController) {
-
+
// if I'm a server then if there's no AutoStarter create one, and then tell the AutoStarter to
// update its Scheduled Start task list based on the ContestInformation in theContest (Model).
// if (isServer()) {
@@ -4641,7 +4804,7 @@ public void updateAutoStartInformation(IInternalContest theContest, IInternalCon
// System.err.println ("in updateAutoStartInformation() -- NOT A SERVER!!");
// }
}
-
+
/**
* Start Auto Stop Contest Clock Thread.
*/
@@ -4650,7 +4813,7 @@ private void updateAutoStopClockThread() {
if (autoStopContestClockThread == null) {
autoStopContestClockThread = new AutoStopContestClockThread(this, contest);
autoStopContestClockThread.start();
-
+
ContestTime time = contest.getContestTime();
log.info("Started auto stop clock thread, remaining time is " + time.getRemainingTimeStr());
}
@@ -4664,13 +4827,13 @@ public IInternalContest getContest() {
@Override
public void submitRun(ClientId submitter, Problem problem, Language language, SerializedFile mainSubmissionFile, SerializedFile[] additionalFiles, long overrideTimeMS, long overrideRunId) {
-
+
submitRun(submitter, problem, language, null, mainSubmissionFile, additionalFiles, overrideTimeMS, overrideRunId);
}
@Override
public void submitRun(ClientId submitter, Problem problem, Language language, String entry_point, SerializedFile mainSubmissionFile, SerializedFile[] additionalFiles, long overrideTimeMS, long overrideSubmissionId) {
-
+
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Run run = new Run(submitter, language, problem);
run.setEntryPoint(entry_point);
@@ -4678,7 +4841,7 @@ public void submitRun(ClientId submitter, Problem problem, Language language, St
Packet packet = PacketFactory.createSubmittedRun(contest.getClientId(), serverClientId, run, runFiles, overrideTimeMS, overrideSubmissionId);
sendToLocalServer(packet);
-
+
}
-
+
}
diff --git a/src/edu/csus/ecs/pc2/core/LanguageUtilities.java b/src/edu/csus/ecs/pc2/core/LanguageUtilities.java
index a73f1adbe..ee02e2da6 100644
--- a/src/edu/csus/ecs/pc2/core/LanguageUtilities.java
+++ b/src/edu/csus/ecs/pc2/core/LanguageUtilities.java
@@ -1,4 +1,4 @@
-// Copyright (C) 1989-2023 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
+// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
package edu.csus.ecs.pc2.core;
import edu.csus.ecs.pc2.core.model.IInternalContest;
@@ -6,13 +6,17 @@
/**
* Utility methods for languages
- *
+ *
* @author Douglas A. Lane
*/
public class LanguageUtilities {
-
+
/**
- * List of language extensions and their full or partial language display name
+ * Legacy list of language extensions and their full or partial language display name
+ * This should be deprecated and languages defined in system.pc2.yaml should be required to
+ * include the CLICS ID (as shown above) and optionally a list of extensions supported by the
+ * language. The list below is inadequate and out of date. For the moment, it is included for
+ * backward compatibility. JB
*/
public static final String[][] LANGUAGE_LIST = { //
{ "java", "Java" }, //
@@ -28,10 +32,9 @@ public class LanguageUtilities {
{ "c", "C" }, //
};
-
- /**
+ /**
* get file extension.
- *
+ *
* @param filename
* @return file extension if no period found returns null
*/
@@ -45,7 +48,7 @@ public static String getExtension(String filename) {
/**
* Match a contest Language for the input extension.
- *
+ *
* @param myContest contest model
* @param filename base name file or full path name.
* @return
@@ -57,14 +60,22 @@ public static Language guessLanguage(IInternalContest myContest, String filename
/**
* Match a contest Language for the input extension.
- *
+ *
* @param inContest contest model
* @param extension the extension without period, ex cpp
* @return null if does not match any language title
*/
public static Language matchFirstLanguage(IInternalContest inContest, String extension) {
- Language[] lang = inContest.getLanguages();
+ Language[] allLangs = inContest.getLanguages();
+ // first try the new way
+ for(Language lang : allLangs) {
+ if(lang.getExtensions().contains(extension)) {
+ return(lang);
+ }
+ }
+
+ // if all else fails, try the old way. This should be deprecated. JB
/**
* Partial or complete display name
*/
@@ -73,7 +84,7 @@ public static Language matchFirstLanguage(IInternalContest inContest, String ext
for (String[] row : LANGUAGE_LIST) {
String fileExtension = row[0];
String dispName = row[1];
-
+
if (fileExtension.equals(extension)) {
displayName = dispName;
break;
@@ -82,7 +93,7 @@ public static Language matchFirstLanguage(IInternalContest inContest, String ext
displayName = displayName.toLowerCase();
- for (Language language : lang) {
+ for (Language language : allLangs) {
if (language.getDisplayName().toLowerCase().indexOf(displayName) != -1) {
return language;
}
diff --git a/src/edu/csus/ecs/pc2/core/MockController.java b/src/edu/csus/ecs/pc2/core/MockController.java
index 5662325a9..69017228e 100644
--- a/src/edu/csus/ecs/pc2/core/MockController.java
+++ b/src/edu/csus/ecs/pc2/core/MockController.java
@@ -41,290 +41,358 @@
/**
* Mock Controller.
- *
+ *
* Some data is mock data some methods implement the controller/contest.
- *
+ *
*/
public class MockController implements IInternalController {
private IInternalContest contest;
-
+
private PacketHandler handler = null;
-
+
private Log log;
+ @Override
public void addNewAccount(Account account) {
contest.addAccount(account);
}
+ @Override
public void addNewAccounts(Account[] accounts) {
contest.addAccounts(accounts);
}
+ @Override
public void addNewBalloonSettings(BalloonSettings newBalloonSettings) {
}
+ @Override
public void addNewCategory(Category newCategory) {
}
+ @Override
public void addNewClientSettings(ClientSettings newClientSettings) {
contest.addClientSettings(newClientSettings);
}
+ @Override
public void addNewGroup(Group group) {
contest.addGroup(group);
}
+ @Override
public void addNewJudgement(Judgement judgement) {
contest.addJudgement(judgement);
}
+ @Override
public void addNewLanguage(Language language) {
contest.addLanguage(language);
}
+ @Override
public void addNewProblem(Problem problem, ProblemDataFiles problemDataFiles) {
contest.addProblem(problem, problemDataFiles);
}
+ @Override
public void addNewProblem(Problem[] problem, ProblemDataFiles[] problemDataFiles) {
for (int i = 0; i < problemDataFiles.length; i++) {
contest.addProblem(problem[i], problemDataFiles[i]);
}
}
+ @Override
public void addNewSite(Site site) {
contest.addSite(site);
}
+ @Override
public void addPacketListener(IPacketListener packetListener) {
}
+ @Override
public void addProblem(Problem problem) {
contest.addProblem(problem);
}
+ @Override
public void autoRegister(String teamInformation) {
}
+ @Override
public void cancelClarification(Clarification clarification) {
}
+ @Override
public void cancelRun(Run run) {
}
+ @Override
public void checkOutClarification(Clarification clarification, boolean readOnly) {
}
+ @Override
public void checkOutRejudgeRun(Run theRun) {
}
+ @Override
public void checkOutRun(Run run, boolean readOnly, boolean computerJudge) {
}
+ @Override
public IInternalContest clientLogin(IInternalContest internalContest, String loginName, String password) throws Exception {
return null;
}
+ @Override
public void cloneProfile(Profile profile, ProfileCloneSettings settings, boolean switchNow) {
}
+ @Override
public void fetchRun(Run run) throws IOException, ClassNotFoundException, FileSecurityException {
}
+ @Override
public void forceConnectionDrop(ConnectionHandlerID connectionHandlerID) {
}
+ @Override
public void generateNewAccounts(String clientTypeName, int count, int startNumber, boolean active) {
}
+ @Override
public void generateNewAccounts(String clientTypeName, int siteNumber, int count, int startNumber, boolean active) {
}
+ @Override
public String getHostContacted() {
return null;
}
+ @Override
public Log getLog() {
return log;
}
+ @Override
public UIPlugin[] getPluginList() {
return null;
}
+ @Override
public int getPortContacted() {
return 0;
}
+ @Override
public ProblemDataFiles getProblemDataFiles(Problem problem) {
return null;
}
+ @Override
public int getSecurityLevel() {
return 0;
}
+ @Override
public void incomingPacket(Packet packet) {
}
+ @Override
public void initializeServer(IInternalContest contest) throws IOException, ClassNotFoundException, FileSecurityException {
-
+
setContest(contest);
}
+ @Override
public void initializeStorage(IStorage storage) {
}
+ @Override
public boolean isClientAutoShutdown() {
return false;
}
+ @Override
public boolean isLogWindowVisible() {
return false;
}
+ @Override
public boolean isUsingGUI() {
return false;
}
+ @Override
public void login(String loginName, String password) {
}
+ @Override
public void logoffUser(ClientId clientId) {
}
+ @Override
public void logWarning(String string, Exception e) {
}
+ @Override
public void outgoingPacket(Packet packet) {
}
+ @Override
public void register(UIPlugin plugin) {
}
+ @Override
public void removeConnection(ConnectionHandlerID connectionHandlerID) {
}
+ @Override
public void removeJudgement(Judgement judgement) {
}
+ @Override
public void removeLogin(ClientId clientId) {
}
+ @Override
public void removePacketListener(IPacketListener packetListener) {
}
+ @Override
public void requestChangePassword(String oldPassword, String newPassword) {
}
+ @Override
public void resetContest(ClientId clientResettingContest, boolean eraseProblems, boolean eraseLanguages) {
}
+ @Override
public void sendCompilingMessage(Run run) {
}
+ @Override
public void sendExecutingMessage(Run run) {
}
+ @Override
public void sendRunToSubmissionInterface(Run run, RunFiles runFiles) {
}
+ @Override
public void sendSecurityMessage(String event, String message, ContestSecurityException contestSecurityException) {
}
+ @Override
public void sendServerLoginRequest(int inSiteNumber) throws Exception {
}
+ @Override
public void sendShutdownAllSites() {
}
+ @Override
public void sendShutdownSite(int siteNumber) {
}
+ @Override
public void sendToAdministrators(Packet packet) {
}
+ @Override
public void sendToClient(Packet packet) {
}
+ @Override
public void sendToJudges(Packet packet) {
}
+ @Override
public void sendToJudgesAndOthers(Packet packet, boolean sendToServers) {
}
+ @Override
public void sendToLocalServer(Packet packet) {
}
+ @Override
public void sendToRemoteServer(int siteNumber, Packet packet) {
}
+ @Override
public void sendToScoreboards(Packet packet) {
}
+ @Override
public void sendToServers(Packet packet) {
}
+ @Override
public void sendToSpectators(Packet packet) {
}
+ @Override
public void sendToTeams(Packet packet) {
}
+ @Override
public void sendValidatingMessage(Run run) {
}
+ @Override
public void setClientAutoShutdown(boolean clientAutoShutdown) {
}
+ @Override
public void setContest(IInternalContest newContest) {
this.contest = newContest;
log = new Log("log", getLogName(contest.getClientId()));
@@ -335,93 +403,127 @@ private String getLogName(ClientId clientId) {
return "mock." + stripChar(clientId.toString(), ' ');
}
+ @Override
public void setContestTime(ContestTime contestTime) {
-
+
}
+ @Override
public void setJudgementList(Judgement[] judgementList) {
}
+ @Override
public void setSecurityLevel(int securityLevel) {
}
+ @Override
public void setSiteNumber(int i) {
}
+ @Override
public void setUsingGUI(boolean usingGUI) {
}
+ @Override
public void showLogWindow(boolean showWindow) {
}
+ @Override
public void shutdownRemoteServers(ClientId requestor) {
}
+ @Override
public void shutdownServer(ClientId requestor) {
}
+ @Override
public void shutdownServer(ClientId requestor, int siteNumber) {
}
+ @Override
public void shutdownTransport() {
}
+ @Override
public void start(String[] stringArray) {
}
+ @Override
public void startAllContestTimes() {
}
+ @Override
public void startContest(int inSiteNumber) {
}
+ @Override
public ILogWindow startLogWindow(IInternalContest contest) {
return null;
}
+ @Override
public void startMainUI(ClientId clientId) {
}
+ @Override
public void startPlayback(PlaybackInfo playbackInfo) {
}
+ @Override
public void stopAllContestTimes() {
}
+ @Override
public void stopContest(int inSiteNumber) {
}
+ @Override
public void submitClarification(Problem problem, String question) {
}
+ @Override
public void submitClarificationAnswer(Clarification clarification) {
}
+ @Override
public void submitJudgeRun(Problem problem, Language language, String filename, SerializedFile[] otherFiles) throws Exception {
submitJudgeRun(problem, language, filename, otherFiles, 0, 0);
}
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles, boolean overrideStopOnFailure) throws Exception {
+ submitJudgeRun(problem, language, mainFileName, otherFiles, 0, 0, overrideStopOnFailure);
+ }
+
+ @Override
public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] auxFileList, long overrideSubmissionTimeMS, long overrideRunId) throws Exception {
-
+ submitJudgeRun(problem, language, mainFileName, auxFileList, overrideSubmissionTimeMS, overrideRunId, false);
+ }
+
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception {
+
Run submittedRun = new Run(contest.getClientId(), language, problem);
+ submittedRun.setOverrideStopOnFailure(overrideStopOnFailure);
submittedRun.setOverRideElapsedTimeMS(overrideSubmissionTimeMS);
submittedRun.setOverRideNumber(new Long(overrideRunId).intValue());
RunFiles runFiles = new RunFiles(submittedRun, mainFileName);
@@ -433,120 +535,148 @@ public void submitJudgeRun(Problem problem, Language language, SerializedFile ma
String mainFileName = mainFile.getName();
submitJudgeRun(problem, language, mainFileName, otherFiles, overrideSubmissionTimeMS, overrideRunId);
}
-
+
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception {
+ String mainFileName = mainFile.getName();
+ submitJudgeRun(problem, language, mainFileName, otherFiles, overrideSubmissionTimeMS, overrideRunId, overrideStopOnFailure);
+ }
+
+ @Override
public void submitRunJudgement(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles) {
}
+ @Override
public void switchProfile(Profile currentProfile, Profile switchToProfile, String contestPassword) {
}
+ @Override
public void syncProfileSubmissions(Profile profile) {
}
+ @Override
public void updateAccount(Account account) {
}
+ @Override
public void updateAccounts(Account[] account) {
}
+ @Override
public void updateBalloonSettings(BalloonSettings newBalloonSettings) {
}
+ @Override
public void updateCategories(Category[] categories) {
}
+ @Override
public void updateCategory(Category newCategory) {
}
+ @Override
public void updateClientSettings(ClientSettings clientSettings) {
}
+ @Override
public void updateContestController(IInternalContest inContest, IInternalController inController) {
}
+ @Override
public void updateContestInformation(ContestInformation contestInformation) {
}
+ @Override
public void updateContestTime(ContestTime newContestTime) {
}
+ @Override
public void updateFinalizeData(FinalizeData data) {
}
+ @Override
public void updateGroup(Group group) {
}
+ @Override
public void updateJudgement(Judgement newJudgement) {
}
+ @Override
public void updateLanguage(Language language) {
}
+ @Override
public void updateProblem(Problem problem) {
}
+ @Override
public void updateProblem(Problem problem, ProblemDataFiles problemDataFiles) {
}
+ @Override
public void updateProfile(Profile profile) {
}
+ @Override
public void updateRun(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles) {
}
+ @Override
public void updateSite(Site newSite) {
}
@Override
public void setConnectionManager(ITransportManager connectionManager) {
-
+
}
@Override
public void addNewLanguages(Language[] languages) {
-
+
}
@Override
public void updateLanguages(Language[] languages) {
-
+
}
@Override
public void addNewGroups(Group[] groups) {
-
+
}
@Override
public void updateGroups(Group[] groups) {
-
+
}
/**
* Creates an {@link AutoStarter} if none exists, and then instructs the AutoStarter to update its Scheduled Start Task to correspond to the Scheduled Start Time information in the
* {@link ContestInformation} object in the received {@link IInternalContest}.
- *
+ *
* @param theContest
* - the Contest (Model) containing the Scheduled Start Time information
* @param theController
@@ -565,12 +695,12 @@ public IInternalContest getContest() {
@Override
public void submitRun(ClientId submitter, Problem problem, Language language, SerializedFile mainSubmissionFile, SerializedFile[] additionalFiles, long overrideTimeMS, long overrideRunId) {
System.out.println("submitRun "+submitter+" "+problem+" "+language+" " +mainSubmissionFile.getName()+" aux file count "+additionalFiles.length+" time ="+overrideTimeMS+" run id ="+overrideRunId);
-
+
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Run run = new Run(submitter, language, problem);
try {
-
+
RunFiles runFiles = new RunFiles(run, mainSubmissionFile, additionalFiles);
Packet packet = PacketFactory.createSubmittedRun(contest.getClientId(), serverClientId, run, runFiles, overrideTimeMS, overrideRunId);
handler.handlePacket(packet, null);
@@ -579,19 +709,19 @@ public void submitRun(ClientId submitter, Problem problem, Language language, Se
rethrow (e);
}
// sendToLocalServer(packet);
-
+
}
@Override
public void submitRun(ClientId submitter, Problem problem, Language language, String entry_point, SerializedFile mainSubmissionFile, SerializedFile[] additionalFiles, long overrideTimeMS, long overrideRunId) {
System.out.println("submitRun "+submitter+" "+problem+" "+language+" " +mainSubmissionFile.getName()+" aux file count "+additionalFiles.length+" entry_point ="+entry_point+" time ="+overrideTimeMS+" run id ="+overrideRunId);
-
+
ClientId serverClientId = new ClientId(contest.getSiteNumber(), Type.SERVER, 0);
Run run = new Run(submitter, language, problem);
run.setEntryPoint(entry_point);
-
+
try {
-
+
RunFiles runFiles = new RunFiles(run, mainSubmissionFile, additionalFiles);
Packet packet = PacketFactory.createSubmittedRun(contest.getClientId(), serverClientId, run, runFiles, overrideTimeMS, overrideRunId);
handler.handlePacket(packet, null);
@@ -604,7 +734,7 @@ public void submitRun(ClientId submitter, Problem problem, Language language, St
private void rethrow(Exception e) {
throw new RuntimeException(e);
}
-
+
protected String stripChar(String s, char ch) {
int idx = s.indexOf(ch);
while (idx > -1) {
diff --git a/src/edu/csus/ecs/pc2/core/NullController.java b/src/edu/csus/ecs/pc2/core/NullController.java
index 46d4050e9..9c8b3fb3c 100644
--- a/src/edu/csus/ecs/pc2/core/NullController.java
+++ b/src/edu/csus/ecs/pc2/core/NullController.java
@@ -39,9 +39,9 @@
/**
* Null Controller, does nothing, nada, zip.
- *
+ *
* A skeleton implementation of the IInternalController.
- *
+ *
* @author pc2@ecs.csus.edu
* @version $Id$
*/
@@ -49,479 +49,605 @@
// $HeadURL$
public class NullController implements IInternalController {
+ @Override
public void addNewAccount(Account account) {
}
+ @Override
public void addNewAccounts(Account[] account) {
}
+ @Override
public void addNewBalloonSettings(BalloonSettings newBalloonSettings) {
}
+ @Override
public void addNewCategory(Category newCategory) {
}
+ @Override
public void addNewClientSettings(ClientSettings newClientSettings) {
}
+ @Override
public void addNewGroup(Group group) {
}
+ @Override
public void addNewJudgement(Judgement judgement) {
}
+ @Override
public void addNewLanguage(Language language) {
}
+ @Override
public void addNewProblem(Problem problem, ProblemDataFiles problemDataFiles) {
}
+ @Override
public void addNewProblem(Problem[] problem, ProblemDataFiles[] problemDataFiles) {
}
+ @Override
public void addNewSite(Site site) {
}
+ @Override
public void addPacketListener(IPacketListener packetListener) {
}
+ @Override
public void addProblem(Problem problem) {
}
+ @Override
public void autoRegister(String teamInformation) {
}
+ @Override
public void cancelClarification(Clarification clarification) {
}
+ @Override
public void cancelRun(Run run) {
}
+ @Override
public void checkOutClarification(Clarification clarification, boolean readOnly) {
}
+ @Override
public void checkOutRejudgeRun(Run theRun) {
}
+ @Override
public void checkOutRun(Run run, boolean readOnly, boolean computerJudge) {
}
+ @Override
public IInternalContest clientLogin(IInternalContest internalContest, String loginName, String password) throws Exception {
return null;
}
+ @Override
public void cloneProfile(Profile profile, ProfileCloneSettings settings, boolean switchNow) {
}
+ @Override
public void fetchRun(Run run) throws IOException, ClassNotFoundException, FileSecurityException {
}
+ @Override
public void forceConnectionDrop(ConnectionHandlerID connectionHandlerID) {
}
+ @Override
public void generateNewAccounts(String clientTypeName, int count, int startNumber, boolean active) {
}
+ @Override
public void generateNewAccounts(String clientTypeName, int siteNumber, int count, int startNumber, boolean active) {
}
+ @Override
public String getHostContacted() {
return null;
}
+ @Override
public Log getLog() {
return null;
}
+ @Override
public UIPlugin[] getPluginList() {
return null;
}
+ @Override
public int getPortContacted() {
return 0;
}
+ @Override
public ProblemDataFiles getProblemDataFiles(Problem problem) {
return null;
}
+ @Override
public int getSecurityLevel() {
return 0;
}
+ @Override
public void incomingPacket(Packet packet) {
}
+ @Override
public void initializeServer(IInternalContest contest) throws IOException, ClassNotFoundException, FileSecurityException {
}
+ @Override
public void initializeStorage(IStorage storage) {
}
+ @Override
public boolean isClientAutoShutdown() {
return false;
}
+ @Override
public boolean isLogWindowVisible() {
return false;
}
+ @Override
public boolean isUsingGUI() {
return false;
}
+ @Override
public void login(String loginName, String password) {
}
+ @Override
public void logoffUser(ClientId clientId) {
}
+ @Override
public void logWarning(String string, Exception e) {
}
+ @Override
public void outgoingPacket(Packet packet) {
}
+ @Override
public void register(UIPlugin plugin) {
}
+ @Override
public void removeConnection(ConnectionHandlerID connectionHandlerID) {
}
+ @Override
public void removeJudgement(Judgement judgement) {
}
+ @Override
public void removeLogin(ClientId clientId) {
}
+ @Override
public void removePacketListener(IPacketListener packetListener) {
}
+ @Override
public void requestChangePassword(String oldPassword, String newPassword) {
}
+ @Override
public void resetContest(ClientId clientResettingContest, boolean eraseProblems, boolean eraseLanguages) {
}
+ @Override
public void sendCompilingMessage(Run run) {
}
+ @Override
public void sendExecutingMessage(Run run) {
}
+ @Override
public void sendRunToSubmissionInterface(Run run, RunFiles runFiles) {
}
+ @Override
public void sendSecurityMessage(String event, String message, ContestSecurityException contestSecurityException) {
}
+ @Override
public void sendServerLoginRequest(int inSiteNumber) throws Exception {
}
+ @Override
public void sendShutdownAllSites() {
}
+ @Override
public void sendShutdownSite(int siteNumber) {
}
+ @Override
public void sendToAdministrators(Packet packet) {
}
+ @Override
public void sendToClient(Packet packet) {
}
+ @Override
public void sendToJudges(Packet packet) {
}
+ @Override
public void sendToJudgesAndOthers(Packet packet, boolean sendToServers) {
}
+ @Override
public void sendToLocalServer(Packet packet) {
}
+ @Override
public void sendToRemoteServer(int siteNumber, Packet packet) {
}
+ @Override
public void sendToScoreboards(Packet packet) {
}
+ @Override
public void sendToServers(Packet packet) {
}
+ @Override
public void sendToSpectators(Packet packet) {
}
+ @Override
public void sendToTeams(Packet packet) {
}
+ @Override
public void sendValidatingMessage(Run run) {
}
+ @Override
public void setClientAutoShutdown(boolean clientAutoShutdown) {
}
+ @Override
public void setContest(IInternalContest newContest) {
}
+ @Override
public void setContestTime(ContestTime contestTime) {
}
+ @Override
public void setJudgementList(Judgement[] judgementList) {
}
+ @Override
public void setSecurityLevel(int securityLevel) {
}
+ @Override
public void setSiteNumber(int i) {
}
+ @Override
public void setUsingGUI(boolean usingGUI) {
}
+ @Override
public void showLogWindow(boolean showWindow) {
}
+ @Override
public void shutdownRemoteServers(ClientId requestor) {
}
+ @Override
public void shutdownServer(ClientId requestor) {
}
+ @Override
public void shutdownServer(ClientId requestor, int siteNumber) {
}
+ @Override
public void shutdownTransport() {
}
+ @Override
public void start(String[] stringArray) {
}
+ @Override
public void startAllContestTimes() {
}
+ @Override
public void startContest(int inSiteNumber) {
}
+ @Override
public ILogWindow startLogWindow(IInternalContest contest) {
return null;
}
+ @Override
public void startMainUI(ClientId clientId) {
}
+ @Override
public void startPlayback(PlaybackInfo playbackInfo) {
}
+ @Override
public void stopAllContestTimes() {
}
+ @Override
public void stopContest(int inSiteNumber) {
}
+ @Override
public void submitClarification(Problem problem, String question) {
}
+ @Override
public void submitClarificationAnswer(Clarification clarification) {
}
+ @Override
public void submitJudgeRun(Problem problem, Language language, String filename, SerializedFile[] otherFiles) throws Exception {
}
+ @Override
public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] auxFileList, long overrideSubmissionTimeMS, long overrideRunId) throws Exception {
}
+ @Override
public void submitRunJudgement(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles) {
}
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles, boolean overrideStopOnFailure) throws Exception {
+
+ }
+
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, String mainFileName, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception {
+
+ }
+
+ @Override
+ public void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles,
+ long overrideSubmissionTimeMS, long overrideRunId, boolean overrideStopOnFailure) throws Exception {
+ }
+ @Override
public void switchProfile(Profile currentProfile, Profile switchToProfile, String contestPassword) {
}
+ @Override
public void syncProfileSubmissions(Profile profile) {
}
+ @Override
public void updateAccount(Account account) {
}
+ @Override
public void updateAccounts(Account[] account) {
}
+ @Override
public void updateBalloonSettings(BalloonSettings newBalloonSettings) {
}
+ @Override
public void updateCategories(Category[] categories) {
}
+ @Override
public void updateCategory(Category newCategory) {
}
+ @Override
public void updateClientSettings(ClientSettings clientSettings) {
}
+ @Override
public void updateContestController(IInternalContest inContest, IInternalController inController) {
}
+ @Override
public void updateContestInformation(ContestInformation contestInformation) {
}
+ @Override
public void updateContestTime(ContestTime newContestTime) {
}
+ @Override
public void updateFinalizeData(FinalizeData data) {
}
+ @Override
public void updateGroup(Group group) {
}
+ @Override
public void updateJudgement(Judgement newJudgement) {
}
+ @Override
public void updateLanguage(Language language) {
}
+ @Override
public void updateProblem(Problem problem) {
}
+ @Override
public void updateProblem(Problem problem, ProblemDataFiles problemDataFiles) {
}
+ @Override
public void updateProfile(Profile profile) {
}
+ @Override
public void updateRun(Run run, JudgementRecord judgementRecord, RunResultFiles runResultFiles) {
}
+ @Override
public void updateSite(Site newSite) {
}
@Override
public void setConnectionManager(ITransportManager connectionManager) {
-
+
}
@Override
public void addNewLanguages(Language[] languages) {
-
+
}
@Override
public void updateLanguages(Language[] languages) {
-
+
}
@Override
public void addNewGroups(Group[] groups) {
-
+
}
@Override
public void updateGroups(Group[] groups) {
-
+
}
/**
* Creates an {@link AutoStarter} if none exists, and then instructs the AutoStarter to update its Scheduled Start Task to correspond to the Scheduled Start Time information in the
* {@link ContestInformation} object in the received {@link IInternalContest}.
- *
+ *
* @param theContest
* - the Contest (Model) containing the Scheduled Start Time information
* @param theController
@@ -539,17 +665,17 @@ public IInternalContest getContest() {
@Override
public void submitRun(ClientId submitter, Problem problem, Language language, SerializedFile mainSubmissionFile, SerializedFile[] additionalFiles, long overrideTimeMS, long overrideRunId) {
-
+
}
@Override
public void submitRun(ClientId submitter, Problem problem, Language language, String entry_point, SerializedFile mainSubmissionFile, SerializedFile[] additionalFiles, long overrideTimeMS, long overrideRunId) {
-
+
}
@Override
public void submitJudgeRun(Problem problem, Language language, SerializedFile mainFile, SerializedFile[] otherFiles, long overrideSubmissionTimeMS, long overrideRunId) throws Exception {
-
+
}
@Override
diff --git a/src/edu/csus/ecs/pc2/core/PacketHandler.java b/src/edu/csus/ecs/pc2/core/PacketHandler.java
index 4fe1b8840..7e0c76679 100644
--- a/src/edu/csus/ecs/pc2/core/PacketHandler.java
+++ b/src/edu/csus/ecs/pc2/core/PacketHandler.java
@@ -1561,6 +1561,8 @@ private void runSubmission(Packet packet, ClientId fromId, ConnectionHandlerID c
}
}
+ Boolean overrideStopOnFailure = (Boolean) PacketFactory.getObjectValue(packet, PacketFactory.OVERRIDE_STOP_ON_FAILURE);
+
ClientId submitter = submittedRun.getSubmitter();
boolean proxySubmission = ! submitter.equals(fromId);
@@ -1589,6 +1591,7 @@ private void runSubmission(Packet packet, ClientId fromId, ConnectionHandlerID c
}
Run run = contest.acceptRun(submittedRun, runFiles);
+ boolean updateRun = false;
/**
* There are three conditions where a run would be added to the system but not appear on the scoreboard (or team's display):
@@ -1600,6 +1603,14 @@ private void runSubmission(Packet packet, ClientId fromId, ConnectionHandlerID c
if (contestTime.isPastEndOfContest() || !contestTime.isContestRunning() || submittedRun.getOverRideElapsedTimeMS() > contestTime.getContestLengthMS()) {
run.setDeleted(true);
submittedRun.setDeleted(true);
+ updateRun = true;
+ }
+
+ if(overrideStopOnFailure != null && overrideStopOnFailure.booleanValue() == true) {
+ run.setOverrideStopOnFailure(true);
+ updateRun = true;
+ }
+ if(updateRun) {
contest.updateRun(run, getServerClientId());
}
diff --git a/src/edu/csus/ecs/pc2/core/execute/Executable.java b/src/edu/csus/ecs/pc2/core/execute/Executable.java
index 630857363..9d3ef1827 100644
--- a/src/edu/csus/ecs/pc2/core/execute/Executable.java
+++ b/src/edu/csus/ecs/pc2/core/execute/Executable.java
@@ -510,6 +510,13 @@ public IFileViewer execute(boolean clearDirFirst) {
//problem indicates stop-on-first-failure
boolean stopOnFirstFailedTestCase = problem.isStopOnFirstFailedTestCase();
+ // if we should override the overrideStopOnFailure, the unset our local flag. Also clear the
+ // run's copy of the flag since this is a one-shot flag. We do not wantto overrideStopOnFailure if
+ // the run is rejudged, for example.
+ if(run.isOverrideStopOnFailure()) {
+ stopOnFirstFailedTestCase = false;
+ run.setOverrideStopOnFailure(false);
+ }
if (dataFiles == null || dataFiles.length <= 1) {
diff --git a/src/edu/csus/ecs/pc2/core/list/StringToDoubleComparator.java b/src/edu/csus/ecs/pc2/core/list/StringToDoubleComparator.java
new file mode 100644
index 000000000..8c2036d09
--- /dev/null
+++ b/src/edu/csus/ecs/pc2/core/list/StringToDoubleComparator.java
@@ -0,0 +1,38 @@
+// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
+package edu.csus.ecs.pc2.core.list;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Compare the two strings as numbers
+ *
+ * Simply convert to integers and compare
+ *
+ * @version $Id$
+ * @author John Buck
+ */
+
+// $HeadURL$
+// $Id$
+
+public class StringToDoubleComparator implements Comparator, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public int compare(String NumOne, String NumTwo) {
+ double dResult = 0;
+ try {
+ dResult = Double.parseDouble(NumOne) - Double.parseDouble(NumTwo);
+ } catch(Exception exception) {
+ return(NumOne.compareTo(NumTwo));
+ }
+ if(dResult < 0)
+ return(-1);
+ if(dResult > 0) {
+ return(1);
+ }
+ return(0);
+ }
+}
diff --git a/src/edu/csus/ecs/pc2/core/model/Filter.java b/src/edu/csus/ecs/pc2/core/model/Filter.java
index 3b74f3146..639e2e69a 100644
--- a/src/edu/csus/ecs/pc2/core/model/Filter.java
+++ b/src/edu/csus/ecs/pc2/core/model/Filter.java
@@ -2,6 +2,7 @@
package edu.csus.ecs.pc2.core.model;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -183,6 +184,9 @@ public class Filter implements Serializable {
private boolean filteringGroups = false;
+ private HashSet customItemHash = new HashSet();
+ private boolean filteringCustom = false;
+
/**
* filtering for this site only
*/
@@ -1033,6 +1037,21 @@ public ClientType.Type[] getClientTypes() {
return elementIds;
}
+ /**
+ * Get list of custom item objects
+ *
+ * @return list of objects
+ */
+ public ArrayList getCustomList() {
+ ArrayList items = new ArrayList();
+
+ customItemHash.forEach((custItem) -> {
+ items.add(custItem);
+ });
+
+ return items;
+ }
+
public void setUsingRunStatesFilter(boolean turnOn) {
filteringRunStates = turnOn;
}
@@ -1210,6 +1229,32 @@ public void clearClarificationStateList() {
clarificationStateHash = new Hashtable();
}
+ /**
+ *
+ * @param o Object of the string to use to attempt the lookup in the hashset
+ * @return true of the string is in the custom item hashset
+ */
+ public boolean matches(Object o) {
+ if(filteringCustom) {
+ return customItemHash.contains(o.toString());
+ }
+ return(true);
+ }
+
+ /**
+ *
+ * @param o adds the string value of o to the custom item hash
+ */
+ public void addCustomItem(Object o) {
+ customItemHash.add(o.toString());
+ filteringCustom = true;
+ }
+
+ public void clearCustomItems() {
+ customItemHash.clear();
+ filteringCustom = false;
+ }
+
@Override
public String toString() {
@@ -1297,6 +1342,14 @@ public void setFilteringAccounts(boolean filteringAccounts) {
this.filteringAccounts = filteringAccounts;
}
+ public boolean isFilteringCustom() {
+ return filteringCustom;
+ }
+
+ public void setFilteringCustom(boolean filtCustom) {
+ filteringCustom = filtCustom;
+ }
+
public void setFilterOff() {
filterEnabled = false;
}
diff --git a/src/edu/csus/ecs/pc2/core/model/Language.java b/src/edu/csus/ecs/pc2/core/model/Language.java
index d33455fad..d88409c3b 100644
--- a/src/edu/csus/ecs/pc2/core/model/Language.java
+++ b/src/edu/csus/ecs/pc2/core/model/Language.java
@@ -1,6 +1,8 @@
// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
package edu.csus.ecs.pc2.core.model;
+import java.util.ArrayList;
+
import edu.csus.ecs.pc2.core.StringUtilities;
import edu.csus.ecs.pc2.core.log.StaticLog;
@@ -27,10 +29,15 @@ public class Language implements IElementObject {
* ICPC contests. JB 03/20/2024
*/
public static final String CLICS_LANGID_JAVA = "java";
+ private static final String [] DEFAULT_EXT_JAVA = { "java" };
public static final String CLICS_LANGID_KOTLIN = "kotlin";
+ private static final String [] DEFAULT_EXT_KOTLIN = { "kt" };
public static final String CLICS_LANGID_PYTHON3 = "python3";
+ private static final String [] DEFAULT_EXT_PYTHON3 = { "py" };
public static final String CLICS_LANGID_C = "c";
+ private static final String [] DEFAULT_EXT_C = { "c" };
public static final String CLICS_LANGID_CPP = "cpp";
+ private static final String [] DEFAULT_EXT_CPP = { "cc", "cpp", "cxx", "c++" };
/**
* Title for the Language.
@@ -81,6 +88,8 @@ public class Language implements IElementObject {
private String id = "";
+ private ArrayList extensions = new ArrayList();
+
public Language(String displayName) {
super();
this.displayName = displayName;
@@ -236,6 +245,15 @@ public int hashCode() {
return elementId.hashCode();
}
+ /**
+ * Check if extensions array is allocated. If not allocate it. This can happen on deserialization of an older object.
+ */
+ private void checkExtensions() {
+ if(extensions == null) {
+ extensions = new ArrayList();
+ }
+ }
+
public String getExecutableIdentifierMask() {
return executableIdentifierMask;
}
@@ -273,10 +291,71 @@ public boolean isUsingJudgeProgramExecuteCommandLine() {
}
public void setID(String newId) {
- this.id = newId;
+ id = newId;
+ checkExtensions();
+ // set default extensions for the language based on its CLICS id
+ if(extensions.isEmpty()) {
+ String [] ext = null;
+ if(newId.equals(CLICS_LANGID_C)) {
+ ext = DEFAULT_EXT_C;
+ } else if(newId.equals(CLICS_LANGID_CPP)) {
+ ext = DEFAULT_EXT_CPP;
+ } else if(newId.equals(CLICS_LANGID_PYTHON3)) {
+ ext = DEFAULT_EXT_PYTHON3;
+ } else if(newId.equals(CLICS_LANGID_JAVA)) {
+ ext = DEFAULT_EXT_JAVA;
+ } else if(newId.equals(CLICS_LANGID_KOTLIN)) {
+ ext = DEFAULT_EXT_KOTLIN;
+ }
+ if(ext != null) {
+ copyExtensions(ext);
+ }
+ }
}
public String getID() {
return id;
}
+
+ public void setExtensions(ArrayList exts) {
+ checkExtensions();
+ extensions.clear();
+ extensions.addAll(exts);
+ }
+
+ public ArrayList getExtensions() {
+ checkExtensions();
+ if(extensions.isEmpty()) {
+ setDefaultExtensions();
+ }
+ return(extensions);
+ }
+
+ /**
+ * In the event the user did not specify a CLICS ID for the language, we have to make a guess.
+ * We use is the lower-case display name, minus spaces, and + changed to p, and compare to our known
+ * list of CLICS ids.
+ */
+ private void setDefaultExtensions()
+ {
+ // Make lower case, get rid of spaces and convert all plus signs to p's (eg c++ -> cpp)
+ String fauxId = getDisplayName().toLowerCase().replaceAll("\\s", "").replaceAll("\\+", "p");
+ // Let's use it as the clics ID
+ setID(fauxId);
+ // if it didn't work, then pretend we didn't try.
+ if(extensions.isEmpty()) {
+ id = null;
+ }
+ }
+
+ /**
+ * Utility method to convert between a string array and ArrayList
+ *
+ * @param exts array of strings to convert
+ */
+ private void copyExtensions(String [] exts) {
+ for(String ext : exts) {
+ extensions.add(ext);
+ }
+ }
}
diff --git a/src/edu/csus/ecs/pc2/core/model/Run.java b/src/edu/csus/ecs/pc2/core/model/Run.java
index ebb71313d..57eff8582 100644
--- a/src/edu/csus/ecs/pc2/core/model/Run.java
+++ b/src/edu/csus/ecs/pc2/core/model/Run.java
@@ -111,6 +111,8 @@ public enum RunStates {
private int overrideNumber = 0;
+ private boolean overrideStopOnFailure = false;
+
/**
* Short/basename for submitted file.
*/
@@ -484,4 +486,22 @@ public String getEntryPoint(){
return null;
}
+
+ /**
+ * Sets the "one-shot" flag to override the stop on failure for a problem
+ * This is used for submitting sample judge runs.
+ *
+ * @param override true to override stop on failure, otherwise it uses the value for the problem
+ */
+ public void setOverrideStopOnFailure(boolean override) {
+ overrideStopOnFailure = override;
+ }
+
+ /**
+ *
+ * @return if we should override the stop on failure set for a problem
+ */
+ public boolean isOverrideStopOnFailure() {
+ return overrideStopOnFailure;
+ }
}
diff --git a/src/edu/csus/ecs/pc2/core/packet/PacketFactory.java b/src/edu/csus/ecs/pc2/core/packet/PacketFactory.java
index 00a5ef332..f6fd31700 100644
--- a/src/edu/csus/ecs/pc2/core/packet/PacketFactory.java
+++ b/src/edu/csus/ecs/pc2/core/packet/PacketFactory.java
@@ -1,4 +1,4 @@
-// Copyright (C) 1989-2019 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
+// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
package edu.csus.ecs.pc2.core.packet;
import java.io.PrintStream;
@@ -48,7 +48,7 @@
/**
* Creates {@link Packet}s.
- *
+ *
* Each packet can be created by using a method in this class. There is a "create" method for each {@link Type}.
* There are also some methods to extract fields/classes from packets.
*
@@ -56,13 +56,13 @@
*
* Constants are present in this class that are used to extract individual contents from a packet.
* Example of extracting individual contents from a packet {@link edu.csus.ecs.pc2.core.packet.Packet}.
- *
+ *
*