package org.scribble.codegen.java.endpointapi; import org.scribble.ast.MessageSigNameDecl; import org.scribble.ast.Module; import org.scribble.codegen.java.util.AbstractMethodBuilder; import org.scribble.codegen.java.util.ClassBuilder; import org.scribble.codegen.java.util.InterfaceBuilder; import org.scribble.codegen.java.util.JavaBuilder; import org.scribble.codegen.java.util.MethodBuilder; import org.scribble.main.ScribbleException; import org.scribble.model.endpoint.EState; import org.scribble.model.endpoint.actions.EAction; import org.scribble.sesstype.name.GProtocolName; import org.scribble.sesstype.name.MessageSigName; // Factor out public class HandlerInterfaceGenerator extends AuxStateChannelTypeGenerator { private final EState curr; // Pre: cb is the BranchSocketBuilder public HandlerInterfaceGenerator(StateChannelApiGenerator apigen, ClassBuilder parent, EState curr) { super(apigen, parent); this.curr = curr; } @Override public InterfaceBuilder generateType() throws ScribbleException { GProtocolName gpn = this.apigen.getGProtocolName(); // Handler interface InterfaceBuilder ib = new InterfaceBuilder(); ib.setPackage(SessionApiGenerator.getStateChannelPackageName(gpn, this.apigen.getSelf())); // FIXME: factor out with ScribSocketBuilder ib.addImports(SessionApiGenerator.getOpsPackageName(gpn) + ".*"); // FIXME: factor out with ScribSocketBuilder //ib.setName(getHandlerInterfaceName(parent)); ib.setName(getHandlerInterfaceName(this.parent.getName())); ib.addModifiers(InterfaceBuilder.PUBLIC); for (EAction a : this.curr.getActions()) // Doesn't need to be sorted { EState succ = this.curr.getSuccessor(a); String nextClass = this.apigen.getSocketClassName(succ); AbstractMethodBuilder mb3 = ib.newAbstractMethod(); if (!this.apigen.skipIOInterfacesGeneration) { mb3.addAnnotations("@Override"); } setHandleMethodHeaderWithoutParamTypes(this.apigen, mb3); if (succ.isTerminal()) { mb3.addParameters(ScribSocketGenerator.GENERATED_ENDSOCKET_NAME + " schan"); // FIXME: factor out } else { mb3.addParameters(nextClass + " schan"); // FIXME: factor out } addHandleMethodOpAndPayloadParams(this.apigen, a, mb3); if (this.curr.getSuccessor(a).isTerminal()) { // FIXME: potentially repeated (but OK) ib.addImports(SessionApiGenerator.getEndpointApiRootPackageName(gpn) + ".*"); // FIXME: factor out with ScribSocketBuilder ib.addImports(SessionApiGenerator.getRolesPackageName(this.apigen.getGProtocolName()) + ".*"); } } return ib; } // void return type -- have to deal with Succ as param public static void setHandleMethodHeaderWithoutParamTypes(StateChannelApiGenerator apigen, MethodBuilder mb) { mb.setName("receive"); mb.addModifiers(JavaBuilder.PUBLIC); mb.setReturn(InterfaceBuilder.VOID); mb.addExceptions(StateChannelApiGenerator.SCRIBBLERUNTIMEEXCEPTION_CLASS, "java.io.IOException", "ClassNotFoundException"); } public static void addHandleMethodOpAndPayloadParams(StateChannelApiGenerator apigen, EAction a, MethodBuilder mb) throws ScribbleException { Module main = apigen.getMainModule(); String opClass = SessionApiGenerator.getOpClassName(a.mid); mb.addParameters(opClass + " " + StateChannelApiGenerator.RECEIVE_OP_PARAM); // More params added below if (a.mid.isOp()) { ReceiveSocketGenerator.addReceiveOpParams(mb, apigen.getMainModule(), a, false); } else //if (a.mid.isMessageSigName()) { MessageSigNameDecl msd = main.getMessageSigDecl(((MessageSigName) a.mid).getSimpleName()); // FIXME: might not belong to main module ReceiveSocketGenerator.addReceiveMessageSigNameParams(mb, msd, false); } } // Pre: cb is the BranchSocketBuilder //public static String getHandlerInterfaceName(TypeBuilder cb) public static String getHandlerInterfaceName(String branchName) { return branchName + "_Handler"; } }