Package juzu.impl.metamodel

Source Code of juzu.impl.metamodel.MetaModelProcessor

/*
* Copyright 2013 eXo Platform SAS
*
* 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 juzu.impl.metamodel;

import juzu.impl.common.Name;
import juzu.impl.compiler.BaseProcessor;
import juzu.impl.compiler.MessageCode;
import juzu.impl.compiler.ProcessingContext;
import juzu.impl.common.Logger;
import juzu.impl.common.Tools;

import javax.annotation.Generated;
import javax.annotation.processing.Completion;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Set;

/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
public abstract class MetaModelProcessor<P extends MetaModelPlugin<M, P>, M extends MetaModel<P, M>> extends BaseProcessor {

  /** . */
  public static final MessageCode ANNOTATION_UNSUPPORTED = new MessageCode("ANNOTATION_UNSUPPORTED", "The annotation of this element cannot be supported");

  /** . */
  private MetaModelState<P, M> state;

  /** . */
  private int index;

  /** . */
  private final Logger log = BaseProcessor.getLogger(getClass());

  /** . */
  private HashSet<String> supportedAnnotations;

  @Override
  protected void doInit(ProcessingContext context) {
    log.info("Using processing env " + context.getClass().getName());

    // Try to get state or create new one
    if (state == null) {
      InputStream in = null;
      try {
        FileObject file = getContext().getResource(StandardLocation.SOURCE_OUTPUT, "juzu", "metamodel.ser");
        in = file.openInputStream();
        ObjectInputStream ois = new ObjectInputStream(in);
        state = (MetaModelState<P, M>)ois.readObject();
        log.info("Loaded model from " + file.toUri());
      }
      catch (Exception e) {
        log.info("Created new meta model");
        MetaModelState<P, M> metaModel = new MetaModelState<P, M>(getPluginType(), createMetaModel());
        metaModel.init(getContext());
        state = metaModel;
      }
      finally {
        Tools.safeClose(in);
      }
    }

    //
    HashSet<String> supportedAnnotations = new HashSet<String>();
    for (Class<?> supportedAnnotation : state.context.getSupportedAnnotations()) {
      supportedAnnotations.add(supportedAnnotation.getName());
    }

    //
    this.supportedAnnotations = supportedAnnotations;
    this.index = 0;
  }

  protected abstract Class<P> getPluginType();

  protected abstract M createMetaModel();

  @Override
  protected void doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    if (!roundEnv.errorRaised()) {
      if (roundEnv.processingOver()) {
        log.info("APT processing over");

        //
        log.info("Passivating model");
        state.metaModel.prePassivate();

        // Passivate model
        ObjectOutputStream out = null;
        try {
          FileObject file = getContext().createResource(StandardLocation.SOURCE_OUTPUT, "juzu", "metamodel.ser");
          out = new ObjectOutputStream(file.openOutputStream());
          out.writeObject(state);
          state = null;
        }
        catch (Exception e) {
          e.printStackTrace();
          log.info("Could not passivate model ", e);
        }
        finally {
          Tools.safeClose(out);
        }
      }
      else {
        log.info("Starting APT round #" + index);

        //
        if (index == 0) {
          log.info("Activating model");
          state.metaModel.postActivate(getContext());
        }

        //
        LinkedHashMap<AnnotationKey, AnnotationState> updates = new LinkedHashMap<AnnotationKey, AnnotationState>();
        for (TypeElement annotationElt : annotations) {
          if (supportedAnnotations.contains(annotationElt.getQualifiedName().toString())) {
            log.info("Processing elements for annotation for " + annotationElt.getQualifiedName());
            for (Element annotatedElt : roundEnv.getElementsAnnotatedWith(annotationElt)) {
              if (annotatedElt.getAnnotation(Generated.class) == null) {
                log.info("Processing element " + annotatedElt);
                for (AnnotationMirror annotationMirror : annotatedElt.getAnnotationMirrors()) {
                  if (annotationMirror.getAnnotationType().asElement().equals(annotationElt)) {
                    AnnotationKey key = new AnnotationKey(annotatedElt, annotationMirror);
                    AnnotationState state = AnnotationState.create(annotationMirror);
                    updates.put(key, state);
                  }
                }
              }
            }
          }
        }

        //
        log.info("Process annotations");
        state.context.processAnnotations(updates.entrySet());

        //
        log.info("Post processing model");
        state.metaModel.postProcessAnnotations();

        //
        log.info("Process events");
        state.metaModel.processEvents();

        //
        log.info("Post process events");
        state.metaModel.postProcessEvents();

        //
        log.info("Ending APT round #" + index++);
      }
    }
  }

  @Override
  public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) {
    Iterable<? extends Completion> completions;
    // For now we don't provide completion when element is absent
    if (element != null) {
      // Get state (but we won't save it)
      log.info("Activating model");
      state.metaModel.postActivate(getContext());
      AnnotationKey annotationKey = new AnnotationKey(element, Name.parse(((TypeElement)annotation.getAnnotationType().asElement()).getQualifiedName().toString()));
      AnnotationState annotationState = AnnotationState.create(annotation);
      completions = state.context.getCompletions(annotationKey, annotationState, member.getSimpleName().toString(), userText);
    } else {
      completions = Collections.emptyList();
    }
    return completions != null ? completions : Collections.<Completion>emptyList();
  }
}
TOP

Related Classes of juzu.impl.metamodel.MetaModelProcessor

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.