diff --git a/java.api.common/apichanges.xml b/java.api.common/apichanges.xml --- a/java.api.common/apichanges.xml +++ b/java.api.common/apichanges.xml @@ -105,6 +105,21 @@ + + + Added LogicalViewProviders support to create default implementation of the LogicalViewProvider2. + + + + + +

+ Added LogicalViewProviders support to create default implementation of the LogicalViewProvider2 + for Ant Based Project. +

+
+ +
Added ProjectHooks factory to create default implementation of the ProjectOpenedHook and the ProjectXmlSavedHook}. diff --git a/java.api.common/manifest.mf b/java.api.common/manifest.mf --- a/java.api.common/manifest.mf +++ b/java.api.common/manifest.mf @@ -1,4 +1,4 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.java.api.common/0 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/api/common/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.61 +OpenIDE-Module-Specification-Version: 1.62 diff --git a/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/Bundle.properties b/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/Bundle.properties --- a/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/Bundle.properties +++ b/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/Bundle.properties @@ -75,3 +75,7 @@ LBL_Properties_Action=Properties # {0} - folder name JavaSourceNodeFactory.gensrc=Generated Sources ({0}) + +#LogicalViewProviders +HINT_project_root_node=Java project in {0} +TP_CompileOnSaveDisabled=Compile on Save is disabled. It can be enabled in Project Properties. \ No newline at end of file diff --git a/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/LogicalViewProviders.java b/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/LogicalViewProviders.java new file mode 100644 --- /dev/null +++ b/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/LogicalViewProviders.java @@ -0,0 +1,559 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.java.api.common.project.ui; + +import java.awt.Color; +import java.awt.Image; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.CharConversionException; +import java.net.URL; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.api.java.project.JavaProjectConstants; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectInformation; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.ProjectUtils; +import org.netbeans.api.project.SourceGroup; +import org.netbeans.api.project.ui.ProjectProblems; +import org.netbeans.spi.java.project.support.ui.PackageView; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.netbeans.spi.project.ui.ProjectProblemsProvider; +import org.netbeans.spi.project.ui.support.CommonProjectActions; +import org.netbeans.spi.project.ui.support.DefaultProjectOperations; +import org.netbeans.spi.project.ui.support.NodeFactorySupport; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectNotFoundException; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Node; +import org.openide.util.ChangeSupport; +import org.openide.util.HelpCtx; +import org.openide.util.ImageUtilities; +import org.openide.util.Lookup; +import org.openide.util.NbBundle; +import org.openide.util.Parameters; +import org.openide.util.RequestProcessor; +import org.openide.util.WeakListeners; +import org.openide.util.lookup.AbstractLookup; +import org.openide.util.lookup.InstanceContent; +import org.openide.xml.XMLUtil; + +/** + * Support for creating default {@link LogicalViewProvider2} for Ant Based Project. + * @author Tomas Zezula + * @since 1.62 + */ +public final class LogicalViewProviders { + + private LogicalViewProviders() { + throw new IllegalStateException("No instance allowed"); //NOI18N + } + + + /** + * Creates a new {@link LogicalViewProviderBuilder}. + * @param project the project for which the builder should be created + * @param eval the project's {@link PropertyEvaluator} + * @param extensionFolder the extension point name + * @return the new {@link LogicalViewProviderBuilder} + */ + @NonNull + public static LogicalViewProviderBuilder createBuilder( + @NonNull final Project project, + @NonNull final PropertyEvaluator eval, + @NonNull final String extensionFolder) { + return new LogicalViewProviderBuilder( + project, + eval, + extensionFolder); + } + + + /** + * Builder for creating a new configured {@link LogicalViewProvider2} instance. + */ + public static class LogicalViewProviderBuilder { + + private final Project project; + private final PropertyEvaluator eval; + private final String projectType; + private HelpCtx helpContext; + private CompileOnSaveBadge badgeStatus; + + + private LogicalViewProviderBuilder( + @NonNull final Project project, + @NonNull final PropertyEvaluator eval, + @NonNull final String projectType) { + Parameters.notNull("project", project); //NOI18N + Parameters.notNull("eval", eval); //NOI18N + Parameters.notNull("projectType", projectType); //NOI18N + this.project = project; + this.eval = eval; + this.projectType = projectType; + } + + /** + * Sets a {@link HelpCtx}. + * @param helpContext the root node {@link HelpCtx} + * @return the {@link LogicalViewProviderBuilder} + */ + @NonNull + public LogicalViewProviderBuilder setHelpCtx(@NonNull final HelpCtx helpContext) { + Parameters.notNull("helpContext", helpContext); //NOI18N + this.helpContext = helpContext; + return this; + } + + /** + * Sets a compile on save badge status. + * @param badgeStatus the compile on save badge status + * @return the {@link LogicalViewProviderBuilder} + */ + @NonNull + public LogicalViewProviderBuilder setCompileOnSaveBadge(@NonNull final CompileOnSaveBadge badgeStatus) { + Parameters.notNull("badgeStatus", badgeStatus); //NOI18N + this.badgeStatus = badgeStatus; + return this; + } + + /** + * Creates a new configured {@link LogicalViewProvider2} instance. + * @return the {@link LogicalViewProvider2} instance + */ + @NonNull + public LogicalViewProvider2 build() { + return new LogicalViewProviderImpl( + project, + eval, + projectType, + helpContext, + badgeStatus); + } + + } + + + /** + * Compile on Save badge status. + * The {@link CompileOnSaveBadge} is used by {@link LogicalViewProvider2} + * to enable or disable the project badge notifying an user about disabled + * compile on save. + */ + public static interface CompileOnSaveBadge { + /** + * Badge visibility check. + * @return true if the badge should be visible + */ + boolean isBadgeVisible(); + /** + * Checks if the changed property affects the compile on save visibility. + * @param propertyName the name of changed property + * @return true if compile on save badge should be recalculated + */ + boolean isImportant(@NonNull String propertyName); + } + + + private static class LogicalViewProviderImpl implements LogicalViewProvider2 { + + private static final RequestProcessor RP = new RequestProcessor(LogicalViewProviders.class); + private static final String COMPILE_ON_SAVE_DISABLED_BADGE_PATH = "org/netbeans/modules/java/api/common/project/ui/resources/compileOnSaveDisabledBadge.gif"; //NOI18N + private static final Image compileOnSaveDisabledBadge; + static { + URL errorBadgeIconURL = LogicalViewProviders.class.getClassLoader().getResource(COMPILE_ON_SAVE_DISABLED_BADGE_PATH); + String compileOnSaveDisabledTP = " " + NbBundle.getMessage(LogicalViewProviders.class, "TP_CompileOnSaveDisabled"); + compileOnSaveDisabledBadge = ImageUtilities.assignToolTipToImage(ImageUtilities.loadImage(COMPILE_ON_SAVE_DISABLED_BADGE_PATH), compileOnSaveDisabledTP); + } + + private final Project project; + private final PropertyEvaluator evaluator; + private final String projectType; + private final HelpCtx helpContext; + private final CompileOnSaveBadge badgeStatus; + private final ChangeSupport changeSupport = new ChangeSupport(this); + private final PropertyChangeListener pcl; + private final RequestProcessor.Task task = RP.create(new Runnable() { + public @Override void run() { + setBroken(ProjectProblems.isBroken(project)); + setCompileOnSaveDisabled(isCompileOnSaveDisabled()); + } + }); + + private volatile boolean listenersInited; + private volatile boolean broken; //Represents a state where project has a broken reference repairable by broken reference support + private volatile boolean compileOnSaveDisabled; //true iff Compile-on-Save is disabled + + + public LogicalViewProviderImpl( + @NonNull final Project project, + @NonNull final PropertyEvaluator evaluator, + @NonNull final String projectType, + @NullAllowed final HelpCtx helpContext, + @NullAllowed final CompileOnSaveBadge badgeStatus) { + Parameters.notNull("project", project); //NOI18N + Parameters.notNull("evaluator", evaluator); //NOI18N + Parameters.notNull("projectType", projectType); //NOI18N + this.project = project; + this.evaluator = evaluator; + this.projectType = projectType; + this.helpContext = helpContext; + this.badgeStatus = badgeStatus; + pcl = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + final String propName = evt.getPropertyName(); + if (ProjectProblemsProvider.PROP_PROBLEMS.equals(evt.getPropertyName()) || + (badgeStatus != null && (propName == null || badgeStatus.isImportant(propName)))) { + testBroken(); + } + } + }; + } + + private void initListeners() { + if (listenersInited) { + return; + } + ProjectManager.mutex().readAccess(new Runnable() { + @Override + public void run() { + synchronized (LogicalViewProviderImpl.class) { + if (!listenersInited) { + evaluator.addPropertyChangeListener(pcl); + final ProjectProblemsProvider ppp = project.getLookup().lookup(ProjectProblemsProvider.class); + if (ppp != null) { + ppp.addPropertyChangeListener(pcl); + } + listenersInited = true; + } + } + } + }); + } + + @Override + public Node createLogicalView() { + initListeners(); + final InstanceContent ic = new InstanceContent(); + ic.add(project); + ic.add(project, new InstanceContent.Convertor() { + @Override + public FileObject convert(Project obj) { + return obj.getProjectDirectory(); + } + @Override + public Class type(Project obj) { + return FileObject.class; + } + @Override + public String id(Project obj) { + final FileObject fo = obj.getProjectDirectory(); + return fo == null ? "" : fo.getPath(); //NOI18N + } + @Override + public String displayName(Project obj) { + return obj.toString(); + } + }); + ic.add(project, new InstanceContent.Convertor() { + @Override + public DataObject convert(Project obj) { + try { + final FileObject fo = obj.getProjectDirectory(); + return fo == null ? null : DataObject.find(fo); + } catch (DataObjectNotFoundException ex) { + return null; + } + } + @Override + public Class type(Project obj) { + return DataObject.class; + } + @Override + public String id(Project obj) { + final FileObject fo = obj.getProjectDirectory(); + return fo == null ? "" : fo.getPath(); //NOI18N + } + @Override + public String displayName(Project obj) { + return obj.toString(); + } + }); + return new LogicalViewRootNode(new AbstractLookup(ic)); + } + + @Override + public Node findPath(Node root, Object target) { + Project prj = root.getLookup().lookup(Project.class); + if (prj == null) { + return null; + } + + if (target instanceof FileObject) { + FileObject fo = (FileObject) target; + if (isOtherProjectSource(fo, prj)) { + return null; // Don't waste time if project does not own the fo among sources + } + + for (Node n : root.getChildren().getNodes(true)) { + Node result = PackageView.findPath(n, target); + if (result != null) { + return result; + } + } + } + + return null; + } + + private static boolean isOtherProjectSource( + @NonNull final FileObject fo, + @NonNull final Project me) { + final Project owner = FileOwnerQuery.getOwner(fo); + if (owner == null) { + return false; + } + if (me.equals(owner)) { + return false; + } + for (SourceGroup sg : ProjectUtils.getSources(owner).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA)) { + if (FileUtil.isParentOf(sg.getRootFolder(), fo)) { + return true; + } + } + return false; + } + + public void addChangeListener(ChangeListener l) { + changeSupport.addChangeListener(l); + } + + public void removeChangeListener(ChangeListener l) { + changeSupport.removeChangeListener(l); + } + + @Override + public void testBroken() { + task.schedule(500); + } + + private boolean isCompileOnSaveDisabled() { + return badgeStatus != null && badgeStatus.isBadgeVisible(); + } + + private final class LogicalViewRootNode extends AbstractNode implements ChangeListener, PropertyChangeListener { + + private final ProjectInformation info; + + @SuppressWarnings("LeakingThisInConstructor") + LogicalViewRootNode(@NonNull final Lookup lkp) { + super(NodeFactorySupport.createCompositeChildren( + project, + String.format("Projects/%s/Nodes",projectType)), //NOI18N + lkp); + broken = ProjectProblems.isBroken(project); + compileOnSaveDisabled = isCompileOnSaveDisabled(); + addChangeListener(WeakListeners.change(this, LogicalViewProviderImpl.this)); + final ProjectInformation pi = project.getLookup().lookup(ProjectInformation.class); + info = pi != null ? pi : new SimpleInfo(project); + info.addPropertyChangeListener(WeakListeners.propertyChange(this, info)); + } + + @Override + public String getShortDescription() { + String prjDirDispName = FileUtil.getFileDisplayName(project.getProjectDirectory()); + return NbBundle.getMessage(LogicalViewProviderImpl.class, "HINT_project_root_node", prjDirDispName); + } + + @Override + public String getHtmlDisplayName() { + String dispName = super.getDisplayName(); + try { + dispName = XMLUtil.toElementContent(dispName); + } catch (CharConversionException ex) { + return dispName; + } + return broken ? "" + dispName + "" : null; //NOI18N + } + + @Override + public void stateChanged(ChangeEvent e) { + fireIconChange(); + fireOpenedIconChange(); + fireDisplayNameChange(null, null); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + RP.post(new Runnable() { + public @Override void run() { + fireNameChange(null, null); + fireDisplayNameChange(null, null); + } + }); + } + + @Override + public Action[] getActions( boolean context ) { + return CommonProjectActions.forType(projectType); + } + + @Override + public boolean canRename() { + return true; + } + + @Override + public String getName() { + return info.getDisplayName(); + } + + @Override + public void setName(String s) { + DefaultProjectOperations.performDefaultRenameOperation(project, s); + } + + @Override + public Image getIcon(int type) { + final Icon icon = info.getIcon(); + final Image img = icon == null ? + super.getIcon(type) : + ImageUtilities.icon2Image(icon); + return !broken && compileOnSaveDisabled ? + ImageUtilities.mergeImages(img, compileOnSaveDisabledBadge, 8, 0) : + img; + } + + @Override + public Image getOpenedIcon(int type) { + return getIcon(type); + } + + @Override + public HelpCtx getHelpCtx() { + return helpContext == null ? + super.getHelpCtx() : + helpContext; + } + + } + + // Private methods ------------------------------------------------- + + private void setBroken(boolean broken) { + //Weak consistent, only visibility required + if (this.broken != broken) { + this.broken = broken; + changeSupport.fireChange(); + } + } + + private void setCompileOnSaveDisabled (boolean value) { + //Weak consistent, only visibility required + if (this.compileOnSaveDisabled != value) { + this.compileOnSaveDisabled = value; + changeSupport.fireChange(); + } + } + + + @NonNull + private static Color getErrorForeground() { + Color result = UIManager.getDefaults().getColor("nb.errorForeground"); //NOI18N + if (result == null) { + result = Color.RED; + } + return result; + } + } + + private static final class SimpleInfo implements ProjectInformation { + + private final Project project; + + SimpleInfo(@NonNull final Project project) { + Parameters.notNull("project", project); //NOI18N + this.project = project; + } + + @Override + public String getName() { + return project.getProjectDirectory().getName(); + } + + @Override + public String getDisplayName() { + return getName(); + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public Project getProject() { + return project; + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener listener) { + //Immutable + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener listener) { + ////Immutable + } + } +} diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/resources/compileOnSaveDisabledBadge.gif b/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/resources/compileOnSaveDisabledBadge.gif rename from java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/resources/compileOnSaveDisabledBadge.gif rename to java.api.common/src/org/netbeans/modules/java/api/common/project/ui/resources/compileOnSaveDisabledBadge.gif diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java @@ -91,9 +91,9 @@ import org.netbeans.modules.java.api.common.classpath.ClassPathProviderImpl; import org.netbeans.modules.java.api.common.project.ProjectHooks; import org.netbeans.modules.java.api.common.project.ProjectProperties; +import org.netbeans.modules.java.api.common.project.ui.LogicalViewProviders; import org.netbeans.modules.java.api.common.queries.QuerySupport; import org.netbeans.modules.java.j2seproject.api.J2SEPropertyEvaluator; -import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider; import org.netbeans.modules.java.j2seproject.ui.customizer.CustomizerProviderImpl; import org.netbeans.modules.project.ui.spi.TemplateCategorySorter; import org.netbeans.spi.java.project.support.ExtraSourceJavadocSupport; @@ -136,6 +136,7 @@ import org.openide.filesystems.URLMapper; import org.openide.loaders.DataObject; import org.openide.modules.SpecificationVersion; +import org.openide.util.HelpCtx; /** * Represents one plain J2SE project. * @author Jesse Glick, et al. @@ -344,7 +345,6 @@ private Lookup createLookup(final AuxiliaryConfiguration aux, final J2SEProjectOperations ops) { final FileEncodingQueryImplementation encodingQuery = QuerySupport.createFileEncodingQuery(evaluator(), ProjectProperties.SOURCE_ENCODING); - final J2SELogicalViewProvider lvp = new J2SELogicalViewProvider(this, this.updateHelper, evaluator(), refHelper); final Lookup base = Lookups.fixed( J2SEProject.this, QuerySupport.createProjectInformation(updateHelper, this, J2SE_PROJECT_ICON), @@ -352,7 +352,13 @@ helper.createCacheDirectoryProvider(), helper.createAuxiliaryProperties(), refHelper.createSubprojectProvider(), - lvp, + LogicalViewProviders.createBuilder( + this, + eval, + "org-netbeans-modules-java-j2seproject"). //NOI18N + setHelpCtx(new HelpCtx("org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider.J2SELogicalViewRootNode")). //NOI18N + setCompileOnSaveBadge(newCoSBadge()). + build(), // new J2SECustomizerProvider(this, this.updateHelper, evaluator(), refHelper), new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper), LookupMergerSupport.createClassPathProviderMerger(cpProvider), @@ -410,7 +416,7 @@ QuerySupport.createAnnotationProcessingQuery(this.helper, this.evaluator(), ProjectProperties.ANNOTATION_PROCESSING_ENABLED, ProjectProperties.ANNOTATION_PROCESSING_ENABLED_IN_EDITOR, ProjectProperties.ANNOTATION_PROCESSING_RUN_ALL_PROCESSORS, ProjectProperties.ANNOTATION_PROCESSING_PROCESSORS_LIST, ProjectProperties.ANNOTATION_PROCESSING_SOURCE_OUTPUT, ProjectProperties.ANNOTATION_PROCESSING_PROCESSOR_OPTIONS), LookupProviderSupport.createActionProviderMerger(), WhiteListQueryMergerSupport.createWhiteListQueryMerger(), - BrokenReferencesSupport.createReferenceProblemsProvider(helper, refHelper, eval, lvp.getBreakableProperties(), lvp.getPlatformProperties()), + BrokenReferencesSupport.createReferenceProblemsProvider(helper, refHelper, eval, J2SEProjectUtil.getBreakableProperties(this), new String[]{ProjectProperties.PLATFORM_ACTIVE}), BrokenReferencesSupport.createPlatformVersionProblemProvider(helper, eval, new PlatformChangedHook(), JavaPlatform.getDefault().getSpecification().getName(), ProjectProperties.PLATFORM_ACTIVE, ProjectProperties.JAVAC_SOURCE, ProjectProperties.JAVAC_TARGET), BrokenReferencesSupport.createProfileProblemProvider(helper, refHelper, eval, ProjectProperties.JAVAC_PROFILE, ProjectProperties.RUN_CLASSPATH, ProjectProperties.ENDORSED_CLASSPATH), UILookupMergerSupport.createProjectProblemsProviderMerger(), @@ -975,4 +981,20 @@ } }; } + + @NonNull + private LogicalViewProviders.CompileOnSaveBadge newCoSBadge() { + return new LogicalViewProviders.CompileOnSaveBadge() { + @Override + public boolean isBadgeVisible() { + return !J2SEProjectUtil.isCompileOnSaveEnabled(J2SEProject.this) && + J2SEProjectUtil.isCompileOnSaveSupported(J2SEProject.this); + } + @Override + public boolean isImportant(@NonNull final String propertyName) { + return ProjectProperties.COMPILE_ON_SAVE.equals(propertyName) || + propertyName.startsWith(ProjectProperties.COMPILE_ON_SAVE_UNSUPPORTED_PREFIX); + } + }; + } } diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectUtil.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectUtil.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectUtil.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectUtil.java @@ -50,7 +50,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.logging.Logger; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.project.Project; +import org.netbeans.modules.java.api.common.SourceRoots; import org.netbeans.modules.java.api.common.project.ProjectProperties; import org.netbeans.spi.project.support.ant.GeneratedFilesHelper; import org.openide.filesystems.FileObject; @@ -63,6 +65,16 @@ */ public class J2SEProjectUtil { + private static final String[] BREAKABLE_PROPERTIES = { + ProjectProperties.JAVAC_CLASSPATH, + ProjectProperties.RUN_CLASSPATH, + ProjectProperties.DEBUG_CLASSPATH, + ProjectProperties.RUN_TEST_CLASSPATH, + ProjectProperties.DEBUG_TEST_CLASSPATH, + ProjectProperties.ENDORSED_CLASSPATH, + ProjectProperties.JAVAC_TEST_CLASSPATH, + }; + private static final Logger LOG = Logger.getLogger(J2SEProjectUtil.class.getName()); private J2SEProjectUtil () {} @@ -159,4 +171,20 @@ "on".equalsIgnoreCase(param); //NOI18N } + /** + * Returns a list of property names which need to be tested for broken references. + * @param project to return property names for + * @return the list of breakable properties + */ + public static String[] getBreakableProperties(@NonNull final J2SEProject project) { + SourceRoots roots = project.getSourceRoots(); + String[] srcRootProps = roots.getRootProperties(); + roots = project.getTestSourceRoots(); + String[] testRootProps = roots.getRootProperties(); + String[] result = new String [BREAKABLE_PROPERTIES.length + srcRootProps.length + testRootProps.length]; + System.arraycopy(BREAKABLE_PROPERTIES, 0, result, 0, BREAKABLE_PROPERTIES.length); + System.arraycopy(srcRootProps, 0, result, BREAKABLE_PROPERTIES.length, srcRootProps.length); + System.arraycopy(testRootProps, 0, result, BREAKABLE_PROPERTIES.length + srcRootProps.length, testRootProps.length); + return result; + } } diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/Bundle.properties b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/Bundle.properties --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/Bundle.properties +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/Bundle.properties @@ -83,9 +83,7 @@ TXT_UnknownProjectName=??? TXT_ProjectArtifactFormat={0} - {1} CTL_OpenProject=Open Project -HINT_project_root_node=Java project in {0} #RemoveClassPathRootAction CTL_RemoveProject=Remove -TP_CompileOnSaveDisabled=Compile on Save is disabled. It can be enabled in Project Properties. diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/J2SELogicalViewProvider.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/J2SELogicalViewProvider.java deleted file mode 100644 --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/J2SELogicalViewProvider.java +++ /dev/null @@ -1,438 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ - -package org.netbeans.modules.java.j2seproject.ui; - -import java.awt.Color; -import java.awt.Image; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.CharConversionException; -import java.net.URL; -import javax.swing.Action; -import javax.swing.UIManager; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import org.netbeans.api.annotations.common.NonNull; -import org.netbeans.api.java.project.JavaProjectConstants; -import org.netbeans.api.project.FileOwnerQuery; -import org.netbeans.api.project.Project; -import org.netbeans.api.project.ProjectInformation; -import org.netbeans.api.project.ProjectManager; -import org.netbeans.api.project.ProjectUtils; -import org.netbeans.api.project.SourceGroup; -import org.netbeans.api.project.ui.ProjectProblems; -import org.netbeans.modules.java.api.common.SourceRoots; -import org.netbeans.modules.java.api.common.ant.UpdateHelper; -import org.netbeans.modules.java.api.common.project.ProjectProperties; -import org.netbeans.modules.java.api.common.project.ui.LogicalViewProvider2; -import org.netbeans.modules.java.j2seproject.J2SEProjectUtil; -import org.netbeans.modules.java.j2seproject.J2SEProject; -import org.netbeans.spi.java.project.support.ui.PackageView; -import org.netbeans.spi.project.support.ant.PropertyEvaluator; -import org.netbeans.spi.project.support.ant.ReferenceHelper; -import org.netbeans.spi.project.ui.ProjectProblemsProvider; -import org.netbeans.spi.project.ui.support.CommonProjectActions; -import org.netbeans.spi.project.ui.support.NodeFactorySupport; -import org.netbeans.spi.project.ui.support.DefaultProjectOperations; -import org.openide.awt.ActionID; -import org.openide.awt.ActionReference; -import org.openide.awt.ActionReferences; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; -import org.openide.loaders.DataObject; -import org.openide.loaders.DataObjectNotFoundException; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.Node; -import org.openide.util.ChangeSupport; -import org.openide.util.HelpCtx; -import org.openide.util.ImageUtilities; -import org.openide.util.Lookup; -import org.openide.util.NbBundle; -import org.openide.util.RequestProcessor; -import org.openide.util.WeakListeners; -import org.openide.util.lookup.AbstractLookup; -import org.openide.util.lookup.InstanceContent; -import org.openide.xml.XMLUtil; - -/** - * Support for creating logical views. - * @author Petr Hrebejk - */ -@ActionReferences({ - @ActionReference( - id=@ActionID(id="org.netbeans.modules.project.ui.problems.BrokenProjectActionFactory",category="Project"), - position = 2600, - path = "Projects/org-netbeans-modules-java-j2seproject/Actions") -}) -public class J2SELogicalViewProvider implements LogicalViewProvider2 { - - private static final RequestProcessor RP = new RequestProcessor(J2SELogicalViewProvider.class); - private static final String[] BREAKABLE_PROPERTIES = { - ProjectProperties.JAVAC_CLASSPATH, - ProjectProperties.RUN_CLASSPATH, - ProjectProperties.DEBUG_CLASSPATH, - ProjectProperties.RUN_TEST_CLASSPATH, - ProjectProperties.DEBUG_TEST_CLASSPATH, - ProjectProperties.ENDORSED_CLASSPATH, - ProjectProperties.JAVAC_TEST_CLASSPATH, - }; - private static final String COMPILE_ON_SAVE_DISABLED_BADGE_PATH = "org/netbeans/modules/java/j2seproject/ui/resources/compileOnSaveDisabledBadge.gif"; - private static final Image compileOnSaveDisabledBadge; - - static { - URL errorBadgeIconURL = J2SELogicalViewProvider.class.getClassLoader().getResource(COMPILE_ON_SAVE_DISABLED_BADGE_PATH); - String compileOnSaveDisabledTP = " " + NbBundle.getMessage(J2SELogicalViewProvider.class, "TP_CompileOnSaveDisabled"); - compileOnSaveDisabledBadge = ImageUtilities.assignToolTipToImage(ImageUtilities.loadImage(COMPILE_ON_SAVE_DISABLED_BADGE_PATH), compileOnSaveDisabledTP); // NOI18N - } - - private final J2SEProject project; - private final UpdateHelper helper; - private final PropertyEvaluator evaluator; - private final ReferenceHelper resolver; - private final ChangeSupport changeSupport = new ChangeSupport(this); - private final PropertyChangeListener pcl; - private final RequestProcessor.Task task = RP.create(new Runnable() { - public @Override void run() { - setBroken(ProjectProblems.isBroken(project)); - setCompileOnSaveDisabled(isCompileOnSaveDisabled()); - } - }); - - private volatile boolean listenersInited; - private volatile boolean broken; //Represents a state where project has a broken reference repairable by broken reference support - private volatile boolean compileOnSaveDisabled; //true iff Compile-on-Save is disabled - - public J2SELogicalViewProvider(J2SEProject project, UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper resolver) { - this.project = project; - assert project != null; - this.helper = helper; - assert helper != null; - this.evaluator = evaluator; - assert evaluator != null; - this.resolver = resolver; - assert resolver != null; - pcl = new PropertyChangeListener() { - public @Override void propertyChange(PropertyChangeEvent evt) { - final String propName = evt.getPropertyName(); - if (propName == null || - ProjectProblemsProvider.PROP_PROBLEMS.equals(evt.getPropertyName()) || - ProjectProperties.COMPILE_ON_SAVE.equals(evt.getPropertyName()) || - propName.startsWith(ProjectProperties.COMPILE_ON_SAVE_UNSUPPORTED_PREFIX)) { - testBroken(); - } - } - }; - } - - private void initListeners() { - if (listenersInited) { - return; - } - ProjectManager.mutex().readAccess(new Runnable() { - @Override - public void run() { - synchronized (J2SELogicalViewProvider.class) { - if (!listenersInited) { - evaluator.addPropertyChangeListener(pcl); - final ProjectProblemsProvider ppp = project.getLookup().lookup(ProjectProblemsProvider.class); - if (ppp != null) { - ppp.addPropertyChangeListener(pcl); - } - listenersInited = true; - } - } - } - }); - } - - @Override - public Node createLogicalView() { - initListeners(); - final InstanceContent ic = new InstanceContent(); - ic.add(project); - ic.add(project, new InstanceContent.Convertor() { - @Override - public FileObject convert(J2SEProject obj) { - return obj.getProjectDirectory(); - } - @Override - public Class type(J2SEProject obj) { - return FileObject.class; - } - @Override - public String id(J2SEProject obj) { - final FileObject fo = obj.getProjectDirectory(); - return fo == null ? "" : fo.getPath(); //NOI18N - } - @Override - public String displayName(J2SEProject obj) { - return obj.toString(); - } - }); - ic.add(project, new InstanceContent.Convertor() { - @Override - public DataObject convert(J2SEProject obj) { - try { - final FileObject fo = obj.getProjectDirectory(); - return fo == null ? null : DataObject.find(fo); - } catch (DataObjectNotFoundException ex) { - return null; - } - } - @Override - public Class type(J2SEProject obj) { - return DataObject.class; - } - @Override - public String id(J2SEProject obj) { - final FileObject fo = obj.getProjectDirectory(); - return fo == null ? "" : fo.getPath(); //NOI18N - } - @Override - public String displayName(J2SEProject obj) { - return obj.toString(); - } - }); - return new J2SELogicalViewRootNode(new AbstractLookup(ic)); - } - - public PropertyEvaluator getEvaluator() { - return evaluator; - } - - public ReferenceHelper getRefHelper() { - return resolver; - } - - public UpdateHelper getUpdateHelper() { - return helper; - } - - @Override - public Node findPath(Node root, Object target) { - Project prj = root.getLookup().lookup(Project.class); - if (prj == null) { - return null; - } - - if (target instanceof FileObject) { - FileObject fo = (FileObject) target; - if (isOtherProjectSource(fo, prj)) { - return null; // Don't waste time if project does not own the fo among sources - } - - for (Node n : root.getChildren().getNodes(true)) { - Node result = PackageView.findPath(n, target); - if (result != null) { - return result; - } - } - } - - return null; - } - - private static boolean isOtherProjectSource( - @NonNull final FileObject fo, - @NonNull final Project me) { - final Project owner = FileOwnerQuery.getOwner(fo); - if (owner == null) { - return false; - } - if (me.equals(owner)) { - return false; - } - for (SourceGroup sg : ProjectUtils.getSources(owner).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA)) { - if (FileUtil.isParentOf(sg.getRootFolder(), fo)) { - return true; - } - } - return false; - } - - public void addChangeListener(ChangeListener l) { - changeSupport.addChangeListener(l); - } - - public void removeChangeListener(ChangeListener l) { - changeSupport.removeChangeListener(l); - } - - @Override - public void testBroken() { - task.schedule(500); - } - - public String[] getBreakableProperties() { - SourceRoots roots = this.project.getSourceRoots(); - String[] srcRootProps = roots.getRootProperties(); - roots = this.project.getTestSourceRoots(); - String[] testRootProps = roots.getRootProperties(); - String[] result = new String [BREAKABLE_PROPERTIES.length + srcRootProps.length + testRootProps.length]; - System.arraycopy(BREAKABLE_PROPERTIES, 0, result, 0, BREAKABLE_PROPERTIES.length); - System.arraycopy(srcRootProps, 0, result, BREAKABLE_PROPERTIES.length, srcRootProps.length); - System.arraycopy(testRootProps, 0, result, BREAKABLE_PROPERTIES.length + srcRootProps.length, testRootProps.length); - return result; - } - - public String[] getPlatformProperties() { - return new String[] {ProjectProperties.PLATFORM_ACTIVE}; - } - - private boolean isCompileOnSaveDisabled() { - return !J2SEProjectUtil.isCompileOnSaveEnabled(project) && J2SEProjectUtil.isCompileOnSaveSupported(project); - } - - private final class J2SELogicalViewRootNode extends AbstractNode implements ChangeListener, PropertyChangeListener { - - private final ProjectInformation info = ProjectUtils.getInformation(project); - - @SuppressWarnings("LeakingThisInConstructor") - J2SELogicalViewRootNode(@NonNull final Lookup lkp) { - super(NodeFactorySupport.createCompositeChildren(project, "Projects/org-netbeans-modules-java-j2seproject/Nodes"), - lkp); - setIconBaseWithExtension("org/netbeans/modules/java/j2seproject/ui/resources/j2seProject.png"); - broken = ProjectProblems.isBroken(project); - compileOnSaveDisabled = isCompileOnSaveDisabled(); - addChangeListener(WeakListeners.change(this, J2SELogicalViewProvider.this)); - info.addPropertyChangeListener(WeakListeners.propertyChange(this, info)); - } - - @Override - public String getShortDescription() { - String prjDirDispName = FileUtil.getFileDisplayName(project.getProjectDirectory()); - return NbBundle.getMessage(J2SELogicalViewProvider.class, "HINT_project_root_node", prjDirDispName); - } - - @Override - public String getHtmlDisplayName() { - String dispName = super.getDisplayName(); - try { - dispName = XMLUtil.toElementContent(dispName); - } catch (CharConversionException ex) { - return dispName; - } - return broken ? "" + dispName + "" : null; //NOI18N - } - - @Override - public Image getIcon(int type) { - final Image original = super.getIcon(type); - return !broken && compileOnSaveDisabled ? ImageUtilities.mergeImages(original, compileOnSaveDisabledBadge, 8, 0) : original; - } - - @Override - public Image getOpenedIcon(int type) { - final Image original = super.getOpenedIcon(type); - return !broken && compileOnSaveDisabled ? ImageUtilities.mergeImages(original, compileOnSaveDisabledBadge, 8, 0) : original; - } - - public @Override void stateChanged(ChangeEvent e) { - fireIconChange(); - fireOpenedIconChange(); - fireDisplayNameChange(null, null); - } - - public @Override void propertyChange(PropertyChangeEvent evt) { - RP.post(new Runnable() { - public @Override void run() { - fireNameChange(null, null); - fireDisplayNameChange(null, null); - } - }); - } - - @Override - public Action[] getActions( boolean context ) { - return CommonProjectActions.forType("org-netbeans-modules-java-j2seproject"); // NOI18N - } - - @Override - public boolean canRename() { - return true; - } - - public @Override String getName() { - return info.getDisplayName(); - } - - @Override - public void setName(String s) { - DefaultProjectOperations.performDefaultRenameOperation(project, s); - } - - @Override - public HelpCtx getHelpCtx() { - return new HelpCtx(J2SELogicalViewRootNode.class); - } - - } - - // Private methods ------------------------------------------------- - - private void setBroken(boolean broken) { - //Weak consistent, only visibility required - if (this.broken != broken) { - this.broken = broken; - changeSupport.fireChange(); - } - } - - private void setCompileOnSaveDisabled (boolean value) { - //Weak consistent, only visibility required - if (this.compileOnSaveDisabled != value) { - this.compileOnSaveDisabled = value; - changeSupport.fireChange(); - } - } - - private static @NonNull Color getErrorForeground() { - Color result = UIManager.getDefaults().getColor("nb.errorForeground"); //NOI18N - if (result == null) { - result = Color.RED; - } - return result; - } -} diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/LibrariesNodeFactory.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/LibrariesNodeFactory.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/LibrariesNodeFactory.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/LibrariesNodeFactory.java @@ -54,6 +54,7 @@ import javax.swing.Action; import javax.swing.SwingUtilities; import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.project.Project; import org.netbeans.modules.java.api.common.SourceRoots; import org.netbeans.modules.java.api.common.ant.UpdateHelper; @@ -70,6 +71,7 @@ import org.openide.nodes.Node; import org.openide.util.ChangeSupport; import org.openide.util.NbBundle; +import org.openide.util.Parameters; import org.openide.util.Utilities; /** @@ -102,14 +104,13 @@ private ReferenceHelper resolver; private final ClassPathSupport cs; - LibrariesNodeList(J2SEProject proj) { + LibrariesNodeList(@NonNull final J2SEProject proj) { + Parameters.notNull("proj", proj); //NOI18N project = proj; testSources = project.getTestSourceRoots(); - J2SELogicalViewProvider logView = project.getLookup().lookup(J2SELogicalViewProvider.class); - assert logView != null; - evaluator = logView.getEvaluator(); - helper = logView.getUpdateHelper(); - resolver = logView.getRefHelper(); + evaluator = project.evaluator(); + helper = project.getUpdateHelper(); + resolver = project.getReferenceHelper(); cs = new ClassPathSupport(evaluator, resolver, helper.getAntProjectHelper(), helper, null); } @@ -143,7 +144,7 @@ if (key == LIBRARIES) { //Libraries Node return - new LibrariesNode(NbBundle.getMessage(J2SELogicalViewProvider.class,"CTL_LibrariesNode"), + new LibrariesNode(NbBundle.getMessage(LibrariesNodeFactory.class,"CTL_LibrariesNode"), project, evaluator, helper, resolver, ProjectProperties.RUN_CLASSPATH, new String[] {ProjectProperties.BUILD_CLASSES_DIR}, "platform.active", // NOI18N @@ -160,7 +161,7 @@ ); } else if (key == TEST_LIBRARIES) { return - new LibrariesNode(NbBundle.getMessage(J2SELogicalViewProvider.class,"CTL_TestLibrariesNode"), + new LibrariesNode(NbBundle.getMessage(LibrariesNodeFactory.class,"CTL_TestLibrariesNode"), project, evaluator, helper, resolver, ProjectProperties.RUN_TEST_CLASSPATH, new String[] { ProjectProperties.BUILD_TEST_CLASSES_DIR, diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java @@ -58,9 +58,9 @@ import org.netbeans.api.project.libraries.LibraryManager; import org.netbeans.modules.java.api.common.classpath.ClassPathSupport; import org.netbeans.modules.java.api.common.project.ui.ClassPathUiSupport; +import org.netbeans.modules.java.api.common.project.ui.LogicalViewProvider2; import org.netbeans.modules.java.api.common.project.ui.customizer.EditMediator; import org.netbeans.modules.java.api.common.ui.PlatformUiSupport; -import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider; import org.netbeans.spi.java.project.support.ui.SharableLibrariesUtils; import org.netbeans.spi.project.support.ant.PropertyUtils; import org.netbeans.spi.project.ui.support.ProjectCustomizer; @@ -298,7 +298,7 @@ else { category.setErrorMessage(null); } - J2SELogicalViewProvider viewProvider = uiProperties.getProject().getLookup().lookup(J2SELogicalViewProvider.class); + LogicalViewProvider2 viewProvider = uiProperties.getProject().getLookup().lookup(LogicalViewProvider2.class); //Update the state of project's node if needed viewProvider.testBroken(); } diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/package-info.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/package-info.java new file mode 100644 --- /dev/null +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/package-info.java @@ -0,0 +1,54 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ + +@ActionReferences({ + @ActionReference( + id=@ActionID(id="org.netbeans.modules.project.ui.problems.BrokenProjectActionFactory",category="Project"), + position = 2600, + path = "Projects/org-netbeans-modules-java-j2seproject/Actions") +}) +package org.netbeans.modules.java.j2seproject.ui; + +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +