Search in sources :

Example 1 with ActionReferences

use of org.openide.awt.ActionReferences in project netbeans-rcp-lite by outersky.

the class ActionProcessor method handleProcess.

@Override
protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
    TypeMirror actionListener = type(ActionListener.class);
    TypeMirror p1 = type(Presenter.Menu.class);
    TypeMirror p2 = type(Presenter.Toolbar.class);
    TypeMirror p3 = type(Presenter.Popup.class);
    TypeMirror caa = type(ContextAwareAction.class);
    TypeMirror dmc = type(DynamicMenuContent.class);
    TypeMirror at = type(Action.class);
    TypeMirror ot = type(Object.class);
    TypeMirror lt = type(EventListener.class);
    TypeMirror vt = type(Void.class);
    for (Element e : roundEnv.getElementsAnnotatedWith(ActionRegistration.class)) {
        ActionRegistration ar = e.getAnnotation(ActionRegistration.class);
        if (ar == null) {
            continue;
        }
        ActionID aid = e.getAnnotation(ActionID.class);
        if (aid == null) {
            throw new LayerGenerationException("@ActionRegistration can only be used together with @ActionID annotation", e, processingEnv, ar);
        }
        if (aid.id() == null) {
            continue;
        }
        if (aid.category().startsWith("Actions/")) {
            throw new LayerGenerationException("@ActionID category() should not start with Actions/", e, processingEnv, aid, "category");
        }
        if (!FQN.matcher(aid.id()).matches()) {
            throw new LayerGenerationException("@ActionID id() must be valid fully qualified name", e, processingEnv, aid, "id");
        }
        String id = aid.id().replace('.', '-');
        LayerBuilder builder = layer(e);
        File f = builder.file("Actions/" + aid.category() + "/" + id + ".instance");
        f.bundlevalue("displayName", ar.displayName(), ar, "displayName");
        String menuText = ar.menuText();
        if (!menuText.isEmpty()) {
            f.bundlevalue("menuText", menuText, ar, "menuText");
        }
        String popupText = ar.popupText();
        if (!popupText.isEmpty()) {
            f.bundlevalue("popupText", popupText, ar, "popupText");
        }
        String key;
        boolean createDelegate = true;
        if (e.getKind() == ElementKind.FIELD) {
            VariableElement var = (VariableElement) e;
            TypeMirror stringType = type(String.class);
            if (e.asType() != stringType || !e.getModifiers().contains(Modifier.PUBLIC) || !e.getModifiers().contains(Modifier.STATIC) || !e.getModifiers().contains(Modifier.FINAL)) {
                throw new LayerGenerationException("Only static string constant fields can be annotated", e, processingEnv, ar);
            }
            if (ar.key().length() != 0) {
                throw new LayerGenerationException("When annotating field, one cannot define key()", e, processingEnv, ar, "key");
            }
            createDelegate = false;
            key = var.getConstantValue().toString();
        } else if (e.getKind() == ElementKind.CLASS) {
            if (!isAssignable(e.asType(), actionListener)) {
                throw new LayerGenerationException("Class annotated with @ActionRegistration must implement java.awt.event.ActionListener!", e, processingEnv, ar);
            }
            if (!e.getModifiers().contains(Modifier.PUBLIC)) {
                throw new LayerGenerationException("Class has to be public", e, processingEnv, ar);
            }
            if (e.getEnclosingElement().getKind() == ElementKind.CLASS && !e.getModifiers().contains(Modifier.STATIC)) {
                throw new LayerGenerationException("Inner class annotated with @ActionRegistration has to be static", e);
            }
            key = ar.key();
        } else {
            assert e.getKind() == ElementKind.METHOD : e;
            builder.instanceFile("dummy", null, ActionListener.class, ar, null);
            key = ar.key();
        }
        Boolean direct = null;
        AnnotationMirror arMirror = null;
        for (AnnotationMirror m : e.getAnnotationMirrors()) {
            if (m.getAnnotationType().toString().equals(ActionRegistration.class.getCanonicalName())) {
                arMirror = m;
                for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : m.getElementValues().entrySet()) {
                    if (entry.getKey().getSimpleName().contentEquals("lazy")) {
                        direct = !(Boolean) entry.getValue().getValue();
                        assert direct == !ar.lazy();
                        break;
                    }
                }
            }
        }
        if (direct == null) {
            if (e.getKind() == ElementKind.FIELD) {
                direct = false;
            } else {
                TypeMirror type = e.getKind() == ElementKind.CLASS ? e.asType() : ((ExecutableElement) e).getReturnType();
                direct = isAssignable(type, p1) || isAssignable(type, p2) || isAssignable(type, p3) || isAssignable(type, caa) || isAssignable(type, dmc);
                if (direct) {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Should explicitly specify lazy attribute", e);
                }
            }
        }
        if (direct) {
            if (key.length() != 0) {
                throw new LayerGenerationException("Cannot specify key and use eager registration", e, processingEnv, ar, "key");
            }
            if (!ar.iconBase().isEmpty()) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "iconBase unused on eager registrations", e, arMirror);
            }
            f.instanceAttribute("instanceCreate", Action.class);
        } else {
            TypeMirror selectType = null;
            if (key.length() == 0) {
                f.methodvalue("instanceCreate", "org.openide.awt.Actions", "alwaysEnabled");
            } else {
                f.methodvalue("instanceCreate", "org.openide.awt.Actions", "callback");
                if (createDelegate) {
                    f.methodvalue("fallback", "org.openide.awt.Actions", "alwaysEnabled");
                }
                f.stringvalue("key", key);
            }
            if (createDelegate) {
                try {
                    f.instanceAttribute("delegate", ActionListener.class, ar, null);
                } catch (LayerGenerationException ex) {
                    selectType = generateContext(e, f, ar);
                }
            }
            if (ar.iconBase().length() > 0) {
                builder.validateResource(ar.iconBase(), e, ar, "iconBase", true);
                f.stringvalue("iconBase", ar.iconBase());
            }
            f.boolvalue("noIconInMenu", !ar.iconInMenu());
            if (ar.asynchronous()) {
                f.boolvalue("asynchronous", true);
            }
            if (ar.surviveFocusChange()) {
                f.boolvalue("surviveFocusChange", true);
            }
            processActionState(e, ar.enabledOn(), f, selectType, true, at, ot, lt, vt);
            processActionState(e, ar.checkedOn(), f, selectType, false, at, ot, lt, vt);
        }
        f.write();
        ActionReference aref = e.getAnnotation(ActionReference.class);
        if (aref != null) {
            processReferences(e, aref, aid);
        }
        ActionReferences refs = e.getAnnotation(ActionReferences.class);
        if (refs != null) {
            for (ActionReference actionReference : refs.value()) {
                processReferences(e, actionReference, aid);
            }
        }
    }
    for (Element e : roundEnv.getElementsAnnotatedWith(ActionReference.class)) {
        if (e.getAnnotation(ActionRegistration.class) != null) {
            continue;
        }
        ActionReference ref = e.getAnnotation(ActionReference.class);
        if (ref == null) {
            continue;
        }
        ActionID id = e.getAnnotation(ActionID.class);
        if (id != null) {
            processReferences(e, ref, id);
            continue;
        }
        throw new LayerGenerationException("Don't use @ActionReference without @ActionID", e, processingEnv, ref);
    }
    for (Element e : roundEnv.getElementsAnnotatedWith(ActionReferences.class)) {
        if (e.getAnnotation(ActionRegistration.class) != null) {
            continue;
        }
        ActionReferences refs = e.getAnnotation(ActionReferences.class);
        if (refs == null) {
            continue;
        }
        ActionID id = e.getAnnotation(ActionID.class);
        if (id != null) {
            for (ActionReference actionReference : refs.value()) {
                if (!actionReference.id().id().isEmpty() || !actionReference.id().category().isEmpty()) {
                    throw new LayerGenerationException("Don't specify additional id=@ActionID(...) when using @ActionID on the element", e, processingEnv, actionReference.id());
                }
                processReferences(e, actionReference, id);
            }
        } else {
            for (ActionReference actionReference : refs.value()) {
                if (actionReference.id().id().isEmpty() || actionReference.id().category().isEmpty()) {
                    throw new LayerGenerationException("Specify real id=@ActionID(...)", e, processingEnv, actionReference.id());
                }
                processReferences(e, actionReference, actionReference.id());
            }
        }
    }
    return true;
}
Also used : VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) LayerGenerationException(org.openide.filesystems.annotations.LayerGenerationException) ActionReference(org.openide.awt.ActionReference) VariableElement(javax.lang.model.element.VariableElement) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ActionID(org.openide.awt.ActionID) ActionListener(java.awt.event.ActionListener) ActionReferences(org.openide.awt.ActionReferences) TypeMirror(javax.lang.model.type.TypeMirror) Presenter(org.openide.util.actions.Presenter) ActionRegistration(org.openide.awt.ActionRegistration) LayerBuilder(org.openide.filesystems.annotations.LayerBuilder) File(org.openide.filesystems.annotations.LayerBuilder.File) Map(java.util.Map)

Aggregations

ActionListener (java.awt.event.ActionListener)1 Map (java.util.Map)1 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 Element (javax.lang.model.element.Element)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 TypeElement (javax.lang.model.element.TypeElement)1 VariableElement (javax.lang.model.element.VariableElement)1 TypeMirror (javax.lang.model.type.TypeMirror)1 ActionID (org.openide.awt.ActionID)1 ActionReference (org.openide.awt.ActionReference)1 ActionReferences (org.openide.awt.ActionReferences)1 ActionRegistration (org.openide.awt.ActionRegistration)1 LayerBuilder (org.openide.filesystems.annotations.LayerBuilder)1 File (org.openide.filesystems.annotations.LayerBuilder.File)1 LayerGenerationException (org.openide.filesystems.annotations.LayerGenerationException)1 Presenter (org.openide.util.actions.Presenter)1