예제 #1
0
  /**
   * Create inner builder class, that is used within the child worker thread classes to create new
   * thread objects at runtime. The code that is generated by this method, makes use of the
   * Singleton and the Builder design pattern.
   *
   * @param workerThreadClassName Name of outer worker thread class
   * @return JClass object with inner builder class
   * @throws Exception Error during code generation
   */
  private JClass createInnerBuilderClass(final String workerThreadClassName) throws Exception {
    String builderClassName = workerThreadClassName + "Builder";

    // Create inner builder class
    JClass builderClass =
        JClass.factory.create(
            JModifier.PUBLIC | JModifier.STATIC | JModifier.FINAL, builderClassName);
    builderClass.setComment(
        new JClassCommentImpl(String.format("Inner '%s' class.", builderClassName)));

    LOGGER.debug(
        String.format(
            "Created '%s' class as inner class of '%s'.", builderClassName, workerThreadClassName));

    /**
     * *************************************************************** Create fields
     * ***************************************************************
     */
    JField instance =
        JField.factory.create(JModifier.PRIVATE | JModifier.STATIC, builderClassName, "instance");
    instance.setComment(new JFieldCommentImpl("Builder instance for Singleton pattern"));
    builderClass.add(instance);

    JField request = JField.factory.create(JModifier.PRIVATE, this.messageClassFullName, "request");
    builderClass.add(request);

    JField serviceProvider =
        JField.factory.create(JModifier.PRIVATE, this.serviceProviderClassName, "serviceProvider");
    builderClass.add(serviceProvider);

    JField webSocket = JField.factory.create(JModifier.PRIVATE, "WebSocket", "webSocket");
    builderClass.add(webSocket);

    /**
     * *************************************************************** Create constructor
     * ***************************************************************
     */
    JConstructor constructor = JConstructor.factory.create(JModifier.PRIVATE, builderClassName);
    constructor.setComment(
        new JConstructorCommentImpl("Private constructor for Singleton pattern."));

    // Set method body
    String methodBody = String.format("this.request = new %s();", this.messageClassFullName);
    constructor.getBody().setSource(methodBody);

    // Add constructor to class
    builderClass.add(constructor);

    /**
     * *************************************************************** Create method to get instance
     * ***************************************************************
     */
    JMethod getInstance =
        JMethod.factory.create(
            JModifier.PUBLIC | JModifier.STATIC | JModifier.SYNCHRONIZED,
            builderClassName,
            "getInstance");
    getInstance.setComment(
        new JMethodCommentImpl(
            "Create a new builder instance, if it does not yet exist, and return the object."));

    // Set method body
    methodBody =
        String.format(
            "if (null == %s.instance) {\n"
                + "\t %s.instance = new %s();\n"
                + "}\n\n"
                + "return %s.instance;",
            builderClassName, builderClassName, builderClassName, builderClassName);
    getInstance.getBody().setSource(methodBody);

    // Add method to class
    builderClass.add(getInstance);

    /**
     * *************************************************************** Create method to set RPC
     * method ***************************************************************
     */
    JParameter methodParameter = JParameter.factory.create(JModifier.FINAL, "String", "method");
    JMethodSignature jms = JMethodSignature.factory.create(methodParameter);
    JMethod executeMethod =
        JMethod.factory.create(JModifier.PUBLIC, builderClassName, "executeMethod", jms);
    executeMethod.setComment(new JMethodCommentImpl("Set RPC method to execute."));

    // Set method body
    methodBody = "this.request.setMethod(method);\n\n" + "return this;";
    executeMethod.getBody().setSource(methodBody);

    // Add method to class
    builderClass.add(executeMethod);

    /**
     * *************************************************************** Create method to set data of
     * request ***************************************************************
     */
    JParameter uuidParameter = JParameter.factory.create(JModifier.FINAL, "String", "uuid");
    JParameter payloadParameter = JParameter.factory.create(JModifier.FINAL, "String", "payload");
    jms = JMethodSignature.factory.create(uuidParameter, payloadParameter);
    JMethod dataMethod =
        JMethod.factory.create(JModifier.PUBLIC, builderClassName, "withData", jms);
    dataMethod.setComment(new JMethodCommentImpl("Set data of request."));

    // Set method body
    methodBody =
        "this.request.setUUID(uuid);\n" + "this.request.setPayload(payload);\n\n" + "return this;";
    dataMethod.getBody().setSource(methodBody);

    // Add method to class
    builderClass.add(dataMethod);

    /**
     * *************************************************************** Create method to set service
     * provider ***************************************************************
     */
    JParameter serviceProviderParameter =
        JParameter.factory.create(
            JModifier.FINAL, this.serviceProviderClassName, "serviceProvider");
    jms = JMethodSignature.factory.create(serviceProviderParameter);
    JMethod providerMethod =
        JMethod.factory.create(JModifier.PUBLIC, builderClassName, "onProvider", jms);
    providerMethod.setComment(new JMethodCommentImpl("Set service provider to use."));

    // Set method body
    methodBody = "this.serviceProvider = serviceProvider;\n\n" + "return this;";
    providerMethod.getBody().setSource(methodBody);

    // Add method to class
    builderClass.add(providerMethod);

    /**
     * *************************************************************** Create method to set
     * connection ***************************************************************
     */
    JParameter webSocketParameter =
        JParameter.factory.create(JModifier.FINAL, "WebSocket", "webSocket");
    jms = JMethodSignature.factory.create(webSocketParameter);
    JMethod connectionMethod =
        JMethod.factory.create(JModifier.PUBLIC, builderClassName, "viaConnection", jms);
    connectionMethod.setComment(new JMethodCommentImpl("Set connection for communication."));

    // Set method body
    methodBody = "this.webSocket = webSocket;\n\n" + "return this;";
    connectionMethod.getBody().setSource(methodBody);

    // Add method to class
    builderClass.add(connectionMethod);

    /**
     * *************************************************************** Create method to build worker
     * thread object ***************************************************************
     */
    JMethod buildMethod = JMethod.factory.create(JModifier.PUBLIC, workerThreadClassName, "build");
    buildMethod.addException("Exception");
    buildMethod.setComment(new JMethodCommentImpl("Build the worker thread object."));

    // Set method body
    methodBody =
        String.format(
            "if (null == this.request || null == this.serviceProvider || null == this.webSocket || "
                + "null == this.request.method() || null == this.request.uuid() || null == this.request.payload()) {\n"
                + "\tthrow new Exception(\"Initialize '%s' object properly before building.\");\n"
                + "}\n\n"
                + "// Message is a per-request object, so we need to create a DEEP COPY here!\n"
                + "%s requestCopy = new %s(this.request.asString());\n\n"
                + "return new %s(this.serviceProvider, this.webSocket, requestCopy);",
            workerThreadClassName,
            this.messageClassFullName,
            this.messageClassFullName,
            workerThreadClassName);
    buildMethod.getBody().setSource(methodBody);

    // Add method to class
    builderClass.add(buildMethod);

    return builderClass;
  }
