All Downloads are FREE. Search and download functionalities are using the official Maven repository.

juzu.impl.metamodel.MetaModelContext Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/*
 * 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.ProcessingContext;
import juzu.impl.compiler.ProcessingException;

import javax.annotation.processing.Completion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;

/** @author Julien Viet */
public final class MetaModelContext

, M extends MetaModel> implements Serializable, Iterable { /** . */ private ProcessingContext processingContext; /** The meta model. */ private ArrayList metaModels; /** The plugins. */ private LinkedHashMap pluginMap; /** The supported annotations per plugin. */ private HashMap> supportedAnnotationsMap; /** All supported annotations. */ private Set> supportedAnnotations; /** . */ private final Class

pluginType; /** All known annotations. */ final LinkedHashMap knownAnnotations = new LinkedHashMap(); public MetaModelContext(Class

pluginType) { this.pluginType = pluginType; this.metaModels = new ArrayList(); } public void init(ProcessingContext env) throws NullPointerException { this.processingContext = env; // HashMap> supportedAnnotationsMap = new HashMap>(); LinkedHashMap pluginMap = new LinkedHashMap(); StringBuilder msg = new StringBuilder("Using plugins:"); for (P plugin : env.loadServices(pluginType)) { msg.append(" ").append(plugin.getName()); pluginMap.put(plugin.getName(), plugin); } env.info(msg); // Collect processed annotations HashSet> supportedAnnotations = new HashSet>(); for (P plugin : pluginMap.values()) { HashSet pluginSupportedAnnotations = new HashSet(); for (Class annotationType : plugin.init(env)) { pluginSupportedAnnotations.add(Name.create(annotationType)); supportedAnnotations.add(annotationType); } env.info("Plugin " + plugin.getName() + " supports " + pluginSupportedAnnotations); supportedAnnotationsMap.put(plugin, pluginSupportedAnnotations); } // this.pluginMap = pluginMap; this.supportedAnnotationsMap = supportedAnnotationsMap; this.supportedAnnotations = supportedAnnotations; } public Iterator iterator() { return metaModels.iterator(); } public Set> getSupportedAnnotations() { return supportedAnnotations; } public Collection

getPlugins() { return pluginMap.values(); } public void add(M metaModel) { metaModel.processingContext = processingContext; metaModel.forward = true; metaModel.context = this; metaModel.init(processingContext); for (P plugin : pluginMap.values()) { plugin.init(metaModel); } metaModels.add(metaModel); } public final void postActivate(ProcessingContext processingContext) throws NullPointerException { this.processingContext = processingContext; for (M metaModel : metaModels) { metaModel.processingContext = processingContext; for (P plugin : pluginMap.values()) { plugin.postActivate(metaModel); } } } public void processAnnotationChange(AnnotationChange change) { // Update state if (change.getAdded() == null) { knownAnnotations.remove(change.getKey()); } else { knownAnnotations.put(change.getKey(), change.getAdded()); } // for (M metaModel : metaModels) { if (metaModel.forward) { metaModel.forward = false; for (Map.Entry annotation : knownAnnotations.entrySet()) { change = new AnnotationChange(annotation.getKey(), null, annotation.getValue()); for (P plugin : pluginMap.values()) { HashSet supportedAnnotations = supportedAnnotationsMap.get(plugin); if (supportedAnnotations.contains(change.key.type)) { plugin.processAnnotationChange(metaModel, change); } } } } else { for (P plugin : pluginMap.values()) { HashSet supportedAnnotations = supportedAnnotationsMap.get(plugin); if (supportedAnnotations.contains(change.key.type)) { plugin.processAnnotationChange(metaModel, change); } } } } } public void processAnnotationChanges(Iterable changes) { for (AnnotationChange change : changes) { processAnnotationChange(change); } } void processAnnotations(Iterable> annotations) { ArrayList delta = new ArrayList(); for (Map.Entry entry : knownAnnotations.entrySet()) { AnnotationKey key = entry.getKey(); Element element = processingContext.get(key.element); if (element == null) { delta.add(new AnnotationChange(key, entry.getValue(), null)); processingContext.log(Level.FINER, "Annotation removed " + key); } else { AnnotationMirror found = null; for (AnnotationMirror mirror : element.getAnnotationMirrors()) { Name f = Name.parse(((TypeElement)mirror.getAnnotationType().asElement()).getQualifiedName().toString()); if (key.getType().equals(f)) { found = mirror; break; } } if (found == null) { delta.add(new AnnotationChange(key, entry.getValue(), null)); processingContext.log(Level.FINER, "Annotation removed " + key); } } } for (Map.Entry annotation : annotations) { AnnotationState knownAnnotation = knownAnnotations.get(annotation.getKey()); if (knownAnnotation != null) { processingContext.log(Level.FINER, "Annotation updated " + annotation.getKey()); } else { processingContext.log(Level.FINER, "Annotation added " + annotation.getKey()); } delta.add(new AnnotationChange(annotation.getKey(), knownAnnotation, annotation.getValue())); } processAnnotationChanges(delta); } public Iterable getCompletions( AnnotationKey annotationKey, AnnotationState annotationState, String member, String userText) { Iterable completions = null; for (M metaModel : metaModels) { for (P plugin : pluginMap.values()) { HashSet supportedAnnotations = supportedAnnotationsMap.get(plugin); if (supportedAnnotations.contains(annotationKey.type)) { completions = plugin.getCompletions(metaModel, annotationKey, annotationState, member, userText); if (completions != null) { break; } } } } return completions; } public void postProcessAnnotations() throws ProcessingException { for (M metaModel : metaModels) { for (P plugin : pluginMap.values()) { plugin.postProcessAnnotations(metaModel); } } } public void processEvents() { for (M metaModel : metaModels) { for (P plugin : pluginMap.values()) { plugin.processEvents(metaModel, new EventQueue(metaModel.dispatch)); } metaModel.dispatch.clear(); } } public void postProcessEvents() { for (M metaModel : metaModels) { for (P plugin : pluginMap.values()) { plugin.postProcessEvents(metaModel); } } } public void prePassivate() { for (M metaModel : metaModels) { for (P plugin : pluginMap.values()) { plugin.prePassivate(metaModel); } metaModel.processingContext = null; } this.processingContext = null; } public void remove(M metaModel) { try { metaModel.processingContext = processingContext; // metaModels.remove(metaModel); // Initialize plugins for (P plugin : pluginMap.values()) { plugin.destroy(metaModel); } } finally { metaModel.processingContext = null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy