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

org.netbeans.modules.maven.j2ee.EmbeddableEJBContainerHint Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.maven.j2ee;

import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.util.TreePath;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.Element;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
import org.netbeans.modules.j2ee.deployment.devmodules.api.InstanceRemovedException;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
import org.netbeans.modules.j2ee.deployment.devmodules.api.ServerInstance;
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
import org.netbeans.modules.java.hints.spi.AbstractHint;
import org.netbeans.modules.javaee.project.api.JavaEEProjectSettings;
import org.netbeans.modules.maven.api.ModelUtils;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.model.ModelOperation;
import org.netbeans.modules.maven.model.pom.Dependency;
import org.netbeans.modules.maven.model.pom.POMModel;
import org.netbeans.modules.maven.model.pom.Properties;
import org.netbeans.spi.editor.hints.ChangeInfo;
import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
import org.netbeans.spi.editor.hints.Fix;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;


/**
 * Warn user when implementation of EJBContainer is missing and offers him Embeddable EJB Container to use .
 */
public class EmbeddableEJBContainerHint extends AbstractHint {

    private static final Set TREE_KINDS =
            EnumSet.of(Tree.Kind.METHOD_INVOCATION);
    
    private static final String PROP_GF_EMBEDDED_JAR = "glassfish.embedded-static-shell.jar";
    
    public EmbeddableEJBContainerHint() {
        super(true, true, AbstractHint.HintSeverity.ERROR);
    }
    
    @Override
    public String getDescription() {
        return NbBundle.getMessage(EmbeddableEJBContainerHint.class, "EmbeddableEJBContainer_Description"); // NOI18N
    }

    @Override
    public Set getTreeKinds() {
        return TREE_KINDS;
    }