예제 #2
0
  /**
   * Create Java class for a single child worker thread. The generated class will be derived from
   * the base worker thread class and only contains a run() method to start the thread.
   *
   * <p>Furthermore, the code includes an inner class that utilizes the Singleton and Builder design
   * pattern, to create new worker thread objects at runtime.
   *
   * @param operation FOperation object from WSDL parser
   * @return JClass object with child worker thread class
   * @throws Exception Error during code generation
   */
  private JClass createWorkerThreadClass(final FOperation operation) throws Exception {
    String rpcMethodName = WorkerThreadGenerator.firstLetterCapital(operation.getOperationName());
    String workerClassName = rpcMethodName + "Worker";

    // Create worker thread class
    JClass workerClass = JClass.factory.create(JModifier.PUBLIC, workerClassName);
    workerClass.setExtends(WORKER_THREAD_CLASS_NAME);
    workerClass.setComment(
        new JClassCommentImpl(String.format("The '%s' class.", workerClassName)));

    LOGGER.debug(String.format("Created '%s' class for child worker thread.", workerClassName));

    /**
     * *************************************************************** Create fields
     * ***************************************************************
     */
    JField logger =
        JField.factory.create(
            JModifier.PRIVATE | JModifier.STATIC | JModifier.FINAL,
            "Logger",
            "LOGGER",
            String.format("LoggerFactory.getLogger(%s.class)", workerClassName));
    logger.setComment(new JFieldCommentImpl("Logger object."));
    workerClass.add(logger);

    String builderClassName = workerClassName + "Builder";
    JField builder =
        JField.factory.create(
            JModifier.PUBLIC | JModifier.STATIC | JModifier.FINAL,
            builderClassName,
            "BUILDER",
            String.format("%s.getInstance()", builderClassName));
    builder.setComment(
        new JFieldCommentImpl(
            String.format("Builder instance to create new '%s' objects.", workerClassName)));
    workerClass.add(builder);

    /**
     * *************************************************************** Create constructor
     * ***************************************************************
     */
    JParameter serviceProvider =
        JParameter.factory.create(
            JModifier.FINAL, this.serviceProviderClassName, "serviceProvider");
    JParameter webSocket = JParameter.factory.create(JModifier.FINAL, "WebSocket", "webSocket");
    JParameter requestMessage =
        JParameter.factory.create(JModifier.FINAL, this.messageClassFullName, "requestMessage");

    JMethodSignature jms =
        JMethodSignature.factory.create(serviceProvider, webSocket, requestMessage);
    JConstructor constructor = JConstructor.factory.create(JModifier.PRIVATE, workerClassName, jms);
    constructor.setComment(
        new JConstructorCommentImpl(
            String.format("Constructor to create a new '%s' object.", workerClassName)));

    // Set method body
    String methodBody = "super(serviceProvider, webSocket, requestMessage);";
    constructor.getBody().setSource(methodBody);

    // Add constructor to class
    workerClass.add(constructor);

    /**
     * *************************************************************** Create run method
     * ***************************************************************
     */
    JMethod run = JMethod.factory.create(JModifier.PUBLIC, "void", "run");
    run.addAnnotation(JMethodAnnotationImpl.OVERRIDE);
    run.setComment(new JMethodCommentImpl("Run worker thread to handle request."));

    // Set method body
    run.getBody().setSource(this.createRunMethodBody(operation, rpcMethodName));

    // Add method to class
    workerClass.add(run);

    /**
     * *************************************************************** Add inner builder class
     * ***************************************************************
     */
    workerClass.add(this.createInnerBuilderClass(workerClassName));

    return workerClass;
  }