Java tutorial
/* * * Goko * Copyright (C) 2013 PsyKo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.goko.grbl.controller; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.goko.core.common.GkUtils; import org.goko.core.common.applicative.logging.IApplicativeLogService; import org.goko.core.common.event.EventBrokerUtils; import org.goko.core.common.event.EventDispatcher; import org.goko.core.common.event.EventListener; import org.goko.core.common.exception.GkException; import org.goko.core.common.exception.GkFunctionalException; import org.goko.core.common.measure.quantity.Length; import org.goko.core.common.measure.quantity.Quantity; import org.goko.core.common.measure.quantity.type.BigDecimalQuantity; import org.goko.core.common.measure.units.Unit; import org.goko.core.config.GokoPreference; import org.goko.core.connection.IConnectionService; import org.goko.core.controller.ICoordinateSystemAdapter; import org.goko.core.controller.IThreeAxisControllerAdapter; import org.goko.core.controller.action.IGkControllerAction; import org.goko.core.controller.bean.EnumControllerAxis; import org.goko.core.controller.bean.MachineValue; import org.goko.core.controller.bean.MachineValueDefinition; import org.goko.core.controller.event.MachineValueUpdateEvent; import org.goko.core.gcode.bean.GCodeCommand; import org.goko.core.gcode.bean.GCodeContext; import org.goko.core.gcode.bean.IGCodeProvider; import org.goko.core.gcode.bean.Tuple6b; import org.goko.core.gcode.bean.commands.EnumCoordinateSystem; import org.goko.core.gcode.bean.commands.EnumGCodeCommandDistanceMode; import org.goko.core.gcode.bean.execution.ExecutionQueue; import org.goko.core.gcode.bean.provider.GCodeExecutionToken; import org.goko.core.gcode.service.IGCodeExecutionMonitorService; import org.goko.core.gcode.service.IGCodeService; import org.goko.core.log.GkLog; import org.goko.grbl.controller.bean.GrblExecutionError; import org.goko.grbl.controller.bean.StatusReport; import org.goko.grbl.controller.configuration.GrblConfiguration; import org.goko.grbl.controller.configuration.GrblSetting; import org.goko.grbl.controller.executionqueue.GrblGCodeExecutionToken; import org.goko.grbl.controller.topic.GrblExecutionErrorTopic; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; /** * GRBL v0.8 Controller implementation * * @author PsyKo * */ public class GrblControllerService extends EventDispatcher implements IGrblControllerService, IThreeAxisControllerAdapter, ICoordinateSystemAdapter { /** Service ID */ public static final String SERVICE_ID = "Grbl v0.8 Controller"; /** Log */ private static final GkLog LOG = GkLog.getLogger(GrblControllerService.class); /** GCode service*/ private IGCodeService gcodeService; /** The execution queue */ private ExecutionQueue<GrblGCodeExecutionToken> executionQueue; /** Sending runnable */ private GrblStreamingRunnable grblStreamingRunnable; /** Status polling */ private Timer statusPollingTimer; /** Controller action factory*/ private GrblActionFactory grblActionFactory; /** Grbl used buffer spaces */ private int usedGrblBuffer; /** Grbl configuration */ private GrblConfiguration configuration; /** Applicative log service */ private IApplicativeLogService applicativeLogService; private GrblState grblState; private GrblCommunicator communicator; private IGCodeExecutionMonitorService monitorService; private EventAdmin eventAdmin; /** * Constructor */ public GrblControllerService() { communicator = new GrblCommunicator(this); } /** (inheritDoc) * @see org.goko.core.common.service.IGokoService#getServiceId() */ @Override public String getServiceId() throws GkException { return SERVICE_ID; } /** (inheritDoc) * @see org.goko.core.common.service.IGokoService#start() */ @Override public void start() throws GkException { grblActionFactory = new GrblActionFactory(this); configuration = new GrblConfiguration(); grblState = new GrblState(); grblState.addListener(this); // Initiate execution queue executionQueue = new ExecutionQueue<GrblGCodeExecutionToken>(); ExecutorService executor = Executors.newSingleThreadExecutor(); grblStreamingRunnable = new GrblStreamingRunnable(executionQueue, this); executor.execute(grblStreamingRunnable); } protected void stopStatusPolling() { statusPollingTimer.cancel(); } public void startStatusPolling() { statusPollingTimer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { try { refreshStatus(); } catch (GkException e) { LOG.error(e); } } }; statusPollingTimer.scheduleAtFixedRate(task, new Date(), 100); } /** * @param evt */ @EventListener(MachineValueUpdateEvent.class) public void onMachineValueUpdate(MachineValueUpdateEvent evt) { notifyListeners(evt); } /** (inheritDoc) * @see org.goko.core.common.service.IGokoService#stop() */ @Override public void stop() throws GkException { // TODO Auto-generated method stub } public void sendCommand(GCodeCommand command) throws GkException { List<Byte> byteCommand = GkUtils.toBytesList(getGCodeService().convert(command)); int usedBufferCount = CollectionUtils.size(byteCommand); communicator.send(byteCommand); setUsedGrblBuffer(usedGrblBuffer + usedBufferCount); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getPosition() */ @Override public Tuple6b getPosition() throws GkException { return grblState.getWorkPosition(); } /** (inheritDoc) * @see org.goko.core.controller.IThreeAxisControllerAdapter#getX() */ @Override public Quantity<Length> getX() throws GkException { BigDecimalQuantity<Length> xPos = grblState.getWorkPosition().getX(); return xPos; } /** (inheritDoc) * @see org.goko.core.controller.IThreeAxisControllerAdapter#getY() */ @Override public Quantity<Length> getY() throws GkException { BigDecimalQuantity<Length> yPos = grblState.getWorkPosition().getY(); return yPos; } /** (inheritDoc) * @throws GkException * @see org.goko.core.controller.IThreeAxisControllerAdapter#getZ() */ @Override public Quantity<Length> getZ() throws GkException { BigDecimalQuantity<Length> zPos = grblState.getWorkPosition().getZ(); return zPos; } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#executeGCode(org.goko.core.gcode.bean.IGCodeProvider) */ @Override public GCodeExecutionToken executeGCode(IGCodeProvider gcodeProvider) throws GkException { GrblGCodeExecutionToken token = new GrblGCodeExecutionToken(gcodeProvider); token.setMonitorService(monitorService); // quand on stoppe et relance un fichier, ca fait n'imp executionQueue.add(token); return token; } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#isReadyForFileStreaming() */ @Override public boolean isReadyForFileStreaming() throws GkException { return GrblMachineState.READY.equals(getState()) || GrblMachineState.CHECK.equals(getState()); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getControllerAction(java.lang.String) */ @Override public IGkControllerAction getControllerAction(String actionId) throws GkException { IGkControllerAction action = grblActionFactory.findAction(actionId); if (action == null) { throw new GkFunctionalException( "Action '" + actionId + "' is not supported by this controller (" + getServiceId() + ")"); } return action; } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#isControllerAction(java.lang.String) */ @Override public boolean isControllerAction(String actionId) throws GkException { return grblActionFactory.findAction(actionId) != null; } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getMachineValue(java.lang.String, java.lang.Class) */ @Override public <T> MachineValue<T> getMachineValue(String name, Class<T> clazz) throws GkException { return getGrblState().getValue(name, clazz); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getMachineValueType(java.lang.String) */ @Override public Class<?> getMachineValueType(String name) throws GkException { return getGrblState().getControllerValueType(name); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getMachineValueDefinition() */ @Override public List<MachineValueDefinition> getMachineValueDefinition() throws GkException { return getGrblState().getMachineValueDefinition(); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#findMachineValueDefinition(java.lang.String) */ @Override public MachineValueDefinition findMachineValueDefinition(String id) throws GkException { return getGrblState().findMachineValueDefinition(id); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getMachineValueDefinition(java.lang.String) */ @Override public MachineValueDefinition getMachineValueDefinition(String id) throws GkException { return getGrblState().getMachineValueDefinition(id); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#cancelFileSending() */ @Override public void cancelFileSending() throws GkException { stopMotion(); } /** * @param connectionService the connectionService to set * @throws GkException GkException */ public void setConnectionService(IConnectionService connectionService) throws GkException { this.communicator.setConnectionService(connectionService); } /** * Refresh the status of the remote Grbl controller * @throws GkException GkException */ public void refreshStatus() throws GkException { if (isActivePollingEnabled()) { communicator.sendWithoutEndLineCharacter(GkUtils.toBytesList(Grbl.CURRENT_STATUS)); } } public void refreshSpaceCoordinates() throws GkException { communicator.send(GkUtils.toBytesList(Grbl.VIEW_PARAMETERS)); } public void refreshParserState() throws GkException { communicator.send(GkUtils.toBytesList(Grbl.PARSER_STATE)); } public void refreshConfiguration() throws GkException { communicator.send(GkUtils.toBytesList(Grbl.CONFIGURATION)); } protected void handleConfigurationReading(String cofigurationMessage) throws GkException { String identifier = StringUtils.substringBefore(cofigurationMessage, "=").trim(); String value = StringUtils.substringBetween(cofigurationMessage, "=", "(").trim(); configuration.setValue(identifier, value); LOG.info("Updating setting '" + identifier + "' with value '" + value + "'"); } protected void receiveParserState(String parserState) throws GkException { String[] commands = StringUtils.split(parserState, " "); GCodeContext context = new GCodeContext(); if (commands != null) { for (String strCommand : commands) { GCodeCommand command = gcodeService.parseCommand(strCommand, context); gcodeService.update(context, command); } } grblState.setCurrentContext(context); } protected void handleError(String errorMessage) throws GkException { if (executionQueue != null) { GrblGCodeExecutionToken currentToken = executionQueue.getCurrentToken(); String formattedErrorMessage = StringUtils.EMPTY; if (currentToken != null && currentToken.getSentCommandCount() > 0) { // Error occured during GCode programm execution, let's give the source command GCodeCommand command = currentToken.markNextCommandAsError(); formattedErrorMessage = "Error with command '" + command.toString() + "' : " + StringUtils.substringAfter(errorMessage, "error: "); } else { formattedErrorMessage = "Grbl Error : " + StringUtils.substringAfter(errorMessage, "error: "); } LOG.error(formattedErrorMessage); getApplicativeLogService().error(formattedErrorMessage, SERVICE_ID); // If not in check mode, let's pause the execution (disabled in check mode because check mode can't handle paused state and buffer would be flooded with commands) if (!ObjectUtils.equals(GrblMachineState.CHECK, getState())) { pauseMotion(); // Map<String, String> mapArgs = new HashMap<String, String>(); // mapArgs.put(Grbl.Topic.GrblExecutionError.TITLE, "Error reported durring execution"); // mapArgs.put(Grbl.Topic.GrblExecutionError.MESSAGE, "Execution was paused after Grbl reported an error. You can resume, or stop the execution at your own risk."); // mapArgs.put(Grbl.Topic.GrblExecutionError.ERROR, formattedErrorMessage); // eventAdmin.sendEvent(new Event(Grbl.Topic.GrblExecutionError.TOPIC, mapArgs)); EventBrokerUtils.send(eventAdmin, new GrblExecutionErrorTopic(), new GrblExecutionError( "Error reported durring execution", "Execution was paused after Grbl reported an error. You can resume, or stop the execution at your own risk.", formattedErrorMessage)); // Verifier pourquoi l'erreur n'est pas affiche } } else { LOG.error("Grbl Error : " + StringUtils.substringAfter(errorMessage, "error: ")); getApplicativeLogService().error(StringUtils.substringAfter(errorMessage, "error: "), SERVICE_ID); } } protected void handleOkResponse() throws GkException { GrblGCodeExecutionToken currentToken = executionQueue.getCurrentToken(); if (currentToken != null) { GCodeCommand command = currentToken.markNextCommandAsConfirmed(); if (command != null) { String strCommand = new String(getGCodeService().convert(command)); setUsedGrblBuffer(usedGrblBuffer - StringUtils.length(strCommand)); } grblStreamingRunnable.releaseBufferSpaceMutex(); } } protected void initialiseConnectedState() throws GkException { setUsedGrblBuffer(0); refreshConfiguration(); refreshSpaceCoordinates(); refreshParserState(); } protected void handleStatusReport(StatusReport statusReport) throws GkException { GrblMachineState previousState = getState(); grblState.setState(statusReport.getState()); grblState.setMachinePosition(statusReport.getMachinePosition(), getConfiguration().getReportUnit()); grblState.setWorkPosition(statusReport.getWorkPosition(), getConfiguration().getReportUnit()); if (!ObjectUtils.equals(previousState, statusReport.getState())) { eventAdmin.sendEvent(new Event(CONTROLLER_TOPIC_STATE_UPDATE, (Map<String, ?>) null)); } } public GrblMachineState getState() throws GkException { return grblState.getState(); } protected GrblMachineState getGrblStateFromString(String code) { switch (code) { case "Alarm": return GrblMachineState.ALARM; case "Idle": return GrblMachineState.READY; case "Queue": return GrblMachineState.MOTION_HOLDING; case "Run": return GrblMachineState.MOTION_RUNNING; case "Home": return GrblMachineState.HOMING; case "Check": return GrblMachineState.CHECK; default: return GrblMachineState.UNDEFINED; } } /* * Action related methods */ public void startHomingSequence() throws GkException { List<Byte> homeCommand = new ArrayList<Byte>(); homeCommand.addAll(GkUtils.toBytesList(Grbl.HOME_COMMAND)); communicator.send(homeCommand); } /** * Pause the motion by sending a pause character to Grbl * If the execution queue is not empty, it is also paused * @throws GkException GkException */ public void pauseMotion() throws GkException { List<Byte> pauseCommand = new ArrayList<Byte>(); pauseCommand.add(Grbl.PAUSE_COMMAND); communicator.sendImmediately(pauseCommand); executionQueue.setPaused(true); } /** * Stop the motion by sending a pause and a flush character to Grbl * If the execution queue is not empty, it is also stopped and emptied * @throws GkException GkException */ public void stopMotion() throws GkException { List<Byte> stopCommand = new ArrayList<Byte>(); stopCommand.add(Grbl.PAUSE_COMMAND); stopCommand.add(Grbl.RESET_COMMAND); // TODO : it seems that resetting while in motion causes the GRBL to go back to alarm state. Wait motion to be complete before resetting communicator.sendImmediately(stopCommand); if (executionQueue != null) { executionQueue.clear(); grblStreamingRunnable.releaseBufferSpaceMutex(); } setUsedGrblBuffer(0); } /** * Start the motion by sending a resume character to Grbl * If the execution queue is paused, it is also resumed * @throws GkException GkException */ public void startMotion() throws GkException { List<Byte> startResumeCommand = new ArrayList<Byte>(); startResumeCommand.add(Grbl.RESUME_COMMAND); communicator.sendWithoutEndLineCharacter(startResumeCommand); if (executionQueue != null) { executionQueue.setPaused(false); } } /** (inheritDoc) * @see org.goko.core.controller.IStepJogService#startJog(org.goko.core.controller.bean.EnumControllerAxis, java.math.BigDecimal, java.math.BigDecimal) */ @Override public void startJog(EnumControllerAxis axis, BigDecimal feedrate, BigDecimalQuantity<Length> step) throws GkException { String oldDistanceMode = "G90"; if (grblState.getDistanceMode() == EnumGCodeCommandDistanceMode.RELATIVE) { oldDistanceMode = "G91"; } String command = "G91G1" + axis.getAxisCode(); if (axis.isNegative()) { command += "-"; } command += step.to(getCurrentGCodeContext().getUnit().getUnit()).value(); command += "F" + feedrate; List<Byte> lstBytes = GkUtils.toBytesList(command); communicator.send(lstBytes); List<Byte> distanceModeBackup = GkUtils.toBytesList(oldDistanceMode); communicator.send(distanceModeBackup); } /** (inheritDoc) * @see org.goko.core.controller.IStepJogService#stopJog() */ @Override public void stopJog() throws GkException { // Nothing to do in stop jog since it's a step jog } public void resetZero(List<String> axes) throws GkException { List<Byte> lstBytes = GkUtils.toBytesList("G92"); if (CollectionUtils.isNotEmpty(axes)) { for (String axe : axes) { lstBytes.addAll(GkUtils.toBytesList(axe + "0")); } } else { lstBytes.addAll(GkUtils.toBytesList("X0Y0Z0")); } communicator.send(lstBytes); } public void killAlarm() throws GkException { List<Byte> lstBytes = GkUtils.toBytesList("$X"); communicator.send(lstBytes); } /** * @return the usedGrblBuffer * @throws GkException GkException */ public int getUsedGrblBuffer() throws GkException { return grblState.getUsedGrblBuffer(); } /** * @param usedGrblBuffer the usedGrblBuffer to set * @throws GkException GkException */ public void setUsedGrblBuffer(int usedGrblBuffer) throws GkException { this.usedGrblBuffer = usedGrblBuffer; grblState.setUsedGrblBuffer(usedGrblBuffer); } /** * @return the configuration */ @Override public GrblConfiguration getConfiguration() { return configuration; } /** * @param configuration the configuration to set * @throws GkException GkException */ @Override public void setConfiguration(GrblConfiguration configuration) throws GkException { this.configuration = configuration; if (CollectionUtils.isNotEmpty(configuration.getLstGrblSetting())) { List<GrblSetting<?>> lstSetting = configuration.getLstGrblSetting(); List<Byte> cfgCommand = new ArrayList<Byte>(); for (GrblSetting<?> grblSetting : lstSetting) { cfgCommand.addAll( GkUtils.toBytesList(grblSetting.getIdentifier() + "=" + grblSetting.getValueAsString())); communicator.send(cfgCommand); cfgCommand.clear(); } } } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#moveToAbsolutePosition(org.goko.core.gcode.bean.Tuple6b) */ @Override public void moveToAbsolutePosition(Tuple6b position) throws GkException { // TODO Auto-generated method stub } /** * @return the gcodeService */ public IGCodeService getGCodeService() { return gcodeService; } /** * @param gcodeService the gcodeService to set */ public void setGCodeService(IGCodeService gcodeService) { this.gcodeService = gcodeService; } /** * @return the applicativeLogService */ public IApplicativeLogService getApplicativeLogService() { return applicativeLogService; } /** * @param applicativeLogService the applicativeLogService to set */ public void setApplicativeLogService(IApplicativeLogService applicativeLogService) { this.applicativeLogService = applicativeLogService; } /** (inheritDoc) * @see org.goko.grbl.controller.IGrblControllerService#getGrblState() */ @Override public GrblState getGrblState() { return grblState; } protected void setOffsetCoordinate(String offsetIdentifier, Tuple6b value) throws GkException { getGrblState().setOffset(EnumCoordinateSystem.valueOf(offsetIdentifier), value); } /** (inheritDoc) * @see org.goko.core.controller.IControllerService#getCurrentGCodeContext() */ @Override public GCodeContext getCurrentGCodeContext() throws GkException { return grblState.getCurrentContext(); } /** (inheritDoc) * @see org.goko.core.controller.ICoordinateSystemAdapter#getCoordinateSystemOffset(org.goko.core.gcode.bean.commands.EnumCoordinateSystem) */ @Override public Tuple6b getCoordinateSystemOffset(EnumCoordinateSystem cs) throws GkException { return grblState.getOffset(cs); } /** (inheritDoc) * @see org.goko.core.controller.ICoordinateSystemAdapter#getCoordinateSystem() */ @Override public List<EnumCoordinateSystem> getCoordinateSystem() throws GkException { return new ArrayList<EnumCoordinateSystem>(Arrays.asList(EnumCoordinateSystem.values())); } /** (inheritDoc) * @see org.goko.core.controller.ICoordinateSystemAdapter#getCurrentCoordinateSystem() */ @Override public EnumCoordinateSystem getCurrentCoordinateSystem() throws GkException { return grblState.getCurrentContext().getCoordinateSystem(); } /** (inheritDoc) * @see org.goko.core.controller.ICoordinateSystemAdapter#setCurrentCoordinateSystem(org.goko.core.gcode.bean.commands.EnumCoordinateSystem) */ @Override public void setCurrentCoordinateSystem(EnumCoordinateSystem cs) throws GkException { communicator.send(GkUtils.toBytesList(String.valueOf(cs))); communicator.send(GkUtils.toBytesList("$G")); } /** (inheritDoc) * @see org.goko.core.controller.ICoordinateSystemAdapter#resetCurrentCoordinateSystem() */ @Override public void resetCurrentCoordinateSystem() throws GkException { EnumCoordinateSystem cs = getGrblState().getCurrentContext().getCoordinateSystem(); String cmd = "G10"; switch (cs) { case G54: cmd += "P1"; break; case G55: cmd += "P2"; break; case G56: cmd += "P3"; break; case G57: cmd += "P4"; break; case G58: cmd += "P5"; break; case G59: cmd += "P6"; break; default: throw new GkFunctionalException("GRBL-002", cs.name()); } Tuple6b offsets = getCoordinateSystemOffset(getCurrentCoordinateSystem()); Tuple6b mPos = new Tuple6b(getPosition()); mPos = mPos.add(offsets); cmd += "L2"; cmd += "X" + getPositionAsString(mPos.getX()); cmd += "Y" + getPositionAsString(mPos.getY()); cmd += "Z" + getPositionAsString(mPos.getZ()); communicator.send(GkUtils.toBytesList(cmd)); communicator.send(GkUtils.toBytesList(Grbl.VIEW_PARAMETERS)); } /** * Returns the given Length quantity as a String, formatted using the goko preferences for decimal numbers * @param q the quantity to format * @return a String * @throws GkException GkException */ protected String getPositionAsString(BigDecimalQuantity<Length> q) throws GkException { return GokoPreference.getInstance().format(q.to(getCurrentUnit()), true, false); } /** * Returns the current unit in the Grbl Conteext. It can be different from the unit in the goko preferences * @return Unit */ private Unit<Length> getCurrentUnit() { return grblState.getContextUnit().getUnit(); } /** (inheritDoc) * @see org.goko.grbl.controller.IGrblControllerService#setActivePollingEnabled(boolean) */ @Override public void setActivePollingEnabled(boolean enabled) throws GkException { grblState.setActivePolling(enabled); } /** (inheritDoc) * @see org.goko.grbl.controller.IGrblControllerService#isActivePollingEnabled() */ @Override public boolean isActivePollingEnabled() throws GkException { return grblState.isActivePolling(); } /** (inheritDoc) * @see org.goko.grbl.controller.IGrblControllerService#setCheckModeEnabled(boolean) */ @Override public void setCheckModeEnabled(boolean enabled) throws GkException { if ((enabled && ObjectUtils.equals(GrblMachineState.READY, getState())) || // Check mode is disabled and we want to enable it (!enabled && ObjectUtils.equals(GrblMachineState.CHECK, getState()))) { // Check mode is enabled and we want to disable it communicator.send(GkUtils.toBytesList(Grbl.CHECK_MODE)); } else { throw new GkFunctionalException("GRBL-001", String.valueOf(enabled), getState().getLabel()); } } /** * @return the eventAdmin */ protected EventAdmin getEventAdmin() { return eventAdmin; } /** * @param eventAdmin the eventAdmin to set */ protected void setEventAdmin(EventAdmin eventAdmin) { this.eventAdmin = eventAdmin; } /** * @return the monitorService */ protected IGCodeExecutionMonitorService getMonitorService() { return monitorService; } /** * @param monitorService the monitorService to set */ protected void setMonitorService(IGCodeExecutionMonitorService monitorService) { this.monitorService = monitorService; } }