Package ch.rasc.extclassgenerator

Source Code of ch.rasc.extclassgenerator.ModelAnnotationProcessor

/**
* Copyright 2013-2014 Ralph Schaer <ralphschaer@gmail.com>
*
* 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 ch.rasc.extclassgenerator;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;

import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@SupportedAnnotationTypes({ "ch.rasc.extclassgenerator.Model" })
@SupportedOptions({ "outputFormat", "debug", "includeValidation" })
public class ModelAnnotationProcessor extends AbstractProcessor {

  private static final boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = false;

  private static final String OPTION_OUTPUTFORMAT = "outputFormat";

  private static final String OPTION_DEBUG = "debug";

  private static final String OPTION_INCLUDEVALIDATION = "includeValidation";

  private static final String OPTION_CREATEBASEANDSUBCLASS = "createBaseAndSubclass";

  private static final String OPTION_USESINGLEQUOTES = "useSingleQuotes";

  private static final String OPTION_SURROUNDAPIWITHQUOTES = "surroundApiWithQuotes";

  @Override
  public boolean process(Set<? extends TypeElement> annotations,
      RoundEnvironment roundEnv) {
    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
        "Running " + getClass().getSimpleName());

    if (roundEnv.processingOver() || annotations.size() == 0) {
      return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
    }

    if (roundEnv.getRootElements() == null || roundEnv.getRootElements().isEmpty()) {
      processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
          "No sources to process");
      return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
    }

    OutputConfig outputConfig = new OutputConfig();

    outputConfig.setDebug(!"false".equals(processingEnv.getOptions()
        .get(OPTION_DEBUG)));
    boolean createBaseAndSubclass = "true".equals(processingEnv.getOptions().get(
        OPTION_CREATEBASEANDSUBCLASS));

    String outputFormatString = processingEnv.getOptions().get(OPTION_OUTPUTFORMAT);
    outputConfig.setOutputFormat(OutputFormat.EXTJS4);
    if (StringUtils.hasText(outputFormatString)) {
      if (OutputFormat.TOUCH2.name().equalsIgnoreCase(outputFormatString)) {
        outputConfig.setOutputFormat(OutputFormat.TOUCH2);
      }
      else if (OutputFormat.EXTJS5.name().equalsIgnoreCase(outputFormatString)) {
        outputConfig.setOutputFormat(OutputFormat.EXTJS5);
      }
    }

    String includeValidationString = processingEnv.getOptions().get(
        OPTION_INCLUDEVALIDATION);
    outputConfig.setIncludeValidation(IncludeValidation.NONE);
    if (StringUtils.hasText(includeValidationString)) {
      if (IncludeValidation.ALL.name().equalsIgnoreCase(includeValidationString)) {
        outputConfig.setIncludeValidation(IncludeValidation.ALL);
      }
      else if (IncludeValidation.BUILTIN.name().equalsIgnoreCase(
          includeValidationString)) {
        outputConfig.setIncludeValidation(IncludeValidation.BUILTIN);
      }
    }

    outputConfig.setUseSingleQuotes("true".equals(processingEnv.getOptions().get(
        OPTION_USESINGLEQUOTES)));
    outputConfig.setSurroundApiWithQuotes("true".equals(processingEnv.getOptions()
        .get(OPTION_SURROUNDAPIWITHQUOTES)));

    for (TypeElement annotation : annotations) {
      Set<? extends Element> elements = roundEnv
          .getElementsAnnotatedWith(annotation);
      for (Element element : elements) {

        try {
          TypeElement typeElement = (TypeElement) element;

          String qualifiedName = typeElement.getQualifiedName().toString();
          Class<?> modelClass = Class.forName(qualifiedName);

          String code = ModelGenerator.generateJavascript(modelClass,
              outputConfig);

          Model modelAnnotation = element.getAnnotation(Model.class);
          String modelName = modelAnnotation.value();
          String fileName;
          String packageName = "";
          if (StringUtils.hasText(modelName)) {
            int lastDot = modelName.lastIndexOf('.');
            if (lastDot != -1) {
              fileName = modelName.substring(lastDot + 1);
              int firstDot = modelName.indexOf('.');
              if (firstDot < lastDot) {
                packageName = modelName.substring(firstDot + 1, lastDot);
              }
            }
            else {
              fileName = modelName;
            }
          }
          else {
            fileName = typeElement.getSimpleName().toString();
          }

          if (createBaseAndSubclass) {
            code = code.replaceFirst("(Ext.define\\([\"'].+?)([\"'],)",
                "$1Base$2");
            FileObject fo = processingEnv.getFiler().createResource(
                StandardLocation.SOURCE_OUTPUT, packageName,
                fileName + "Base.js");
            OutputStream os = fo.openOutputStream();
            os.write(code.getBytes(ModelGenerator.UTF8_CHARSET));
            os.close();

            try {
              fo = processingEnv.getFiler().getResource(
                  StandardLocation.SOURCE_OUTPUT, packageName,
                  fileName + ".js");
              InputStream is = fo.openInputStream();
              is.close();
            }
            catch (FileNotFoundException e) {
              String subClassCode = generateSubclassCode(modelClass,
                  outputConfig);
              fo = processingEnv.getFiler().createResource(
                  StandardLocation.SOURCE_OUTPUT, packageName,
                  fileName + ".js");
              os = fo.openOutputStream();
              os.write(subClassCode.getBytes(ModelGenerator.UTF8_CHARSET));
              os.close();
            }

          }
          else {
            FileObject fo = processingEnv.getFiler().createResource(
                StandardLocation.SOURCE_OUTPUT, packageName,
                fileName + ".js");
            OutputStream os = fo.openOutputStream();
            os.write(code.getBytes(ModelGenerator.UTF8_CHARSET));
            os.close();
          }

        }
        catch (ClassNotFoundException e) {
          processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
              e.getMessage());
        }
        catch (IOException e) {
          processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
              e.getMessage());
        }

      }
    }

    return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
  }

  private static String generateSubclassCode(Class<?> clazz, OutputConfig outputConfig) {
    Model modelAnnotation = clazz.getAnnotation(Model.class);

    String name;
    if (modelAnnotation != null && StringUtils.hasText(modelAnnotation.value())) {
      name = modelAnnotation.value();
    }
    else {
      name = clazz.getName();
    }

    Map<String, Object> modelObject = new LinkedHashMap<String, Object>();
    modelObject.put("extend", name + "Base");

    StringBuilder sb = new StringBuilder(100);
    sb.append("Ext.define(\"").append(name).append("\",");
    if (outputConfig.isDebug()) {
      sb.append("\n");
    }

    String configObjectString;
    try {

      ObjectMapper mapper = new ObjectMapper();
      mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);

      if (!outputConfig.isSurroundApiWithQuotes()) {
        if (outputConfig.getOutputFormat() == OutputFormat.EXTJS5) {
          mapper.addMixInAnnotations(ProxyObject.class,
              ProxyObjectWithoutApiQuotesExtJs5Mixin.class);
        }
        else {
          mapper.addMixInAnnotations(ProxyObject.class,
              ProxyObjectWithoutApiQuotesMixin.class);
        }
        mapper.addMixInAnnotations(ApiObject.class, ApiObjectMixin.class);
      }
      else {
        if (outputConfig.getOutputFormat() != OutputFormat.EXTJS5) {
          mapper.addMixInAnnotations(ProxyObject.class,
              ProxyObjectWithApiQuotesMixin.class);
        }
      }

      if (outputConfig.isDebug()) {
        configObjectString = mapper.writerWithDefaultPrettyPrinter()
            .writeValueAsString(modelObject);
      }
      else {
        configObjectString = mapper.writeValueAsString(modelObject);
      }

    }
    catch (JsonGenerationException e) {
      throw new RuntimeException(e);
    }
    catch (JsonMappingException e) {
      throw new RuntimeException(e);
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }

    sb.append(configObjectString);
    sb.append(");");

    if (outputConfig.isUseSingleQuotes()) {
      return sb.toString().replace('"', '\'');
    }

    return sb.toString();

  }
}
TOP

Related Classes of ch.rasc.extclassgenerator.ModelAnnotationProcessor

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.