Package org.jboss.errai.codegen.framework.builder.impl

Source Code of org.jboss.errai.codegen.framework.builder.impl.AnonymousClassStructureBuilderImpl$DeferredGenerateCallback

/*
* Copyright 2011 JBoss, by Red Hat, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jboss.errai.codegen.framework.builder.impl;

import static org.jboss.errai.codegen.framework.builder.callstack.LoadClassReference.getClassReference;

import java.util.ArrayList;
import java.util.List;

import org.jboss.errai.codegen.framework.AbstractStatement;
import org.jboss.errai.codegen.framework.Context;
import org.jboss.errai.codegen.framework.DefParameters;
import org.jboss.errai.codegen.framework.Parameter;
import org.jboss.errai.codegen.framework.Statement;
import org.jboss.errai.codegen.framework.Variable;
import org.jboss.errai.codegen.framework.builder.AnonymousClassStructureBuilder;
import org.jboss.errai.codegen.framework.builder.BlockBuilder;
import org.jboss.errai.codegen.framework.builder.BuildCallback;
import org.jboss.errai.codegen.framework.exception.UndefinedMethodException;
import org.jboss.errai.codegen.framework.meta.MetaClass;
import org.jboss.errai.codegen.framework.meta.MetaMethod;
import org.jboss.errai.codegen.framework.util.GenUtil;

/**
* @author Mike Brock <cbrock@redhat.com>
* @author Christian Sadilek <csadilek@redhat.com>
*/
public class AnonymousClassStructureBuilderImpl
        extends ClassBuilder<AnonymousClassStructureBuilder>
        implements AnonymousClassStructureBuilder {
  private BuildCallback<ObjectBuilder> callback;
  private List<DeferredGenerateCallback> callables = new ArrayList<DeferredGenerateCallback>();
  private Context context;

  AnonymousClassStructureBuilderImpl(MetaClass clazz, BuildCallback<ObjectBuilder> builderBuildCallback) {
    super(clazz.getFullyQualifiedName(), clazz, builderBuildCallback.getParentContext());
    this.callback = builderBuildCallback;
    this.context = builderBuildCallback.getParentContext();
  }

  public BlockBuilder<AnonymousClassStructureBuilder> initialize() {
    return new BlockBuilderImpl<AnonymousClassStructureBuilder>(
            new BuildCallback<AnonymousClassStructureBuilder>() {
              @Override
              public AnonymousClassStructureBuilderImpl callback(final Statement statement) {

                addCallable(new DeferredGenerateCallback() {
                  @Override
                  public String doGenerate(Context context) {
                    StringBuilder buf = new StringBuilder(256);
                    buf.append("{\n");
                    if (statement != null) {
                      buf.append(statement.generate(Context.create(context))).append("\n");
                    }
                    buf.append("}\n");

                    return buf.toString();
                  }
                });

                return AnonymousClassStructureBuilderImpl.this;
              }

              @Override
              public Context getParentContext() {
                return context;
              }
            });
  }

  private BlockBuilder<AnonymousClassStructureBuilder> publicOverridesMethod(final MetaMethod method,
                                                                             final DefParameters parameters) {
    return new BlockBuilderImpl<AnonymousClassStructureBuilder>(
            new BuildCallback<AnonymousClassStructureBuilder>() {
              @Override
              public AnonymousClassStructureBuilder callback(final Statement statement) {

                addCallable(new DeferredGenerateCallback() {
                  @Override
                  public String doGenerate(Context context) {
                    Context subContext = Context.create(context);
                    for (Parameter parm : parameters.getParameters()) {
                      subContext.addVariable(Variable.create(parm.getName(), parm.getType()));
                    }

                    StringBuilder buf = new StringBuilder(256);
                    String returnType = getClassReference(method.getReturnType(), context);

                    buf.append("public ").append(returnType)
                            .append(" ")
                            .append(method.getName())
                            .append(parameters.generate(context)).append(" {\n");
                    if (statement != null) {
                      buf.append(statement.generate(subContext)).append("\n");
                    }
                    buf.append("}\n");

                    return buf.toString();
                  }
                });

                return AnonymousClassStructureBuilderImpl.this;
              }

              @Override
              public Context getParentContext() {
                return context;
              }
            });
  }

  public BlockBuilder<AnonymousClassStructureBuilder> publicOverridesMethod(String name, Parameter... args) {
    List<MetaClass> types = new ArrayList<MetaClass>();
    for (Parameter arg : args) {
      types.add(arg.getType());
    }
    MetaMethod method = classDefinition.getSuperClass()
            .getBestMatchingMethod(name, types.toArray(new MetaClass[args.length]));
    if (method == null)
      throw new UndefinedMethodException("Method not found:" + name + "(" + types + ")");

    return publicOverridesMethod(method, DefParameters.from(method, args));
  }


  @Override
  public ObjectBuilder finish() {
    if (callback != null) {
      return callback.callback(new AbstractStatement() {
        @Override
        public String generate(Context context) {
          context.attachClass(getClassDefinition());
          return doGenerate(context);
        }
      });
    }

    return null;
  }

  private void addCallable(DeferredGenerateCallback callable) {
    callables.add(callable);
  }

  String generatedCache;

  private String doGenerate(Context context) {
    if (generatedCache != null) return generatedCache;
    try {
      if (callables == null)
        return null;

      Context subContext = Context.create(context);
      subContext.addVariable(Variable.create("this", getClassDefinition()));

      StringBuilder buf = new StringBuilder(256);
      for (DeferredGenerateCallback c : callables) {
        buf.append(c.doGenerate(subContext));
        buf.append('\n');
      }

      buf.append(classDefinition.membersToString());

      return generatedCache = buf.toString();
    }
    catch (Exception e) {
      GenUtil.throwIfUnhandled("while generating: " + classDefinition.getFullyQualifiedName(), e);
      return null;
    }
  }

  public static interface DeferredGenerateCallback {
    public String doGenerate(Context context);
  }


  public MetaClass getClassDefinition() {
    return classDefinition;
  }
}
TOP

Related Classes of org.jboss.errai.codegen.framework.builder.impl.AnonymousClassStructureBuilderImpl$DeferredGenerateCallback

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