| /* |
| * 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.cpplite.project; |
| |
| import java.beans.PropertyChangeListener; |
| import java.io.IOException; |
| import java.util.concurrent.atomic.AtomicReference; |
| import java.util.prefs.BackingStoreException; |
| import java.util.prefs.Preferences; |
| import javax.swing.Icon; |
| import org.netbeans.api.java.classpath.ClassPath; |
| import org.netbeans.api.java.classpath.GlobalPathRegistry; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectInformation; |
| import org.netbeans.api.project.ProjectManager; |
| import org.netbeans.modules.cpplite.project.ui.customizer.CustomizerProviderImpl; |
| import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
| import org.netbeans.spi.project.ProjectFactory; |
| import org.netbeans.spi.project.ProjectFactory2; |
| import org.netbeans.spi.project.ProjectState; |
| import org.netbeans.spi.project.ui.PrivilegedTemplates; |
| import org.netbeans.spi.project.ui.ProjectOpenedHook; |
| import org.netbeans.spi.project.ui.RecommendedTemplates; |
| import org.openide.filesystems.FileObject; |
| import org.openide.util.ImageUtilities; |
| import org.openide.util.Lookup; |
| import org.openide.util.NbPreferences; |
| import org.openide.util.lookup.Lookups; |
| import org.openide.util.lookup.ServiceProvider; |
| |
| /** |
| * |
| * @author lahvac |
| */ |
| public class CPPLiteProject implements Project { |
| |
| public static final String PROJECT_KEY = "org-netbeans-modules-cpplite-project-CPPLiteProject"; |
| public static final String KEY_COMPILE_COMMANDS = "compile-commands"; |
| public static final String KEY_COMPILE_COMMANDS_EXECUTABLE = "compile-commands-executable"; |
| public static final String KEY_NEXT_MARK = "next-mark"; |
| public static final String KEY_IS_PROJECT = "is-project"; |
| |
| public static Preferences getRootPreferences(FileObject root) { |
| return getRootPreferences(root, true); |
| } |
| |
| private static Preferences getRootPreferences(FileObject root, boolean create) { |
| String encoded = root.toURI().toString().replace("/", "."); |
| Preferences projectsRoot = NbPreferences.forModule(CPPLiteProject.class).node("projects"); |
| try { |
| for (String key : projectsRoot.keys()) { |
| if (encoded.equals(projectsRoot.get(key, null))) { |
| return projectsRoot.node(key); |
| } |
| } |
| } catch (BackingStoreException ex) { |
| } |
| if (!create) { |
| return null; |
| } |
| synchronized (CPPLiteProject.class) { |
| int mark = projectsRoot.getInt(KEY_NEXT_MARK, 0); |
| String key = Integer.toHexString(mark); |
| projectsRoot.putInt(KEY_NEXT_MARK, mark + 1); |
| projectsRoot.put(key, encoded); |
| return projectsRoot.node(key); |
| } |
| } |
| |
| public static Preferences getBuildPreferences(FileObject root) { |
| return getRootPreferences(root).node("build"); |
| } |
| |
| private final FileObject projectDirectory; |
| private final Lookup lookup; |
| private final AtomicReference<BuildConfiguration> buildConfigurations = new AtomicReference<>(); |
| |
| private CPPLiteProject(FileObject projectDirectory) { |
| this.projectDirectory = projectDirectory; |
| this.lookup = Lookups.fixed(new LogicalViewProviderImpl(this), |
| new ActionProviderImpl(this), |
| new CustomizerProviderImpl(this), |
| new CPPLiteCProjectConfigurationProvider(getRootPreferences(projectDirectory)), |
| new RecommendedTemplatesImpl(), |
| new PrivilegedTemplatesImpl(), |
| new ProjectInfo(this), |
| new ProjectOpenHookImpl(this), |
| this); |
| buildConfigurations.set(BuildConfiguration.read(getBuildPreferences(projectDirectory))); |
| } |
| |
| @Override |
| public FileObject getProjectDirectory() { |
| return projectDirectory; |
| } |
| |
| @Override |
| public Lookup getLookup() { |
| return lookup; |
| } |
| |
| public BuildConfiguration getActiveBuildConfiguration() { |
| return buildConfigurations.get(); |
| } |
| |
| public void setActiveBuildConfiguration(BuildConfiguration config) { |
| buildConfigurations.set(config); |
| } |
| |
| public String getCompileCommands() { |
| return getRootPreferences(projectDirectory).get(KEY_COMPILE_COMMANDS, ""); |
| } |
| |
| public void setCompileCommands(String compileCommands) { |
| getRootPreferences(projectDirectory).put(KEY_COMPILE_COMMANDS, compileCommands); |
| } |
| |
| public String getCompileCommandsExecutable() { |
| return getRootPreferences(projectDirectory).get(KEY_COMPILE_COMMANDS_EXECUTABLE, ""); |
| } |
| |
| public void setCompileCommandsExecutable(String compileCommandsExecutable) { |
| getRootPreferences(projectDirectory).put(KEY_COMPILE_COMMANDS_EXECUTABLE, compileCommandsExecutable); |
| } |
| |
| private static Icon loadProjectIcon() { |
| return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/cpplite/project/resources/project.gif")); |
| } |
| |
| @ServiceProvider(service=ProjectFactory.class) |
| public static final class FactoryImpl implements ProjectFactory2 { |
| |
| @Override |
| public ProjectManager.Result isProject2(FileObject projectDirectory) { |
| Preferences prefs = getRootPreferences(projectDirectory, false); |
| if (prefs != null && prefs.getBoolean(KEY_IS_PROJECT, false)) { |
| return new ProjectManager.Result(loadProjectIcon()); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean isProject(FileObject projectDirectory) { |
| return isProject2(projectDirectory) != null; |
| } |
| |
| @Override |
| public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException { |
| if (isProject(projectDirectory)) { |
| return new CPPLiteProject(projectDirectory); |
| } |
| return null; |
| } |
| |
| @Override |
| public void saveProject(Project project) throws IOException, ClassCastException { |
| } |
| |
| } |
| |
| private static class RecommendedTemplatesImpl implements RecommendedTemplates { |
| |
| private static final String[] TEMPLATES = new String[] { |
| "cpplite" |
| }; |
| |
| @Override |
| public String[] getRecommendedTypes() { |
| return TEMPLATES; |
| } |
| } |
| |
| private static class PrivilegedTemplatesImpl implements PrivilegedTemplates { |
| |
| private static final String[] TEMPLATES = new String[] { |
| "Templates/cpplite/CTemplate.c", |
| "Templates/cpplite/CPPTemplate.cpp", |
| "Templates/cpplite/HTemplate.h", |
| "Templates/cpplite/HPPTemplate.hpp", |
| }; |
| |
| @Override |
| public String[] getPrivilegedTemplates() { |
| return TEMPLATES; |
| } |
| } |
| |
| private static final class ProjectInfo implements ProjectInformation { |
| |
| private final Project prj; |
| |
| public ProjectInfo(Project prj) { |
| this.prj = prj; |
| } |
| |
| @Override |
| public String getName() { |
| return prj.getProjectDirectory().getNameExt(); |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return prj.getProjectDirectory().getNameExt(); |
| } |
| |
| @Override |
| public Icon getIcon() { |
| return loadProjectIcon(); |
| } |
| |
| @Override |
| public Project getProject() { |
| return prj; |
| } |
| |
| @Override |
| public void addPropertyChangeListener(PropertyChangeListener listener) {} |
| |
| @Override |
| public void removePropertyChangeListener(PropertyChangeListener listener) {} |
| |
| } |
| |
| private static final class ProjectOpenHookImpl extends ProjectOpenedHook { |
| |
| private final ClassPath source; |
| |
| public ProjectOpenHookImpl(Project prj) { |
| this.source = ClassPathSupport.createClassPath(prj.getProjectDirectory()); |
| } |
| |
| @Override |
| protected void projectOpened() { |
| GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {source}); |
| } |
| |
| @Override |
| protected void projectClosed() { |
| GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {source}); |
| } |
| |
| } |
| } |