0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.apisupport.project.ui.customizer;
0043:
0044: import java.awt.EventQueue;
0045: import java.beans.PropertyChangeEvent;
0046: import java.beans.PropertyChangeListener;
0047: import java.beans.PropertyEditor;
0048: import java.io.File;
0049: import java.io.IOException;
0050: import java.lang.reflect.InvocationTargetException;
0051: import java.text.Collator;
0052: import java.util.Arrays;
0053: import java.util.Comparator;
0054: import java.util.HashMap;
0055: import java.util.HashSet;
0056: import java.util.Iterator;
0057: import java.util.LinkedHashSet;
0058: import java.util.Map;
0059: import java.util.Set;
0060: import java.util.SortedMap;
0061: import java.util.SortedSet;
0062: import java.util.TreeMap;
0063: import java.util.TreeSet;
0064: import javax.swing.event.ChangeEvent;
0065: import javax.swing.event.ChangeListener;
0066: import org.netbeans.api.java.platform.JavaPlatform;
0067: import org.netbeans.api.java.platform.PlatformsCustomizer;
0068: import org.netbeans.api.project.ProjectUtils;
0069: import org.netbeans.modules.apisupport.project.ManifestManager;
0070: import org.netbeans.modules.apisupport.project.NbModuleProject;
0071: import org.netbeans.modules.apisupport.project.NbModuleProjectType;
0072: import org.netbeans.modules.apisupport.project.Util;
0073: import org.netbeans.modules.apisupport.project.suite.SuiteProject;
0074: import org.netbeans.modules.apisupport.project.ui.UIUtil;
0075: import org.netbeans.modules.apisupport.project.ui.platform.PlatformComponentFactory;
0076: import org.netbeans.modules.apisupport.project.ui.platform.NbPlatformCustomizer;
0077: import org.netbeans.modules.apisupport.project.universe.ModuleEntry;
0078: import org.netbeans.modules.apisupport.project.universe.NbPlatform;
0079: import org.netbeans.spi.project.ui.support.ProjectCustomizer;
0080: import org.openide.ErrorManager;
0081: import org.openide.NotifyDescriptor;
0082: import org.openide.explorer.ExplorerManager;
0083: import org.openide.modules.Dependency;
0084: import org.openide.modules.SpecificationVersion;
0085: import org.openide.nodes.AbstractNode;
0086: import org.openide.nodes.Children;
0087: import org.openide.nodes.Node;
0088: import org.openide.nodes.PropertySupport;
0089: import org.openide.nodes.Sheet;
0090: import org.openide.util.NbBundle;
0091: import org.openide.util.RequestProcessor;
0092: import org.w3c.dom.Element;
0093:
0094: /**
0095: * Represents <em>Libraries</em> panel in Suite customizer.
0096: *
0097: * @author Martin Krauskopf
0098: */
0099: final class SuiteCustomizerLibraries extends NbPropertyPanel.Suite
0100: implements Comparator<Node>, ExplorerManager.Provider,
0101: ChangeListener {
0102: private final ExplorerManager manager;
0103: private ModuleEntry[] platformModules;
0104: static boolean TEST = false;
0105:
0106: /**
0107: * Creates new form SuiteCustomizerLibraries
0108: */
0109: public SuiteCustomizerLibraries(final SuiteProperties suiteProps,
0110: ProjectCustomizer.Category cat) {
0111: super (suiteProps, SuiteCustomizerLibraries.class, cat);
0112: initComponents();
0113: initAccessibility();
0114: manager = new ExplorerManager();
0115: refresh();
0116:
0117: view
0118: .setProperties(new Node.Property[] { ENABLED_PROP_TEMPLATE });
0119: view.setRootVisible(false);
0120: view.setDefaultActionAllowed(false);
0121:
0122: suiteProps.getBrandingModel().addChangeListener(this );
0123: suiteProps
0124: .addPropertyChangeListener(new PropertyChangeListener() {
0125: public void propertyChange(PropertyChangeEvent evt) {
0126: if (SuiteProperties.NB_PLATFORM_PROPERTY
0127: .equals(evt.getPropertyName())) {
0128: refresh();
0129: }
0130: }
0131: });
0132:
0133: javaPlatformCombo.setRenderer(JavaPlatformComponentFactory
0134: .javaPlatformListCellRenderer());
0135: }
0136:
0137: void refresh() {
0138: refreshJavaPlatforms();
0139: refreshPlatforms();
0140: Runnable r = new Runnable() {
0141: public void run() {
0142: refreshModules();
0143: }
0144: };
0145: if (TEST) {
0146: r.run();
0147: } else {
0148: RequestProcessor.getDefault().post(r);
0149: }
0150: updateJavaPlatformEnabled();
0151: }
0152:
0153: private void refreshModules() {
0154: platformModules = getProperties().getActivePlatform()
0155: .getModules();
0156: Node root = createPlatformModulesNode();
0157: manager.setRootContext(root);
0158: synchronized (this ) {
0159: universe = null;
0160: }
0161: updateDependencyWarnings();
0162: }
0163:
0164: private void refreshJavaPlatforms() {
0165: javaPlatformCombo.setModel(JavaPlatformComponentFactory
0166: .javaPlatformListModel());
0167: javaPlatformCombo.setSelectedItem(getProperties()
0168: .getActiveJavaPlatform());
0169: }
0170:
0171: private void refreshPlatforms() {
0172: platformValue
0173: .setModel(new PlatformComponentFactory.NbPlatformListModel(
0174: getProperties().getActivePlatform())); // refresh
0175: platformValue.requestFocus();
0176: }
0177:
0178: @Override
0179: public void store() {
0180: Set<String> enabledClusters = new TreeSet<String>();
0181: Set<String> disabledModules = new TreeSet<String>();
0182:
0183: for (Node cluster : getExplorerManager().getRootContext()
0184: .getChildren().getNodes()) {
0185: if (cluster instanceof Enabled) {
0186: Enabled e = (Enabled) cluster;
0187: if (e.isEnabled()) {
0188: enabledClusters.add(e.getName());
0189: for (Node module : e.getChildren().getNodes()) {
0190: if (module instanceof Enabled) {
0191: Enabled m = (Enabled) module;
0192: if (!m.isEnabled()) {
0193: disabledModules.add(m.getName());
0194: }
0195: }
0196: }
0197: }
0198: }
0199: }
0200:
0201: getProperties().setEnabledClusters(
0202: enabledClusters.toArray(new String[enabledClusters
0203: .size()]));
0204: getProperties().setDisabledModules(
0205: disabledModules.toArray(new String[disabledModules
0206: .size()]));
0207: }
0208:
0209: /** This method is called from within the constructor to
0210: * initialize the form.
0211: * WARNING: Do NOT modify this code. The content of this method is
0212: * always regenerated by the Form Editor.
0213: */
0214: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
0215: private void initComponents() {
0216: java.awt.GridBagConstraints gridBagConstraints;
0217:
0218: platformsPanel = new javax.swing.JPanel();
0219: platformValue = org.netbeans.modules.apisupport.project.ui.platform.PlatformComponentFactory
0220: .getNbPlatformsComboxBox();
0221: platform = new javax.swing.JLabel();
0222: managePlafsButton = new javax.swing.JButton();
0223: javaPlatformLabel = new javax.swing.JLabel();
0224: javaPlatformCombo = new javax.swing.JComboBox();
0225: javaPlatformButton = new javax.swing.JButton();
0226: filler = new javax.swing.JLabel();
0227: view = new org.openide.explorer.view.TreeTableView();
0228: viewLabel = new javax.swing.JLabel();
0229:
0230: setLayout(new java.awt.GridBagLayout());
0231:
0232: platformsPanel.setLayout(new java.awt.GridBagLayout());
0233:
0234: platformValue
0235: .addItemListener(new java.awt.event.ItemListener() {
0236: public void itemStateChanged(
0237: java.awt.event.ItemEvent evt) {
0238: platformValueItemStateChanged(evt);
0239: }
0240: });
0241:
0242: gridBagConstraints = new java.awt.GridBagConstraints();
0243: gridBagConstraints.gridx = 1;
0244: gridBagConstraints.gridy = 1;
0245: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
0246: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
0247: gridBagConstraints.weightx = 1.0;
0248: gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 12);
0249: platformsPanel.add(platformValue, gridBagConstraints);
0250:
0251: platform.setLabelFor(platformValue);
0252: org.openide.awt.Mnemonics.setLocalizedText(platform,
0253: org.openide.util.NbBundle.getMessage(
0254: SuiteCustomizerLibraries.class,
0255: "LBL_NetBeansPlatform"));
0256: gridBagConstraints = new java.awt.GridBagConstraints();
0257: gridBagConstraints.gridx = 0;
0258: gridBagConstraints.gridy = 1;
0259: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
0260: gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 12);
0261: platformsPanel.add(platform, gridBagConstraints);
0262:
0263: org.openide.awt.Mnemonics.setLocalizedText(managePlafsButton,
0264: org.openide.util.NbBundle.getMessage(
0265: SuiteCustomizerLibraries.class,
0266: "CTL_ManagePlatform_a"));
0267: managePlafsButton
0268: .addActionListener(new java.awt.event.ActionListener() {
0269: public void actionPerformed(
0270: java.awt.event.ActionEvent evt) {
0271: managePlatforms(evt);
0272: }
0273: });
0274:
0275: gridBagConstraints = new java.awt.GridBagConstraints();
0276: gridBagConstraints.gridx = 2;
0277: gridBagConstraints.gridy = 1;
0278: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
0279: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
0280: gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0);
0281: platformsPanel.add(managePlafsButton, gridBagConstraints);
0282:
0283: javaPlatformLabel.setLabelFor(javaPlatformCombo);
0284: org.openide.awt.Mnemonics.setLocalizedText(javaPlatformLabel,
0285: NbBundle.getMessage(SuiteCustomizerLibraries.class,
0286: "LBL_Java_Platform"));
0287: gridBagConstraints = new java.awt.GridBagConstraints();
0288: gridBagConstraints.gridx = 0;
0289: gridBagConstraints.gridy = 0;
0290: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
0291: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
0292: platformsPanel.add(javaPlatformLabel, gridBagConstraints);
0293:
0294: javaPlatformCombo
0295: .addItemListener(new java.awt.event.ItemListener() {
0296: public void itemStateChanged(
0297: java.awt.event.ItemEvent evt) {
0298: javaPlatformComboItemStateChanged(evt);
0299: }
0300: });
0301:
0302: gridBagConstraints = new java.awt.GridBagConstraints();
0303: gridBagConstraints.gridx = 1;
0304: gridBagConstraints.gridy = 0;
0305: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
0306: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
0307: gridBagConstraints.weightx = 1.0;
0308: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
0309: platformsPanel.add(javaPlatformCombo, gridBagConstraints);
0310:
0311: org.openide.awt.Mnemonics.setLocalizedText(javaPlatformButton,
0312: NbBundle.getMessage(SuiteCustomizerLibraries.class,
0313: "LBL_Manage_Java_Platforms"));
0314: javaPlatformButton
0315: .addActionListener(new java.awt.event.ActionListener() {
0316: public void actionPerformed(
0317: java.awt.event.ActionEvent evt) {
0318: javaPlatformButtonActionPerformed(evt);
0319: }
0320: });
0321:
0322: gridBagConstraints = new java.awt.GridBagConstraints();
0323: gridBagConstraints.gridx = 2;
0324: gridBagConstraints.gridy = 0;
0325: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
0326: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
0327: platformsPanel.add(javaPlatformButton, gridBagConstraints);
0328:
0329: gridBagConstraints = new java.awt.GridBagConstraints();
0330: gridBagConstraints.gridx = 0;
0331: gridBagConstraints.gridy = 0;
0332: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
0333: gridBagConstraints.weightx = 1.0;
0334: add(platformsPanel, gridBagConstraints);
0335:
0336: gridBagConstraints = new java.awt.GridBagConstraints();
0337: gridBagConstraints.gridx = 0;
0338: gridBagConstraints.gridy = 1;
0339: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
0340: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
0341: gridBagConstraints.weighty = 1.0;
0342: add(filler, gridBagConstraints);
0343:
0344: view.setBorder(javax.swing.UIManager
0345: .getBorder("ScrollPane.border"));
0346: gridBagConstraints = new java.awt.GridBagConstraints();
0347: gridBagConstraints.gridx = 0;
0348: gridBagConstraints.gridy = 2;
0349: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
0350: gridBagConstraints.weightx = 1.0;
0351: gridBagConstraints.weighty = 1.0;
0352: add(view, gridBagConstraints);
0353:
0354: viewLabel.setLabelFor(view);
0355: org.openide.awt.Mnemonics.setLocalizedText(viewLabel,
0356: org.openide.util.NbBundle.getMessage(
0357: SuiteCustomizerLibraries.class,
0358: "LBL_PlatformModules"));
0359: gridBagConstraints = new java.awt.GridBagConstraints();
0360: gridBagConstraints.gridx = 0;
0361: gridBagConstraints.gridy = 1;
0362: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
0363: gridBagConstraints.insets = new java.awt.Insets(18, 0, 2, 0);
0364: add(viewLabel, gridBagConstraints);
0365:
0366: }// </editor-fold>//GEN-END:initComponents
0367:
0368: private void javaPlatformButtonActionPerformed(
0369: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_javaPlatformButtonActionPerformed
0370: PlatformsCustomizer
0371: .showCustomizer((JavaPlatform) javaPlatformCombo
0372: .getSelectedItem());
0373: }//GEN-LAST:event_javaPlatformButtonActionPerformed
0374:
0375: private void javaPlatformComboItemStateChanged(
0376: java.awt.event.ItemEvent evt) {//GEN-FIRST:event_javaPlatformComboItemStateChanged
0377: getProperties().setActiveJavaPlatform(
0378: (JavaPlatform) javaPlatformCombo.getSelectedItem());
0379: }//GEN-LAST:event_javaPlatformComboItemStateChanged
0380:
0381: private void platformValueItemStateChanged(
0382: java.awt.event.ItemEvent evt) {//GEN-FIRST:event_platformValueItemStateChanged
0383: getProperties().setActivePlatform(
0384: (NbPlatform) platformValue.getSelectedItem());
0385: EventQueue.invokeLater(new Runnable() { // #98622: may be in Children.MUTEX read lock here
0386: public void run() {
0387: refreshModules();
0388: }
0389: });
0390: updateJavaPlatformEnabled();
0391: }//GEN-LAST:event_platformValueItemStateChanged
0392:
0393: private void managePlatforms(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_managePlatforms
0394: NbPlatformCustomizer.showCustomizer();
0395: refreshPlatforms();
0396: }//GEN-LAST:event_managePlatforms
0397:
0398: // Variables declaration - do not modify//GEN-BEGIN:variables
0399: private javax.swing.JLabel filler;
0400: private javax.swing.JButton javaPlatformButton;
0401: private javax.swing.JComboBox javaPlatformCombo;
0402: private javax.swing.JLabel javaPlatformLabel;
0403: private javax.swing.JButton managePlafsButton;
0404: private javax.swing.JLabel platform;
0405: private javax.swing.JComboBox platformValue;
0406: private javax.swing.JPanel platformsPanel;
0407: private org.openide.explorer.view.TreeTableView view;
0408: private javax.swing.JLabel viewLabel;
0409:
0410: // End of variables declaration//GEN-END:variables
0411:
0412: private Node createPlatformModulesNode() {
0413: Set<String> disabledModuleCNB = new HashSet<String>(Arrays
0414: .asList(getProperties().getDisabledModules()));
0415: Set<String> enabledClusters = new HashSet<String>(Arrays
0416: .asList(getProperties().getEnabledClusters()));
0417:
0418: Map<File, Children> clusterToChildren = new HashMap<File, Children>();
0419:
0420: Children.SortedArray clusters = new Children.SortedArray();
0421: clusters.setComparator(this );
0422: AbstractNode n = new AbstractNode(clusters);
0423: n.setName(getMessage("LBL_ModuleListClusters"));
0424: n.setDisplayName(getMessage("LBL_ModuleListClustersModules"));
0425:
0426: for (ModuleEntry platformModule : platformModules) {
0427: Children clusterChildren = clusterToChildren
0428: .get(platformModule.getClusterDirectory());
0429: if (clusterChildren == null) {
0430: Children.SortedArray modules = new Children.SortedArray();
0431: modules.setComparator(this );
0432: clusterChildren = modules;
0433:
0434: String clusterName = platformModule
0435: .getClusterDirectory().getName();
0436: Enabled cluster = new Enabled(modules, enabledClusters
0437: .contains(clusterName));
0438: cluster.setName(clusterName);
0439: cluster
0440: .setIconBaseWithExtension(SuiteProject.SUITE_ICON_PATH);
0441: clusterToChildren.put(platformModule
0442: .getClusterDirectory(), modules);
0443: n.getChildren().add(new Node[] { cluster });
0444: }
0445:
0446: String cnb = platformModule.getCodeNameBase();
0447: AbstractNode module = new Enabled(Children.LEAF,
0448: !disabledModuleCNB.contains(cnb));
0449: module.setName(cnb);
0450: module.setDisplayName(platformModule.getLocalizedName());
0451: String desc = platformModule.getShortDescription();
0452: String tooltip;
0453: if (desc != null) {
0454: if (desc.startsWith("<html>")) { // NOI18N
0455: tooltip = "<html>"
0456: + NbBundle
0457: .getMessage(
0458: SuiteCustomizerLibraries.class,
0459: "SuiteCustomizerLibraries.HINT_module_desc",
0460: cnb, desc.substring(6));
0461: } else {
0462: tooltip = NbBundle
0463: .getMessage(
0464: SuiteCustomizerLibraries.class,
0465: "SuiteCustomizerLibraries.HINT_module_desc",
0466: cnb, desc);
0467: }
0468: } else {
0469: tooltip = NbBundle.getMessage(
0470: SuiteCustomizerLibraries.class,
0471: "SuiteCustomizerLibraries.HINT_module_no_desc",
0472: cnb);
0473: }
0474: module.setShortDescription(tooltip);
0475: module
0476: .setIconBaseWithExtension(NbModuleProject.NB_PROJECT_ICON_PATH);
0477:
0478: clusterChildren.add(new Node[] { module });
0479: }
0480:
0481: return n;
0482: }
0483:
0484: public int compare(Node n1, Node n2) {
0485: return n1.getDisplayName().compareTo(n2.getDisplayName());
0486: }
0487:
0488: public ExplorerManager getExplorerManager() {
0489: return manager;
0490: }
0491:
0492: private static final Set<String> DISABLED_PLATFORM_MODULES = new HashSet<String>();
0493:
0494: static {
0495: // Probably not needed for most platform apps, and won't even work under JNLP.
0496: DISABLED_PLATFORM_MODULES
0497: .add("org.netbeans.modules.autoupdate.services"); // NOI18N
0498: DISABLED_PLATFORM_MODULES
0499: .add("org.netbeans.modules.autoupdate.ui"); // NOI18N
0500: // XXX the following would not be shown in regular apps anyway, because they are autoloads,
0501: // but they *are* shown in JNLP apps because currently even unused autoloads are enabled under JNLP:
0502: // Just annoying; e.g. shows Runtime tab prominently.
0503: DISABLED_PLATFORM_MODULES.add("org.openide.execution"); // NOI18N
0504: DISABLED_PLATFORM_MODULES.add("org.netbeans.core.execution"); // NOI18N
0505: // Similar - unlikely to really be wanted by typical platform apps, and show some GUI.
0506: /* XXX #107870: currently org.netbeans.core.actions.LogAction needs OW:
0507: DISABLED_PLATFORM_MODULES.add("org.openide.io"); // NOI18N
0508: DISABLED_PLATFORM_MODULES.add("org.netbeans.core.output2"); // NOI18N
0509: */
0510: DISABLED_PLATFORM_MODULES.add("org.netbeans.core.multiview"); // NOI18N
0511: // this one is useful only for writers of apps showing local disk
0512: DISABLED_PLATFORM_MODULES.add("org.netbeans.modules.favorites"); // NOI18N
0513: // And these are deprecated:
0514: DISABLED_PLATFORM_MODULES.add("org.openide.compat"); // NOI18N
0515: DISABLED_PLATFORM_MODULES.add("org.openide.util.enumerations"); // NOI18N
0516: // See issue #112931
0517: DISABLED_PLATFORM_MODULES.add("org.netbeans.modules.core.kit"); // NOI18N
0518: // #110085: some more unwanted ones...
0519: DISABLED_PLATFORM_MODULES.add("org.netbeans.modules.templates"); // NOI18N
0520: DISABLED_PLATFORM_MODULES.add("org.netbeans.libs.jsr223"); // NOI18N
0521: DISABLED_PLATFORM_MODULES.add("org.openide.options"); // NOI18N
0522: DISABLED_PLATFORM_MODULES.add("org.netbeans.api.visual"); // NOI18N
0523:
0524: }
0525:
0526: public void stateChanged(ChangeEvent ev) {
0527: if (getProperties().getBrandingModel().isBrandingEnabled()) {
0528: // User is turning on branded mode. Let's take a guess: they want to
0529: // exclude the usual suspects from the module list. We do not want to set
0530: // these excludes on a new suite because user might want to use real IDE as the platform
0531: // (i.e. not be creating an app, but rather be creating some modules for the IDE).
0532: // Only do this if there are no existing exclusions.
0533: Node[] clusters = getExplorerManager().getRootContext()
0534: .getChildren().getNodes();
0535: for (Node cluster : clusters) {
0536: if (cluster instanceof Enabled) {
0537: Enabled e = (Enabled) cluster;
0538: if (!e.isEnabled()) {
0539: return;
0540: } else {
0541: for (Node module : e.getChildren().getNodes()) {
0542: if (module instanceof Enabled) {
0543: Enabled m = (Enabled) module;
0544: if (!m.isEnabled()) {
0545: return;
0546: }
0547: }
0548: }
0549: }
0550: }
0551: }
0552: // #64443: prompt first.
0553: if (!UIUtil
0554: .showAcceptCancelDialog(
0555: getMessage("SuiteCustomizerLibraries.title.exclude_ide_modules"),
0556: getMessage("SuiteCustomizerLibraries.text.exclude_ide_modules"),
0557: getMessage("SuiteCustomizerLibraries.button.exclude"),
0558: getMessage("SuiteCustomizerLibraries.button.skip"),
0559: NotifyDescriptor.QUESTION_MESSAGE)) {
0560: return;
0561: }
0562: // OK, continue.
0563: for (Node cluster : clusters) {
0564: if (cluster instanceof Enabled) {
0565: Enabled e = (Enabled) cluster;
0566: if (e.getName().startsWith("platform")) { // NOI18N
0567: for (Node module : e.getChildren().getNodes()) {
0568: if (module instanceof Enabled) {
0569: Enabled m = (Enabled) module;
0570: if (DISABLED_PLATFORM_MODULES
0571: .contains(m.getName())) {
0572: m.setEnabled(false);
0573: }
0574: }
0575: }
0576: } else {
0577: e.setEnabled(false);
0578: }
0579: }
0580: }
0581: }
0582: }
0583:
0584: final class Enabled extends AbstractNode {
0585: private boolean enabled;
0586: private Children standard;
0587:
0588: public Enabled(Children ch, boolean enabled) {
0589: super (ch);
0590: this .standard = ch;
0591: this .enabled = enabled;
0592:
0593: Sheet s = Sheet.createDefault();
0594: Sheet.Set ss = s.get(Sheet.PROPERTIES);
0595: ss.put(new EnabledProp(this ));
0596: setSheet(s);
0597: }
0598:
0599: public void setEnabled(boolean s) {
0600: if (s == enabled) {
0601: return;
0602: }
0603: enabled = s;
0604: //refresh childern
0605: for (Node nn : standard.getNodes()) {
0606: if (nn instanceof Enabled) {
0607: Enabled en = (Enabled) nn;
0608: en.firePropertyChange(null, null, null);
0609: }
0610: }
0611: //refresh parent
0612: Node n = getParentNode();
0613: if (n instanceof Enabled) {
0614: Enabled en = (Enabled) n;
0615: en.firePropertyChange(null, null, null);
0616: }
0617: updateDependencyWarnings();
0618: }
0619:
0620: public boolean isEnabled() {
0621: return enabled;
0622: }
0623: }
0624:
0625: private static final EnabledProp ENABLED_PROP_TEMPLATE = new EnabledProp(
0626: null);
0627:
0628: private static final class EnabledProp extends
0629: PropertySupport.ReadWrite<Boolean> {
0630:
0631: private Enabled node;
0632: private PropertyEditor editor;
0633:
0634: public EnabledProp(Enabled node) {
0635: super ("enabled", Boolean.TYPE,
0636: getMessage("LBL_ModuleListEnabled"),
0637: getMessage("LBL_ModuleListEnabledShortDescription"));
0638: this .node = node;
0639: }
0640:
0641: public void setValue(Boolean val)
0642: throws IllegalAccessException,
0643: IllegalArgumentException, InvocationTargetException {
0644: node.setEnabled(val);
0645: }
0646:
0647: public Boolean getValue() throws IllegalAccessException,
0648: InvocationTargetException {
0649: Children ch = node.getChildren();
0650: if (ch == Children.LEAF) {
0651: return node.isEnabled();
0652: } else {
0653: boolean on = false;
0654: boolean off = false;
0655: for (Node n : ch.getNodes()) {
0656: if (((Enabled) n).isEnabled()) {
0657: on = true;
0658: } else {
0659: off = true;
0660: }
0661:
0662: if (on && off && node.isEnabled()) {
0663: return null;
0664: }
0665: }
0666:
0667: return on && node.isEnabled();
0668: }
0669: }
0670:
0671: @Override
0672: public boolean canWrite() {
0673: Node parent = node.getParentNode();
0674: if (parent instanceof Enabled) {
0675: // cluster node
0676: return ((Enabled) parent).isEnabled();
0677: }
0678: return true;
0679: }
0680:
0681: @Override
0682: public PropertyEditor getPropertyEditor() {
0683: if (editor == null) {
0684: editor = super .getPropertyEditor();
0685: }
0686: return editor;
0687: }
0688:
0689: }
0690:
0691: private static String getMessage(String key) {
0692: return NbBundle.getMessage(CustomizerDisplay.class, key);
0693: }
0694:
0695: private void initAccessibility() {
0696: managePlafsButton.getAccessibleContext()
0697: .setAccessibleDescription(
0698: getMessage("ACSD_ManagePlafsButton"));
0699: platformValue.getAccessibleContext().setAccessibleDescription(
0700: getMessage("ACSD_PlatformValue"));
0701: javaPlatformCombo.getAccessibleContext()
0702: .setAccessibleDescription(
0703: getMessage("ACSD_JavaPlatformCombo"));
0704: javaPlatformButton.getAccessibleContext()
0705: .setAccessibleDescription(
0706: getMessage("ACSD_JavaPlatformButton"));
0707:
0708: javaPlatformLabel.getAccessibleContext()
0709: .setAccessibleDescription(
0710: getMessage("ACSD_JavaPlatformLbl"));
0711: platform.getAccessibleContext().setAccessibleDescription(
0712: getMessage("ACSD_PlatformLbl"));
0713: }
0714:
0715: // #65924: show warnings if some dependencies cannot be satisfied
0716:
0717: interface UniverseModule {
0718: String getCodeNameBase();
0719:
0720: int getReleaseVersion();
0721:
0722: SpecificationVersion getSpecificationVersion();
0723:
0724: String getImplementationVersion();
0725:
0726: Set<String> getProvidedTokens();
0727:
0728: Set<String> getRequiredTokens();
0729:
0730: Set<Dependency> getModuleDependencies();
0731:
0732: String getCluster();
0733:
0734: String getDisplayName();
0735: }
0736:
0737: private static abstract class AbstractUniverseModule implements
0738: UniverseModule {
0739: protected final ManifestManager mm;
0740:
0741: protected AbstractUniverseModule(ManifestManager mm) {
0742: this .mm = mm;
0743: }
0744:
0745: public int getReleaseVersion() {
0746: String s = mm.getReleaseVersion();
0747: return s != null ? Integer.parseInt(s) : -1;
0748: }
0749:
0750: public String getImplementationVersion() {
0751: return mm.getImplementationVersion();
0752: }
0753:
0754: public Set<String> getProvidedTokens() {
0755: return new HashSet<String>(Arrays.asList(mm
0756: .getProvidedTokens()));
0757: }
0758:
0759: public Set<String> getRequiredTokens() {
0760: Set<String> s = new HashSet<String>(Arrays.asList(mm
0761: .getRequiredTokens()));
0762: Iterator<String> it = s.iterator();
0763: while (it.hasNext()) {
0764: String tok = it.next();
0765: if (tok.startsWith("org.openide.modules.ModuleFormat")
0766: || tok.startsWith("org.openide.modules.os.")) { // NOI18N
0767: it.remove();
0768: }
0769: }
0770: s.addAll(Arrays.asList(mm.getNeededTokens()));
0771: return s;
0772: }
0773:
0774: @Override
0775: public String toString() {
0776: return getCodeNameBase();
0777: }
0778: }
0779:
0780: private static final class PlatformModule extends
0781: AbstractUniverseModule {
0782: private final ModuleEntry entry;
0783:
0784: public PlatformModule(ModuleEntry entry) throws IOException {
0785: super (ManifestManager.getInstanceFromJAR(entry
0786: .getJarLocation()));
0787: this .entry = entry;
0788: }
0789:
0790: public String getCodeNameBase() {
0791: return entry.getCodeNameBase();
0792: }
0793:
0794: public SpecificationVersion getSpecificationVersion() {
0795: String s = entry.getSpecificationVersion();
0796: return s != null ? new SpecificationVersion(s) : null;
0797: }
0798:
0799: public Set<Dependency> getModuleDependencies() {
0800: return mm.getModuleDependencies();
0801: }
0802:
0803: public String getCluster() {
0804: return entry.getClusterDirectory().getName();
0805: }
0806:
0807: public String getDisplayName() {
0808: return entry.getLocalizedName();
0809: }
0810: }
0811:
0812: private static final class SuiteModule extends
0813: AbstractUniverseModule {
0814: private final NbModuleProject project;
0815: private final Set<Dependency> dependencies;
0816:
0817: public SuiteModule(NbModuleProject project) {
0818: super (ManifestManager.getInstance(project.getManifest(),
0819: false));
0820: this .project = project;
0821: dependencies = new HashSet<Dependency>();
0822: // Cannot use ProjectXMLManager since we need to report also deps on nonexistent modules.
0823: Element dataE = project.getPrimaryConfigurationData();
0824: Element depsE = Util.findElement(dataE,
0825: "module-dependencies",
0826: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
0827: assert depsE != null : "Malformed metadata in " + project;
0828: for (Element dep : Util.findSubElements(depsE)) {
0829: Element run = Util.findElement(dep, "run-dependency",
0830: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
0831: if (run == null) {
0832: continue;
0833: }
0834: String text = Util.findText(Util.findElement(dep,
0835: "code-name-base",
0836: NbModuleProjectType.NAMESPACE_SHARED)); // NOI18N
0837: Element relverE = Util.findElement(run,
0838: "release-version",
0839: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
0840: if (relverE != null) {
0841: text += '/' + Util.findText(relverE);
0842: }
0843: Element specverE = Util.findElement(run,
0844: "specification-version",
0845: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
0846: if (specverE != null) {
0847: text += " > " + Util.findText(specverE);
0848: } else {
0849: Element implver = Util.findElement(run,
0850: "implementation-version",
0851: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
0852: if (implver != null) {
0853: // Will special-case '*' as an impl version to mean "match anything".
0854: text += " = *"; // NOI18N
0855: }
0856: }
0857: dependencies.addAll(Dependency.create(
0858: Dependency.TYPE_MODULE, text));
0859: }
0860: }
0861:
0862: public String getCodeNameBase() {
0863: return project.getCodeNameBase();
0864: }
0865:
0866: public SpecificationVersion getSpecificationVersion() {
0867: String s = project.getSpecVersion();
0868: return s != null ? new SpecificationVersion(s) : null;
0869: }
0870:
0871: public Set<Dependency> getModuleDependencies() {
0872: return dependencies;
0873: }
0874:
0875: public String getCluster() {
0876: return null;
0877: }
0878:
0879: public String getDisplayName() {
0880: return ProjectUtils.getInformation(project)
0881: .getDisplayName();
0882: }
0883: }
0884:
0885: private RequestProcessor.Task updateDependencyWarningsTask;
0886:
0887: private void updateDependencyWarnings() {
0888: if (TEST) {
0889: return;
0890: }
0891: // XXX avoid running unless and until we become visible, perhaps
0892: if (updateDependencyWarningsTask == null) {
0893: updateDependencyWarningsTask = RequestProcessor
0894: .getDefault().create(new Runnable() {
0895: public void run() {
0896: doUpdateDependencyWarnings();
0897: }
0898: });
0899: }
0900: updateDependencyWarningsTask.schedule(0);
0901: }
0902:
0903: static Set<UniverseModule> loadUniverseModules(
0904: ModuleEntry[] platformModules,
0905: Set<NbModuleProject> suiteModules) throws IOException {
0906: Set<UniverseModule> universeModules = new LinkedHashSet<UniverseModule>();
0907: for (NbModuleProject p : suiteModules) {
0908: universeModules.add(new SuiteModule(p));
0909: }
0910: for (ModuleEntry e : platformModules) {
0911: universeModules.add(new PlatformModule(e));
0912: }
0913: return universeModules;
0914: }
0915:
0916: static String[] findWarning(Set<UniverseModule> universeModules,
0917: Set<String> enabledClusters, Set<String> disabledModules) {
0918: SortedMap<String, UniverseModule> sortedModules = new TreeMap<String, UniverseModule>();
0919: Set<UniverseModule> excluded = new HashSet<UniverseModule>();
0920: Map<String, Set<UniverseModule>> providers = new HashMap<String, Set<UniverseModule>>();
0921: for (UniverseModule m : universeModules) {
0922: String cnb = m.getCodeNameBase();
0923: String cluster = m.getCluster();
0924: if (cluster != null
0925: && (!enabledClusters.contains(cluster) || disabledModules
0926: .contains(cnb))) {
0927: excluded.add(m);
0928: }
0929: sortedModules.put(cnb, m);
0930: for (String tok : m.getProvidedTokens()) {
0931: Set<UniverseModule> providersOf = providers.get(tok);
0932: if (providersOf == null) {
0933: providersOf = new TreeSet<UniverseModule>(
0934: UNIVERSE_MODULE_COMPARATOR);
0935: providers.put(tok, providersOf);
0936: }
0937: providersOf.add(m);
0938: }
0939: }
0940: for (UniverseModule m : sortedModules.values()) {
0941: if (excluded.contains(m)) {
0942: continue;
0943: }
0944: String[] warning = findWarning(m, sortedModules, providers,
0945: excluded);
0946: if (warning != null) {
0947: return warning;
0948: }
0949: }
0950: return null;
0951: }
0952:
0953: private static final Comparator<UniverseModule> UNIVERSE_MODULE_COMPARATOR = new Comparator<UniverseModule>() {
0954: Collator COLL = Collator.getInstance();
0955:
0956: public int compare(UniverseModule m1, UniverseModule m2) {
0957: return COLL.compare(m1.getDisplayName(), m2
0958: .getDisplayName());
0959: }
0960: };
0961:
0962: private Set<UniverseModule> universe;
0963:
0964: private/* #71791 */synchronized void doUpdateDependencyWarnings() {
0965: if (universe == null) {
0966: try {
0967: Set<NbModuleProject> suiteModules = getProperties()
0968: .getSubModules();
0969: universe = loadUniverseModules(platformModules,
0970: suiteModules);
0971: } catch (IOException e) {
0972: Util.err.notify(ErrorManager.INFORMATIONAL, e);
0973: return; // any warnings would probably be wrong anyway
0974: }
0975: }
0976:
0977: Set<String> enabledClusters = new TreeSet<String>();
0978: Set<String> disabledModules = new TreeSet<String>();
0979:
0980: for (Node cluster : getExplorerManager().getRootContext()
0981: .getChildren().getNodes()) {
0982: if (cluster instanceof Enabled) {
0983: Enabled e = (Enabled) cluster;
0984: if (e.isEnabled()) {
0985: enabledClusters.add(e.getName());
0986: for (Node module : e.getChildren().getNodes()) {
0987: if (module instanceof Enabled) {
0988: Enabled m = (Enabled) module;
0989: if (!m.isEnabled()) {
0990: disabledModules.add(m.getName());
0991: }
0992: }
0993: }
0994: }
0995: }
0996: }
0997:
0998: final String[] warning = findWarning(universe, enabledClusters,
0999: disabledModules);
1000:
1001: EventQueue.invokeLater(new Runnable() {
1002: public void run() {
1003: if (warning != null) {
1004: String key = warning[0];
1005: String[] args = new String[warning.length - 1];
1006: System.arraycopy(warning, 1, args, 0, args.length);
1007: category.setErrorMessage(NbBundle.getMessage(
1008: SuiteCustomizerLibraries.class, key, args));
1009: } else {
1010: category.setErrorMessage(null);
1011: }
1012: }
1013: });
1014:
1015: }
1016:
1017: private static String[] findWarning(UniverseModule m,
1018: Map<String, UniverseModule> modules,
1019: Map<String, Set<UniverseModule>> providers,
1020: Set<UniverseModule> excluded) {
1021: // Check module dependencies:
1022: SortedSet<Dependency> deps = new TreeSet<Dependency>(
1023: new Comparator<Dependency>() {
1024: public int compare(Dependency d1, Dependency d2) {
1025: return d1.getName().compareTo(d2.getName());
1026: }
1027: });
1028: deps.addAll(m.getModuleDependencies());
1029: for (Dependency d : deps) {
1030: String codename = d.getName();
1031: String cnb;
1032: int mrvLo, mrvHi;
1033: int slash = codename.lastIndexOf('/');
1034: if (slash == -1) {
1035: cnb = codename;
1036: mrvLo = -1;
1037: mrvHi = -1;
1038: } else {
1039: cnb = codename.substring(0, slash);
1040: String mrv = codename.substring(slash + 1);
1041: int dash = mrv.lastIndexOf('-');
1042: if (dash == -1) {
1043: mrvLo = mrvHi = Integer.parseInt(mrv);
1044: } else {
1045: mrvLo = Integer.parseInt(mrv.substring(0, dash));
1046: mrvHi = Integer.parseInt(mrv.substring(dash + 1));
1047: }
1048: }
1049: UniverseModule dep = modules.get(cnb);
1050: if (dep == null) {
1051: if (m.getCluster() != null) {
1052: return new String[] { "ERR_platform_no_dep",
1053: m.getDisplayName(), m.getCluster(), cnb };
1054: } else {
1055: return new String[] { "ERR_suite_no_dep",
1056: m.getDisplayName(), cnb };
1057: }
1058: }
1059: if (excluded.contains(dep)) {
1060: assert dep.getCluster() != null;
1061: if (m.getCluster() != null) {
1062: return new String[] { "ERR_platform_excluded_dep",
1063: m.getDisplayName(), m.getCluster(),
1064: dep.getDisplayName(), dep.getCluster() };
1065: } else {
1066: return new String[] { "ERR_suite_excluded_dep",
1067: m.getDisplayName(), dep.getDisplayName(),
1068: dep.getCluster() };
1069: }
1070: }
1071: if (dep.getReleaseVersion() < mrvLo
1072: || dep.getReleaseVersion() > mrvHi) {
1073: if (m.getCluster() != null) {
1074: return new String[] { "ERR_platform_bad_dep_mrv",
1075: m.getDisplayName(), m.getCluster(),
1076: dep.getDisplayName() };
1077: } else {
1078: return new String[] { "ERR_suite_bad_dep_mrv",
1079: m.getDisplayName(), dep.getDisplayName() };
1080: }
1081: }
1082: if (d.getComparison() == Dependency.COMPARE_SPEC) {
1083: SpecificationVersion needed = new SpecificationVersion(
1084: d.getVersion());
1085: SpecificationVersion found = dep
1086: .getSpecificationVersion();
1087: if (found == null || found.compareTo(needed) < 0) {
1088: if (m.getCluster() != null) {
1089: return new String[] {
1090: "ERR_platform_bad_dep_spec",
1091: m.getDisplayName(), m.getCluster(),
1092: dep.getDisplayName() };
1093: } else {
1094: return new String[] { "ERR_suite_bad_dep_spec",
1095: m.getDisplayName(),
1096: dep.getDisplayName() };
1097: }
1098: }
1099: } else if (d.getComparison() == Dependency.COMPARE_IMPL) {
1100: String needed = d.getVersion();
1101: if (!needed.equals("*")
1102: && !needed.equals(dep
1103: .getImplementationVersion())) { // NOI18N
1104: assert m.getCluster() != null;
1105: return new String[] { "ERR_platform_bad_dep_impl",
1106: m.getDisplayName(), m.getCluster(),
1107: dep.getDisplayName() };
1108: }
1109: }
1110: }
1111: // Now check token availability:
1112: for (String tok : new TreeSet<String>(m.getRequiredTokens())) {
1113: UniverseModule wouldBeProvider = null;
1114: boolean found = false;
1115: Set<UniverseModule> possibleProviders = providers.get(tok);
1116: if (possibleProviders != null) {
1117: for (UniverseModule p : possibleProviders) {
1118: if (excluded.contains(p)) {
1119: if (wouldBeProvider == null) {
1120: wouldBeProvider = p;
1121: }
1122: } else {
1123: found = true;
1124: break;
1125: }
1126: }
1127: }
1128: if (!found) {
1129: if (wouldBeProvider != null) {
1130: assert wouldBeProvider.getCluster() != null;
1131: if (m.getCluster() != null) {
1132: return new String[] {
1133: "ERR_platform_only_excluded_providers",
1134: tok, m.getDisplayName(),
1135: m.getCluster(),
1136: wouldBeProvider.getDisplayName(),
1137: wouldBeProvider.getCluster() }; // NOI18N
1138: } else {
1139: return new String[] {
1140: "ERR_suite_only_excluded_providers",
1141: tok, m.getDisplayName(),
1142: wouldBeProvider.getDisplayName(),
1143: wouldBeProvider.getCluster() }; // NOI18N
1144: }
1145: } else {
1146: if (m.getCluster() != null) {
1147: return new String[] {
1148: "ERR_platform_no_providers", tok,
1149: m.getDisplayName(), m.getCluster() }; // NOI18N
1150: } else {
1151: return new String[] { "ERR_suite_no_providers",
1152: tok, m.getDisplayName() }; // NOI18N
1153: }
1154: }
1155: }
1156: }
1157: // All clear for this module.
1158: return null;
1159: }
1160:
1161: private void updateJavaPlatformEnabled() { // #71631
1162: boolean enabled = ((NbPlatform) platformValue.getSelectedItem())
1163: .getHarnessVersion() >= NbPlatform.HARNESS_VERSION_50u1;
1164: javaPlatformCombo.setEnabled(enabled);
1165: javaPlatformButton.setEnabled(enabled); // #72061
1166: }
1167:
1168: }
|