blob: 62d8e94c484dc09ce6705a03701d99342cd11a0e [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;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.event.ChangeListener;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.spi.project.ProjectContainerProvider;
import org.netbeans.spi.project.ProjectServiceProvider;
import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.ChangeSupport;
/**
* finds subprojects (projects this one depends on) that are locally available
* and can be build as one unit. Uses maven multiproject infrastructure. (maven.multiproject.includes)
* @author Milos Kleint
*/
@ProjectServiceProvider(service=ProjectContainerProvider.class, projectType="org-netbeans-modules-maven")
public class ProjectContainerProviderImpl implements ProjectContainerProvider {
private final Project project;
private final ChangeSupport cs = new ChangeSupport(this);
private final PropertyChangeListener propertyChange;
public ProjectContainerProviderImpl(Project proj) {
project = proj;
propertyChange = new PropertyChangeListener() {
@Override public void propertyChange(PropertyChangeEvent evt) {
//TODO effectively we should listen on all "pom" child projects as well here.
//but is someone actually currently listening on SubprojectProvider changes?
if (NbMavenProject.PROP_PROJECT.equals(evt.getPropertyName())) {
cs.fireChange();
}
}
};
}
@Override
public Result getContainedProjects() {
Set<Project> projects = new HashSet<Project>();
File basedir = FileUtil.toFile(project.getProjectDirectory());
try {
addProjectModules(basedir, projects, project.getLookup().lookup(NbMavenProject.class).getMavenProject().getModules());
} catch (InterruptedException x) {
// can be interrupted in the open project dialog..
return new Result(Collections.<Project>emptySet(), false);
}
projects.remove(project);
return new Result(projects, false);
}
private boolean isProcessed(Set<Project> resultset, FileObject projectDir) {
for (Project p : resultset) {
if (p.getProjectDirectory().equals(projectDir)) {
return true;
}
}
return false;
}
private void addProjectModules(File basedir, Set<Project> resultset, List<String> modules) throws InterruptedException {
if (modules == null) {
return;
}
for (String path : modules) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
if (path.trim().length() == 0) {
//#175331
continue;
}
File sub = new File(basedir, path);
File projectFile = FileUtil.normalizeFile(sub);
if (!projectFile.equals(basedir) //#175331
&& projectFile.exists()) {
FileObject projectDir = FileUtil.toFileObject(projectFile);
if (projectDir != null && projectDir.isFolder() && !isProcessed(resultset, projectDir)) {
Project proj = processOneSubproject(projectDir);
NbMavenProjectImpl mv = proj != null ? proj.getLookup().lookup(NbMavenProjectImpl.class) : null;
if (mv != null) {
resultset.add(proj);
// if (resultset.add(proj)) { //prevent cycles
//no recursion
// addProjectModules(FileUtil.toFile(mv.getProjectDirectory()),
// resultset, mv.getOriginalMavenProject().getModules());
// }
}
} else {
// HUH?
ErrorManager.getDefault().log("fileobject not found=" + sub); //NOI18N
}
} else {
ErrorManager.getDefault().log("project file not found=" + sub); //NOI18N
}
}
}
private Project processOneSubproject(FileObject projectDir) {
try {
return ProjectManager.getDefault().findProject(projectDir);
} catch (IOException exc) {
ErrorManager.getDefault().notify(exc);
}
return null;
}
@Override public synchronized void addChangeListener(ChangeListener changeListener) {
if (!cs.hasListeners()) {
project.getLookup().lookup(NbMavenProject.class).addPropertyChangeListener(propertyChange);
}
cs.addChangeListener(changeListener);
}
@Override public synchronized void removeChangeListener(ChangeListener changeListener) {
cs.removeChangeListener(changeListener);
if (!cs.hasListeners()) {
project.getLookup().lookup(NbMavenProject.class).removePropertyChangeListener(propertyChange);
}
}
}