/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.tvl.goworks.project; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; import javax.swing.Icon; import javax.swing.ImageIcon; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.java.classpath.GlobalPathRegistry; import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectInformation; import org.netbeans.spi.project.CopyOperationImplementation; import org.netbeans.spi.project.DeleteOperationImplementation; import org.netbeans.spi.project.ProjectState; import org.netbeans.spi.project.ui.ProjectOpenedHook; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; /** * * @author Sam Harwell */ public class GoProject implements Project { // -J-Dorg.tvl.goworks.project.GoProject.level=FINE private static final Logger LOGGER = Logger.getLogger(GoProject.class.getName()); public static final String SOURCE = "go/classpath/source"; public static final String PLATFORM = "go/classpath/platform"; public static final String GO_PROJECT_ID = "org-tvl-goworks-go-project"; private final FileObject projectDir; private final boolean isStandardLibrary; private final ProjectState state; private Lookup lkp; public GoProject(FileObject projectDir, ProjectState state) { this.projectDir = projectDir; this.state = state; String goroot = System.getenv("GOROOT"); if (goroot != null) { File gorootFile = new File(goroot); FileObject gorootFileObject = FileUtil.toFileObject(gorootFile); isStandardLibrary = projectDir.equals(gorootFileObject); } else { isStandardLibrary = false; } } @Override public FileObject getProjectDirectory() { return projectDir; } public FileObject getSourceRoot() { if (isStandardLibrary()) { return getProjectDirectory().getFileObject("src/pkg"); } else { return getProjectDirectory().getFileObject("src"); } } public boolean isStandardLibrary() { return isStandardLibrary; } public List<? extends GoProject> getLibraryProjects() { if (isStandardLibrary) { return Collections.emptyList(); } Set<GoProject> projects = new HashSet<>(); Set<? extends ClassPath> platformPaths = GlobalPathRegistry.getDefault().getPaths(PLATFORM); for (ClassPath path : platformPaths) { for (FileObject root : path.getRoots()) { Project project = FileOwnerQuery.getOwner(root); if (project instanceof GoProject) { projects.add((GoProject)project); } } } projects.remove(this); return new ArrayList<>(projects); } //The project type's capabilities are registered in the project's lookup: @Override public Lookup getLookup() { if (lkp == null) { lkp = Lookups.fixed(new Object[]{ this, state, //allow outside code to mark the project as needing saving new GoActionProvider(this), //Provides standard actions like Build and Clean new GoDeleteOperation(), new GoCopyOperation(this), new Info(), //Project information implementation new GoProjectLogicalView(this), //Logical view of project implementation new ProjectOpenedHookImpl(), new ClassPathProviderImpl(this), new GoSourcesImpl(this), }); } return lkp; } private final class GoDeleteOperation implements DeleteOperationImplementation { @Override public void notifyDeleting() throws IOException { } @Override public void notifyDeleted() throws IOException { } @Override public List<FileObject> getMetadataFiles() { List<FileObject> dataFiles = new ArrayList<>(); return dataFiles; } @Override public List<FileObject> getDataFiles() { List<FileObject> dataFiles = new ArrayList<>(); return dataFiles; } } private final class GoCopyOperation implements CopyOperationImplementation { private final GoProject project; private final FileObject projectDir; public GoCopyOperation(GoProject project) { this.project = project; this.projectDir = project.getProjectDirectory(); } @Override public List<FileObject> getMetadataFiles() { return Collections.emptyList(); } @Override public List<FileObject> getDataFiles() { return Collections.emptyList(); } @Override public void notifyCopying() throws IOException { } @Override public void notifyCopied(Project arg0, File arg1, String arg2) throws IOException { } } private final class Info implements ProjectInformation { @Override public Icon getIcon() { return new ImageIcon(ImageUtilities.loadImage( "org/tvl/goworks/project/ui/resources/icon1.png")); } @Override public String getName() { return getProjectDirectory().getName(); } @Override public String getDisplayName() { return getName(); } @Override public void addPropertyChangeListener(PropertyChangeListener pcl) { //do nothing, won't change } @Override public void removePropertyChangeListener(PropertyChangeListener pcl) { //do nothing, won't change } @Override public Project getProject() { return GoProject.this; } } private final class ProjectOpenedHookImpl extends ProjectOpenedHook { @Override protected void projectOpened() { // register project's classpaths to GlobalPathRegistry FileObject sourceRoot = getSourceRoot(); if (sourceRoot != null && sourceRoot.isFolder()) { ClassPath sourceRootClassPath = ClassPath.getClassPath(sourceRoot, SOURCE); if (sourceRootClassPath != null) { GlobalPathRegistry.getDefault().register(GoProject.SOURCE, new ClassPath[] { sourceRootClassPath }); } } String goroot = System.getenv("GOROOT"); if (goroot != null) { File gorootFile = new File(goroot); if (gorootFile.isDirectory()) { FileObject stdlibRootFile = FileUtil.toFileObject(gorootFile); final FileObject stdlibSourceRoot = stdlibRootFile.getFileObject("src/pkg"); if (stdlibSourceRoot != null && stdlibSourceRoot.isFolder()) { ClassPath stdLibRoot = ClassPath.getClassPath(stdlibSourceRoot, PLATFORM); if (stdLibRoot != null) { GlobalPathRegistry.getDefault().register(PLATFORM, new ClassPath[] { stdLibRoot }); } } } } } @Override protected void projectClosed() { FileObject sourceRoot = getSourceRoot(); if (sourceRoot != null && sourceRoot.isFolder()) { ClassPath sourceRootClassPath = ClassPath.getClassPath(sourceRoot, SOURCE); if (sourceRootClassPath != null) { GlobalPathRegistry.getDefault().unregister(GoProject.SOURCE, new ClassPath[] { sourceRootClassPath }); } } String goroot = System.getenv("GOROOT"); if (goroot != null) { File gorootFile = new File(goroot); if (gorootFile.isDirectory()) { FileObject stdlibRootFile = FileUtil.toFileObject(gorootFile); final FileObject stdlibSourceRoot = stdlibRootFile.getFileObject("src/pkg"); if (stdlibSourceRoot != null && stdlibSourceRoot.isFolder()) { ClassPath stdLibRoot = ClassPath.getClassPath(stdlibSourceRoot, PLATFORM); if (stdLibRoot != null) { GlobalPathRegistry.getDefault().unregister(PLATFORM, new ClassPath[] { stdLibRoot }); } } } } } } }