    @Override
    public List run(CompilationInfo info, TreePath treePath) {
        Tree t = treePath.getLeaf();

        Element el = info.getTrees().getElement(treePath);

        if (!(el != null && el.getEnclosingElement().getSimpleName().toString().equals("EJBContainer") &&  // NOI18N
            el.getSimpleName().toString().equals("createEJBContainer"))) { // NOI18N
            return null;
        }
        
        FileObject testFile = info.getFileObject();
        Project prj = FileOwnerQuery.getOwner(testFile);
        if (prj == null) {
            return null;
        }
        if (prj.getLookup().lookup(NbMavenProject.class) == null) {
            // handles only Maven projects; Ant projects solves this issue differently
            return null;
        }
        ClassPath cp = ClassPath.getClassPath(testFile, ClassPath.EXECUTE);
        if (cp == null) {
            return null;
        }
        for (FileObject cpRoot : cp.getRoots()) {
            FileObject fo = FileUtil.getArchiveFile(cpRoot);
            if (fo != null && fo.getNameExt().toLowerCase().contains("glassfish-embedded-static-shell")) {
                return null;
            }
        }
        try {
            cp.getClassLoader(true).loadClass("javax.ejb.embeddable.EJBContainer"); // NOI18N
            return null;
        } catch (ClassFormatError tt) {
            // OK, show hint to add GF
        } catch (ClassNotFoundException tt) {
            // OK, show hint to add GF
        }
        
        List fixes = new ArrayList();
        J2eeModuleProvider provider = prj.getLookup().lookup(J2eeModuleProvider.class);
        if (provider != null) {
            fixes = FixEjbContainerAction.createGF3SystemScope(prj);
        }
                
        return Collections.singletonList(
                ErrorDescriptionFactory.createErrorDescription(
                getSeverity().toEditorSeverity(),
                getDisplayName(),
                fixes,
                info.getFileObject(),
                (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), t),
                (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), t)));
    }

    @Override
    public String getId() {
        return "EmbeddableEJBContainer"; // NOI18N
    }

    @Override
    public String getDisplayName() {
        return NbBundle.getMessage(EmbeddableEJBContainerHint.class, "EmbeddableEJBContainer_DisplayName"); // NOI18N
    }

    @Override
    public void cancel() {
    }

    private static final class FixEjbContainerAction implements Fix {

        private static final String GF_EMBEDDED_STATIC_SHELL_POM_LATEST = "https://maven.java.net/content/repositories/releases/org/glassfish/main/extras/glassfish-embedded-static-shell/3.1.2.2/glassfish-embedded-static-shell-3.1.2.2.pom";
        private static final String GF_EMBEDDED_STATIC_SHELL_POM_OLD = "http://repo2.maven.org/maven2/org/glassfish/extras/glassfish-embedded-static-shell/3.0.1/glassfish-embedded-static-shell-3.0.1.pom";
        private final String fixDesc;
        private final URL pomUrl;
        private final Project project;
        private final File file;


        private FixEjbContainerAction(String fixDesc, URL pomUrl, File f, Project prj) {
            this.fixDesc = fixDesc;
            this.pomUrl = pomUrl;
            this.project = prj;
            this.file = FileUtil.normalizeFile(f);
        }

        public static List createGF3SystemScope(Project prj) {
            List fixes = new ArrayList();
            String usedServer = JavaEEProjectSettings.getServerInstanceID(prj);
            for (String serId : Deployment.getDefault().getServerInstanceIDs()) {
                ServerInstance server = Deployment.getDefault().getServerInstance(serId);
                try {
                    if (!"gfv3ee6".equals(server.getServerID())) {
                        continue;
                    }
                } catch (InstanceRemovedException ex) {
                    continue;
                }
                try {
                    File[] files = server.getJ2eePlatform().getToolClasspathEntries(J2eePlatform.TOOL_EMBEDDABLE_EJB);
                    assert files.length == 1 : "expecting one item: " + Arrays.asList(files);
                    
                    try {
                        URL pomUrl;
                        if (serId.indexOf("gfv3ee6wc") != -1) {
                            pomUrl = new URL(GF_EMBEDDED_STATIC_SHELL_POM_LATEST);
                        } else {
                            pomUrl = new URL(GF_EMBEDDED_STATIC_SHELL_POM_OLD);
                        }
                        if (serId.equals(usedServer)) {
                            fixes.clear();
                        }
                        fixes.add(new FixEjbContainerAction(
                                NbBundle.getMessage(EmbeddableEJBContainerHint.class, "EmbeddableEJBContainer_FixGFStatic", server.getDisplayName()),
                                pomUrl, files[0], prj));
                        if (serId.equals(usedServer)) {
                            return fixes;
                        }
                    } catch (MalformedURLException ex) {
                        Exceptions.printStackTrace(ex);
                    }
                } catch (InstanceRemovedException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
            return fixes;
        }
        
        @Override
        public ChangeInfo implement() throws Exception {
            final Boolean[] added = new Boolean[1];
            ModelOperation operation = new ModelOperation() {
                @Override
                public void performOperation(POMModel model) {
                    added[0] = checkAndAddPom(pomUrl, model, file);
                }
            };
            FileObject pom = project.getProjectDirectory().getFileObject("pom.xml");//NOI18N
            org.netbeans.modules.maven.model.Utilities.performPOMModelOperations(pom, Collections.singletonList(operation));
            //TODO is the manual reload necessary if pom.xml file is being saved?
    //                NbMavenProject.fireMavenProjectReload(project);
            if (added[0]) {
                project.getLookup().lookup(NbMavenProject.class).triggerDependencyDownload();
            }
            return null;
        }

        private boolean checkAndAddPom(URL pom, POMModel model, File systemDep) {
            ModelUtils.LibraryDescriptor result = ModelUtils.checkLibrary(pom);
            if (result != null) {
                //set dependency
                Dependency dep = ModelUtils.checkModelDependency(model, result.getGroupId(), result.getArtifactId(), true);
                dep.setVersion(result.getVersion());
                dep.setScope("system"); //NOI18N
                
                if (result.getClassifier() != null) {
                    dep.setClassifier(result.getClassifier());
                }
                if (systemDep != null) {
                    Properties props = model.getProject().getProperties();
                    if (props != null && props.getProperty(PROP_GF_EMBEDDED_JAR) == null) {
                        props.setProperty(PROP_GF_EMBEDDED_JAR, systemDep.getAbsolutePath());
                    }
                    dep.setSystemPath("${"+PROP_GF_EMBEDDED_JAR+ "}");
                }
                return true;
            }
            return false;
        }

        @Override
        public String getText() {
            return fixDesc;
        }
     }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy