blob: cbd70f41a9556111fa1e4fec39c55c4c39146a04 [file] [log] [blame]
/*
* 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.apisupport;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.SwingUtilities;
import org.netbeans.api.project.Project;
import org.netbeans.modules.java.api.common.ant.PackageModifierImplementation;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.model.ModelOperation;
import org.netbeans.modules.maven.model.Utilities;
import org.netbeans.modules.maven.model.pom.Build;
import org.netbeans.modules.maven.model.pom.Configuration;
import org.netbeans.modules.maven.model.pom.POMExtensibilityElement;
import org.netbeans.modules.maven.model.pom.POMModel;
import org.netbeans.modules.maven.model.pom.POMQName;
import org.netbeans.modules.maven.model.pom.Plugin;
import org.netbeans.modules.maven.model.pom.PluginContainer;
import org.netbeans.modules.maven.model.pom.PluginManagement;
import org.netbeans.spi.project.ProjectServiceProvider;
import org.netbeans.spi.project.ui.LogicalViewProvider;
import org.openide.explorer.ExplorerManager;
import org.openide.filesystems.FileObject;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
/**
*
* @author mkleint
*/
@ProjectServiceProvider(service = PackageModifierImplementation.class, projectType="org-netbeans-modules-maven/" + NbMavenProject.TYPE_NBM)
public class MavenPackageModifierImpl implements PackageModifierImplementation {
private final Project project;
public MavenPackageModifierImpl(Project p) {
this.project = p;
}
static final String ID_LOGICAL = "projectTabLogical_tc"; // NOI18N
@Override
public void exportPackageAction(final Collection<String> packagesToExport, final boolean export) {
final PropertyChangeListener prop = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!NbMavenProject.PROP_PROJECT.equals(evt.getPropertyName())) {
return;
}
try {
FileObject srcdir = org.netbeans.modules.maven.api.FileUtilities.convertStringToFileObject(project.getLookup().lookup(NbMavenProject.class).getMavenProject().getBuild().getSourceDirectory());
if (srcdir != null) {
LogicalViewProvider lvp = project.getLookup().lookup(LogicalViewProvider.class);
assert lvp != null;
Node root = findProjectTCRootNode();
if (root != null) {
for (Node prjNode : root.getChildren().getNodes(true)) {
Project p = prjNode.getLookup().lookup(Project.class);
if (project.equals(p)) {
Node found = lvp.findPath(prjNode, srcdir);
if (found != null) {
iterateNodesAndFireIconChange(found);
}
break;
}
}
}
}
} finally {
project.getLookup().lookup(NbMavenProject.class).removePropertyChangeListener(this);
}
}
//ugly reflection to force a change of icon badge
private void iterateNodesAndFireIconChange(Node found) {
for (Node nd : found.getChildren().getNodes(true)) {
FileObject fo = nd.getLookup().lookup(FileObject.class);
if (fo != null && fo.isFolder() && fo.isFolder()) {
try {
Method m1 = Node.class.getDeclaredMethod("fireIconChange");
m1.setAccessible(true);
Method m2 = Node.class.getDeclaredMethod("fireOpenedIconChange");
m2.setAccessible(true);
m2.invoke(nd);
m1.invoke(nd);
} catch (NoSuchMethodException ex) {
Exceptions.printStackTrace(ex);
} catch (SecurityException ex) {
Exceptions.printStackTrace(ex);
} catch (IllegalAccessException ex) {
Exceptions.printStackTrace(ex);
} catch (IllegalArgumentException ex) {
Exceptions.printStackTrace(ex);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
}
iterateNodesAndFireIconChange(nd);
}
}
}
//ugly way of finding the shown root package node to fire iconChange events
private Node findProjectTCRootNode() {
final Node[] toRet = new Node[1];
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
TopComponent projecttc = WindowManager.getDefault().findTopComponent(ID_LOGICAL);
if (projecttc != null && projecttc instanceof ExplorerManager.Provider) {
ExplorerManager.Provider em = (ExplorerManager.Provider) projecttc;
Node root = em.getExplorerManager().getRootContext();
toRet[0] = root;
}
}
});
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
}
return toRet[0];
}
};
Utilities.performPOMModelOperations(project.getProjectDirectory().getFileObject("pom.xml"),
Collections.singletonList(new ModelOperation<POMModel>() {
@Override
public void performOperation(POMModel model) {
org.netbeans.modules.maven.model.pom.Project p = model.getProject();
Build bld = p.getBuild();
POMExtensibilityElement publicPackages = null;
if (bld != null) {
publicPackages = findPublicPackagesElement(bld);
if (publicPackages != null) {
//find in pluginmanagement
PluginManagement pm = bld.getPluginManagement();
if (pm != null) {
publicPackages = findPublicPackagesElement(pm);
}
}
}
if (publicPackages == null && export) {
publicPackages = createPublicPackagesElement(p);
assert publicPackages != null;
}
if (export) {
for (String exp : packagesToExport) {
POMExtensibilityElement pack = model.getFactory().createPOMExtensibilityElement(POMQName.createQName("publicPackage"));
publicPackages.addExtensibilityElement(pack);
pack.setElementText(exp);
}
} else {
//find the right publicPackage element and remove it.
//TODO what to do with subpackages?
Set<POMExtensibilityElement> toRemove = new HashSet<POMExtensibilityElement>();
LBL : for (String exp : packagesToExport) {
for (POMExtensibilityElement el : publicPackages.getExtensibilityElements()) {
if ("publicPackage".equals(el.getQName().getLocalPart()) && el.getElementText() != null && el.getElementText().equals(exp)) {
toRemove.add(el);
continue LBL;
}
}
//TODO not in the current file's list or is covered by subpackage?
}
if (!toRemove.isEmpty()) {
for (POMExtensibilityElement el : toRemove) {
publicPackages.removeExtensibilityElement(el);
}
if (publicPackages.getChildren() == null || publicPackages.getChildren().isEmpty()) {
publicPackages.getParent().removeExtensibilityElement(publicPackages);
}
}
}
project.getLookup().lookup(NbMavenProject.class).addPropertyChangeListener(prop);
}
private POMExtensibilityElement createPublicPackagesElement(org.netbeans.modules.maven.model.pom.Project p) {
Build bld = p.getBuild();
if (bld == null) {
bld = p.getModel().getFactory().createBuild();
p.setBuild(bld);
}
Plugin plug = findNbmPlugin(bld);
if (plug == null) {
//mostly should not happen with nb modules..
plug = bld.getModel().getFactory().createPlugin();
// create on new groupID
plug.setGroupId("org.apache.netbeans.utilities");
plug.setArtifactId("nbm-maven-plugin");
plug.setExtensions(Boolean.TRUE);
//set version? let's hope it's managed..
bld.addPlugin(plug);
}
Configuration conf = plug.getConfiguration();
if (conf == null) {
conf = plug.getModel().getFactory().createConfiguration();
plug.setConfiguration(conf);
}
List<POMExtensibilityElement> elems = conf.getConfigurationElements();
if (elems != null) {
for (POMExtensibilityElement el : elems) {
if ("publicPackages".equals(el.getQName().getLocalPart())) {
return el;
}
}
}
POMExtensibilityElement toRet = conf.getModel().getFactory().createPOMExtensibilityElement(POMQName.createQName("publicPackages"));
conf.addExtensibilityElement(toRet);
return toRet;
}
private POMExtensibilityElement findPublicPackagesElement(PluginContainer bld) {
POMExtensibilityElement publicPackages = null;
Plugin plug = findNbmPlugin(bld);
if (plug != null) {
Configuration conf = plug.getConfiguration();
if (conf != null) {
List<POMExtensibilityElement> elems = conf.getConfigurationElements();
if (elems != null) {
for (POMExtensibilityElement el : elems) {
if ("publicPackages".equals(el.getQName().getLocalPart())) {
publicPackages = el;
break;
}
}
}
}
}
return publicPackages;
}
}));
}
private Plugin findNbmPlugin(PluginContainer build) {
// check old groupid of nbm maven plugin
Plugin plugin = build.findPluginById("org.codehaus.mojo", "nbm-maven-plugin");
// check new groupid of nbm maven plugins
if (plugin == null) {
plugin = build.findPluginById("org.apache.netbeans.utilities", "nbm-maven-plugin");
}
return plugin;
}
}