diff -r 6b487c15857b deployment.deviceanywhere/src/org/netbeans/modules/deployment/deviceanywhere/DeviceAnywhereDeploymentPlugin.java --- a/deployment.deviceanywhere/src/org/netbeans/modules/deployment/deviceanywhere/DeviceAnywhereDeploymentPlugin.java Tue Nov 25 18:06:33 2008 -0500 +++ b/deployment.deviceanywhere/src/org/netbeans/modules/deployment/deviceanywhere/DeviceAnywhereDeploymentPlugin.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,6 +50,7 @@ import java.util.Collections; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.openide.util.NbBundle; import org.netbeans.spi.mobility.deployment.DeploymentPlugin; @@ -120,7 +121,7 @@ public class DeviceAnywhereDeploymentPlu return new DeviceAnywhereGlobalCustomizerPanel(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.props = props; this.configuration = configuration; } diff -r 6b487c15857b j2me.cdc.project.bdj/src/org/netbeans/modules/j2me/cdc/project/bdj/BDJProjectCategoryCustomizer.java --- a/j2me.cdc.project.bdj/src/org/netbeans/modules/j2me/cdc/project/bdj/BDJProjectCategoryCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.bdj/src/org/netbeans/modules/j2me/cdc/project/bdj/BDJProjectCategoryCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -44,8 +44,7 @@ import java.io.File; import java.io.File; import javax.swing.JFileChooser; import javax.swing.JPanel; -import javax.swing.filechooser.FileFilter; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; @@ -70,7 +69,7 @@ public class BDJProjectCategoryCustomize initComponents(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); projectDir = FileUtil.toFile(props.getProjectDirectory()).getAbsolutePath(); diff -r 6b487c15857b j2me.cdc.project.execui/src/org/netbeans/modules/j2me/cdc/project/execui/MainClassChooser.java --- a/j2me.cdc.project.execui/src/org/netbeans/modules/j2me/cdc/project/execui/MainClassChooser.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.execui/src/org/netbeans/modules/j2me/cdc/project/execui/MainClassChooser.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,13 +50,31 @@ import org.openide.filesystems.FileObjec */ public abstract class MainClassChooser extends JPanel { + /** - * Inicialize MainClassChooser to be able to search for main classes + * Initialize MainClassChooser to be able to search for main classes + * @deprecated Use initialize (FileObject[] ...) instead * @param sourceRoot * @param executionModes * @param bootcp */ - public abstract void inicialize(FileObject sourceRoot, Map executionModes, String bootcp); + @Deprecated + public void inicialize(FileObject sourceRoot, Map executionModes, String bootcp) { + initialize (new FileObject[] { sourceRoot }, executionModes, bootcp); + } + + /** + * Initialize MainClassChooser to be able to search for main classes + * @param sourceRoot + * @param executionModes + * @param bootcp + */ + public void initialize(FileObject[] sourceRoots, Map executionModes, String bootcp) { + //For bw compatibility, need some implementation. Will not be + //called if an old subclass overrides the formerly abstract + //inicialize(). -Tim + throw new UnsupportedOperationException("Not implemented"); + } /** * Sets the main class(-es). If more than one main class is selected (applies only for Xlets), then they are divided by ';' diff -r 6b487c15857b j2me.cdc.project.execuiimpl/src/org/netbeans/modules/j2me/cdc/project/execuiimpl/MainClassChooserImpl.java --- a/j2me.cdc.project.execuiimpl/src/org/netbeans/modules/j2me/cdc/project/execuiimpl/MainClassChooserImpl.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.execuiimpl/src/org/netbeans/modules/j2me/cdc/project/execuiimpl/MainClassChooserImpl.java Wed Nov 26 00:47:25 2008 -0500 @@ -102,7 +102,7 @@ public class MainClassChooserImpl extend protected ChangeListener changeListener; private String dialogSubtitle = null; protected List possibleMainClasses; - private FileObject sourcesRoot; + private FileObject[] sourceRoots; private String bcp; protected boolean onlyMain; protected String mainClass; @@ -117,12 +117,12 @@ public class MainClassChooserImpl extend } @Override - public void inicialize(FileObject sourceRoot, Map executionModes, String bootcp) { + public void initialize(FileObject[] sourceRoots, Map executionModes, String bootcp) { dialogSubtitle = null; - this.sourcesRoot = sourceRoot; + this.sourceRoots = sourceRoots; this.onlyMain = false; this.executionModes = executionModes; - initClassesView (sourcesRoot); + initClassesView (sourceRoots); if (onlyMain) onlymainLabel.setText(NbBundle.getMessage(MainClassChooserImpl.class, "MSG_OnlyMainAllowed")); bcp=bootcp; @@ -130,7 +130,7 @@ public class MainClassChooserImpl extend specialExecFqnApplet = (executionModes != null) ? executionModes.get(CDCPlatform.PROP_EXEC_APPLET) : null; } - private void initClassesView (final FileObject sourcesRoot) { + private void initClassesView (final FileObject[] sourceRoots) { possibleMainClasses = null; jMainClassList.setSelectionMode (ListSelectionModel.SINGLE_SELECTION); jMainClassList.setListData (getWarmupList ()); @@ -161,7 +161,7 @@ public class MainClassChooserImpl extend RequestProcessor.getDefault ().post (new Runnable () { public void run () { - possibleMainClasses = getMainClasses (new FileObject[] {sourcesRoot}, executionModes,bcp); + possibleMainClasses = getMainClasses (sourceRoots, executionModes,bcp); if (possibleMainClasses.isEmpty ()) { SwingUtilities.invokeLater( new Runnable () { public void run () { @@ -177,7 +177,7 @@ public class MainClassChooserImpl extend final List l = new ArrayList(possibleMainClasses); for (Iterator it = l.iterator(); it.hasNext();) { String elem = it.next(); - if (!isMainClass(elem, sourcesRoot) || (executionModes != null && executionModes.containsKey(CDCPlatform.PROP_EXEC_MAIN))){ + if (!isMainClass(elem, sourceRoots) || (executionModes != null && executionModes.containsKey(CDCPlatform.PROP_EXEC_MAIN))){ it.remove(); } } @@ -197,7 +197,7 @@ public class MainClassChooserImpl extend boolean xlet = false; if (!possibleMainClasses.isEmpty()){ for (String elem : possibleMainClasses) { - if (isXletClass(elem, sourcesRoot, specialExecFqnXlet)){ + if (isXletClass(elem, sourceRoots[0], specialExecFqnXlet)){ xlet = true; break; } @@ -260,9 +260,9 @@ public class MainClassChooserImpl extend { public void run() { - isMain[0] = isMainClass(mainClass, sourcesRoot); - isXlet[0] = isXletClass(mainClass, sourcesRoot, specialExecFqnXlet); - isApplet[0] = isAppletClass(mainClass, sourcesRoot, specialExecFqnApplet); + isMain[0] = isMainClass(mainClass, sourceRoots); + isXlet[0] = isXletClass(mainClass, sourceRoots[0], specialExecFqnXlet); + isApplet[0] = isAppletClass(mainClass, sourceRoots[0], specialExecFqnApplet); } }); task.waitFinished(); @@ -490,12 +490,12 @@ public class MainClassChooserImpl extend }//GEN-LAST:event_multipleXletsActionPerformed protected String[] updateListView(final boolean onlyXlets) { - if (onlyXlets){ + if (onlyXlets && sourceRoots.length > 0){ jMainClassList.setSelectionMode (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); List l = new ArrayList(possibleMainClasses); for (Iterator it = l.iterator(); it.hasNext();) { String elem = it.next(); - if (!isXletClass(elem, sourcesRoot, specialExecFqnXlet)){ + if (!isXletClass(elem, sourceRoots[0], specialExecFqnXlet)){ it.remove(); } } @@ -709,6 +709,16 @@ public class MainClassChooserImpl extend ex.printStackTrace(); } } + + private FileObject rootOf (FileObject test) { + for (FileObject root : sourceRoots) { + if (FileUtil.isParentOf(root, test)) { + return root; + } + } + throw new AssertionError (test.getPath() + " not a child of source " + + "roots " + Arrays.asList(sourceRoots)); + } /** Returns if the given class name exists under the sources root and * it's a main class. @@ -717,7 +727,11 @@ public class MainClassChooserImpl extend * @param root roots of sources * @return true if the class name exists and it's a main class */ - public static boolean isMainClass(String className, FileObject root) { + public static boolean isMainClass(String className, FileObject[] roots) { + if (roots.length == 0) { + return false; + } + FileObject root = roots[0]; ClassPath boot = ClassPath.getClassPath (root, ClassPath.BOOT); //Single compilation unit ClassPath rtm2 = ClassPath.getClassPath (root, ClassPath.EXECUTE); //Single compilation unit' ClassPath rtm1 = ClassPath.getClassPath (root, ClassPath.COMPILE); diff -r 6b487c15857b j2me.cdc.project.nokiaS80/src/org/netbeans/modules/j2me/cdc/project/nokiaS80/NokiaS80ProjectCategoryCustomizer.java --- a/j2me.cdc.project.nokiaS80/src/org/netbeans/modules/j2me/cdc/project/nokiaS80/NokiaS80ProjectCategoryCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.nokiaS80/src/org/netbeans/modules/j2me/cdc/project/nokiaS80/NokiaS80ProjectCategoryCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -46,7 +46,7 @@ import javax.swing.JPanel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.filechooser.FileFilter; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; @@ -71,7 +71,7 @@ public class NokiaS80ProjectCategoryCust initComponents(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); projectDir = FileUtil.toFile(props.getProjectDirectory()).getAbsolutePath(); diff -r 6b487c15857b j2me.cdc.project.nsicom/src/org/netbeans/modules/j2me/cdc/project/nsicom/NSIcomProjectCategoryCustomizer.java --- a/j2me.cdc.project.nsicom/src/org/netbeans/modules/j2me/cdc/project/nsicom/NSIcomProjectCategoryCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.nsicom/src/org/netbeans/modules/j2me/cdc/project/nsicom/NSIcomProjectCategoryCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -51,7 +51,7 @@ import java.beans.PropertyChangeListener import java.beans.PropertyChangeListener; import javax.swing.JPanel; import javax.swing.UIManager; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.mobility.activesync.ActiveSyncOps; import org.netbeans.mobility.activesync.DeviceConnectedListener; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -360,7 +360,7 @@ public class NSIcomProjectCategoryCustom } } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); } diff -r 6b487c15857b j2me.cdc.project.ricoh/src/org/netbeans/modules/j2me/cdc/project/ricoh/RicohProjectCategoryCustomizer.java --- a/j2me.cdc.project.ricoh/src/org/netbeans/modules/j2me/cdc/project/ricoh/RicohProjectCategoryCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.ricoh/src/org/netbeans/modules/j2me/cdc/project/ricoh/RicohProjectCategoryCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,15 +50,13 @@ import java.beans.PropertyChangeListener import java.beans.PropertyChangeListener; import java.io.File; import javax.swing.JButton; -import javax.xml.parsers.*; import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.filechooser.FileFilter; -import javax.swing.event.*; import org.netbeans.api.java.platform.JavaPlatform; import org.netbeans.api.java.platform.JavaPlatformManager; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; @@ -97,7 +95,7 @@ public class RicohProjectCategoryCustomi } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); projectDir = FileUtil.toFile(props.getProjectDirectory()).getAbsolutePath(); diff -r 6b487c15857b j2me.cdc.project.savaje/src/org/netbeans/modules/j2me/cdc/project/savaje/SavaJeProjectCategoryCustomizer.java --- a/j2me.cdc.project.savaje/src/org/netbeans/modules/j2me/cdc/project/savaje/SavaJeProjectCategoryCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.savaje/src/org/netbeans/modules/j2me/cdc/project/savaje/SavaJeProjectCategoryCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -46,7 +46,7 @@ import javax.swing.JPanel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.filechooser.FileFilter; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; @@ -73,7 +73,7 @@ public class SavaJeProjectCategoryCustom initComponents(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); projectDir = FileUtil.toFile(props.getProjectDirectory()).getAbsolutePath(); diff -r 6b487c15857b j2me.cdc.project.semc/src/org/netbeans/modules/j2me/cdc/project/semc/SemcProjectCategoryCustomizer.java --- a/j2me.cdc.project.semc/src/org/netbeans/modules/j2me/cdc/project/semc/SemcProjectCategoryCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project.semc/src/org/netbeans/modules/j2me/cdc/project/semc/SemcProjectCategoryCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,7 +50,7 @@ import javax.swing.filechooser.FileFilte import javax.swing.filechooser.FileFilter; import org.netbeans.api.java.platform.JavaPlatform; import org.netbeans.api.java.platform.JavaPlatformManager; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; @@ -90,7 +90,7 @@ public class SemcProjectCategoryCustomiz initComponents(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); projectDir = FileUtil.toFile(props.getProjectDirectory()).getAbsolutePath(); diff -r 6b487c15857b j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CDCPlatformCustomizer.java --- a/j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CDCPlatformCustomizer.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CDCPlatformCustomizer.java Wed Nov 26 00:47:25 2008 -0500 @@ -51,7 +51,7 @@ import org.netbeans.api.java.platform.Ja import org.netbeans.api.java.platform.JavaPlatformManager; import org.netbeans.api.java.platform.PlatformsCustomizer; import org.netbeans.api.java.platform.Specification; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.j2me.cdc.platform.CDCDevice; import org.netbeans.modules.j2me.cdc.platform.CDCPlatform; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; @@ -93,7 +93,7 @@ public class CDCPlatformCustomizer exten initAll(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.props = props; this.vps = VisualPropertySupport.getDefault(props); this.configuration = configuration; diff -r 6b487c15857b j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CustomizerCDCGeneral.java --- a/j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CustomizerCDCGeneral.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CustomizerCDCGeneral.java Wed Nov 26 00:47:25 2008 -0500 @@ -42,7 +42,7 @@ package org.netbeans.modules.j2me.cdc.pr package org.netbeans.modules.j2me.cdc.project; import javax.swing.JPanel; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; @@ -67,7 +67,7 @@ public class CustomizerCDCGeneral extend public CustomizerCDCGeneral() { initComponents(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); } diff -r 6b487c15857b j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CustomizerRun.java --- a/j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CustomizerRun.java Tue Nov 25 18:06:33 2008 -0500 +++ b/j2me.cdc.project/src/org/netbeans/modules/j2me/cdc/project/CustomizerRun.java Wed Nov 26 00:47:25 2008 -0500 @@ -51,7 +51,7 @@ import javax.swing.JTextField; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.j2me.cdc.project.CDCPropertiesDescriptor; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -80,7 +80,7 @@ public class CustomizerRun extends JPane }; private VisualPropertySupport vps; - private ProjectProperties prop; + private MultiRootProjectProperties prop; private MainClassChooser chooser; @@ -89,7 +89,7 @@ public class CustomizerRun extends JPane jTextHidden=new javax.swing.JTextField(); chooser = Lookup.getDefault().lookup(org.netbeans.modules.j2me.cdc.project.execui.MainClassChooser.class); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(jCheckBox1, configuration, this); prop=props; @@ -271,7 +271,7 @@ public class CustomizerRun extends JPane if (chooser == null) return; //do nothing - chooser.inicialize(prop.getSourceRoot(), + chooser.initialize(prop.getSourceRoots(), CDCProjectUtil.getExecutionModes(prop),(String)prop.get("platform.bootclasspath")); // only chooseMainClassButton can be performed // final MainClassChooser panel = new MainClassChooser (prop.getSourceRoot(), diff -r 6b487c15857b java.api.common/nbproject/project.xml --- a/java.api.common/nbproject/project.xml Tue Nov 25 18:06:33 2008 -0500 +++ b/java.api.common/nbproject/project.xml Wed Nov 26 00:47:25 2008 -0500 @@ -199,13 +199,14 @@ org.netbeans.modules.j2ee.earproject org.netbeans.modules.j2ee.ejbjarproject org.netbeans.modules.java.j2seproject + org.netbeans.modules.javafx.profiler org.netbeans.modules.javafx.project - org.netbeans.modules.javafx.profiler + org.netbeans.modules.mobility.project org.netbeans.modules.projectimport - org.netbeans.modules.projectimport.jbuilder org.netbeans.modules.projectimport.eclipse.core org.netbeans.modules.projectimport.eclipse.j2se org.netbeans.modules.projectimport.eclipse.web + org.netbeans.modules.projectimport.jbuilder org.netbeans.modules.scala.project org.netbeans.modules.web.project org.netbeans.modules.xtest diff -r 6b487c15857b java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties Tue Nov 25 18:06:33 2008 -0500 +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties Wed Nov 26 00:47:25 2008 -0500 @@ -174,7 +174,7 @@ CTL_ProjectFolder=Project Folder\: CTL_ProjectFolder=Project Folder\: TITLE_InvalidRoot=Add Package Folder MSG_InvalidRoot=Package Folder Already Used in Project\n\ - Following folders you selected are already used in this or another\n\ + The following folders you selected are already used in this or another\n\ project. One package folder can only be used in one project in one\n\ package folder list (source packages or test packages). LBL_InvalidRoot=Package folders already in use: diff -r 6b487c15857b mobility.deployment.ricoh/src/org/netbeans/modules/mobility/deployment/ricoh/RicohCustomizerPanel.java --- a/mobility.deployment.ricoh/src/org/netbeans/modules/mobility/deployment/ricoh/RicohCustomizerPanel.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.deployment.ricoh/src/org/netbeans/modules/mobility/deployment/ricoh/RicohCustomizerPanel.java Wed Nov 26 00:47:25 2008 -0500 @@ -43,16 +43,12 @@ package org.netbeans.modules.mobility.de package org.netbeans.modules.mobility.deployment.ricoh; import java.awt.CardLayout; -import java.awt.Component; -import java.awt.Container; -import javax.swing.text.JTextComponent; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.openide.util.*; import javax.swing.*; import java.awt.event.*; import java.io.File; -import java.util.Set; -import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.project.support.ant.EditableProperties; import org.netbeans.spi.project.support.ant.PropertyUtils; @@ -354,7 +350,7 @@ public class RicohCustomizerPanel extend this.repaint(); } - public void initValues(ProjectProperties props, String configuration) + public void initValues(MultiRootProjectProperties props, String configuration) { actConfig=configuration; actProps =props; diff -r 6b487c15857b mobility.j2meunit/src/org/netbeans/modules/mobility/j2meunit/J2MEUnitProjectLookupProvider.java --- a/mobility.j2meunit/src/org/netbeans/modules/mobility/j2meunit/J2MEUnitProjectLookupProvider.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.j2meunit/src/org/netbeans/modules/mobility/j2meunit/J2MEUnitProjectLookupProvider.java Wed Nov 26 00:47:25 2008 -0500 @@ -67,7 +67,7 @@ public class J2MEUnitProjectLookupProvid { List lookups=new ArrayList(); lookups.add(new J2MEUnitPlugin(project,helper)); - lookups.add(new UnitTestForSourceQueryImpl(helper)); + lookups.add(new UnitTestForSourceQueryImpl(project, helper)); return lookups; } } diff -r 6b487c15857b mobility.j2meunit/src/org/netbeans/modules/mobility/j2meunit/UnitTestForSourceQueryImpl.java --- a/mobility.j2meunit/src/org/netbeans/modules/mobility/j2meunit/UnitTestForSourceQueryImpl.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.j2meunit/src/org/netbeans/modules/mobility/j2meunit/UnitTestForSourceQueryImpl.java Wed Nov 26 00:47:25 2008 -0500 @@ -48,9 +48,15 @@ package org.netbeans.modules.mobility.j2 package org.netbeans.modules.mobility.j2meunit; import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.modules.mobility.project.J2MEProject; +import org.netbeans.modules.mobility.project.J2MESources; import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileUtil; /** * @@ -59,23 +65,28 @@ public class UnitTestForSourceQueryImpl public class UnitTestForSourceQueryImpl implements MultipleRootsUnitTestForSourceQueryImplementation { final private AntProjectHelper myHelper; + private final J2MEProject project; - public UnitTestForSourceQueryImpl(AntProjectHelper aph) { + public UnitTestForSourceQueryImpl(J2MEProject project, AntProjectHelper aph) { this.myHelper=aph; + this.project = project; } public URL[] findUnitTests(@SuppressWarnings("unused") final FileObject source) { //we have only one source root in J2ME projects, it is same for both sources and tests - try { - final String sourceRootPath=myHelper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - if (sourceRootPath == null) return null; - final FileObject sourceRoot=this.myHelper.resolveFileObject(sourceRootPath); - if (sourceRoot == null) return null; - return new URL[] {sourceRoot.getURL()}; - } catch (Exception e) { - return null; + J2MESources sources = project.getLookup().lookup(J2MESources.class); + assert sources != null; + FileObject sourceRoot = sources.rootFor(source); + if (sourceRoot != null) { + String path = FileUtil.getRelativePath(sourceRoot, source); + try { + return new URL[]{sourceRoot.getURL()}; + } catch (FileStateInvalidException ex) { + Logger.getLogger(getClass().getName()).log(Level.INFO, null, ex); + } } + return null; } public URL[] findSources(final FileObject unitTest) { diff -r 6b487c15857b mobility.project.ant/antsrc/org/netbeans/modules/mobility/project/ant/KdpDebugTask.java --- a/mobility.project.ant/antsrc/org/netbeans/modules/mobility/project/ant/KdpDebugTask.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project.ant/antsrc/org/netbeans/modules/mobility/project/ant/KdpDebugTask.java Wed Nov 26 00:47:25 2008 -0500 @@ -67,6 +67,7 @@ import org.openide.util.NbBundle; import org.openide.util.NbBundle; import java.beans.PropertyChangeEvent; import java.net.URL; +import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import org.netbeans.api.debugger.DebuggerEngine; @@ -165,8 +166,19 @@ public class KdpDebugTask extends Task { throw new BuildException(NbBundle.getMessage(KdpDebugTask.class, "ERR_ANT_Address_missing"), getLocation()); //NOI18N } - //locate source root - String src = project.getProperty("src.dir"); //NOI18N + //locate at least one source root + String src = null; + Hashtable props = project.getProperties(); + for (Object prop : props.keySet()) { + if (prop instanceof String) { + String p = (String) prop; + if (p.startsWith("src.") && p.endsWith(".dir")) { //NOI18N + src = project.getProperty(p); + break; + } + } + } + if (src == null) throw new BuildException(NbBundle.getMessage(KdpDebugTask.class, "ERR_ANT_source_root_missing"), getLocation()); //NOI18N File srcFile = new File(project.getBaseDir(), src); if (!srcFile.isDirectory()) srcFile = new File(src); diff -r 6b487c15857b mobility.project/nbproject/project.xml --- a/mobility.project/nbproject/project.xml Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/nbproject/project.xml Wed Nov 26 00:47:25 2008 -0500 @@ -307,6 +307,15 @@ made subject to such option by the copyr 6.2 + + org.netbeans.modules.java.api.common + + + + 0 + 1.3 + + diff -r 6b487c15857b mobility.project/src/org/netbeans/api/mobility/project/ui/customizer/MultiRootProjectProperties.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/api/mobility/project/ui/customizer/MultiRootProjectProperties.java Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,60 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.api.mobility.project.ui.customizer; + +import org.openide.filesystems.FileObject; + +/** + * Extends ProjectProperties to support multiple source roots. + * + * @author Tim Boudreau + */ +public abstract class MultiRootProjectProperties implements ProjectProperties { + + /** + * Get all source roots in the project. Replaces + * ProjectProperties.getSourceRoot(). + * @return + */ + public FileObject[] getSourceRoots(){ + return new FileObject[] { getSourceRoot() }; + } + +} diff -r 6b487c15857b mobility.project/src/org/netbeans/api/mobility/project/ui/customizer/ProjectProperties.java --- a/mobility.project/src/org/netbeans/api/mobility/project/ui/customizer/ProjectProperties.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/api/mobility/project/ui/customizer/ProjectProperties.java Wed Nov 26 00:47:25 2008 -0500 @@ -24,7 +24,7 @@ * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * 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 @@ -46,13 +46,18 @@ import org.openide.filesystems.FileObjec import org.openide.filesystems.FileObject; /** + * All mobile projects now use MultiRootProjectProperties - + * for accessing the source root folders, use that class's + * getSourceRoots(). * + * @see MultiRootProjectProperties * @author Adam Sotona */ public interface ProjectProperties extends Map { public FileObject getProjectDirectory(); - + + @Deprecated public FileObject getSourceRoot(); public ProjectConfiguration[] getConfigurations(); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ApplicationDescriptorHandler.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ApplicationDescriptorHandler.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ApplicationDescriptorHandler.java Wed Nov 26 00:47:25 2008 -0500 @@ -83,17 +83,19 @@ public class ApplicationDescriptorHandle public void handleRename(final FileObject file, final String newName) { if (!isJava(file)) return; final Project p = findProject(file); - final String className = calculateClassName(getSrcRoot(p), file); + final String className = calculateClassName(getSrcRoot(p, file), file); if (className != null) postChangeRequest(p, className, className.substring(0, className.length() - file.getName().length()) + newName); } public void handleMove(final FileObject file, final FileObject newFolder) { if (!isJava(file)) return; final Project p = findProject(file); - final FileObject srcRoot = getSrcRoot(p); - final String className = calculateClassName(getSrcRoot(p), file); + final FileObject srcRoot = getSrcRoot(p, file); + final String className = calculateClassName(srcRoot, file); if (className == null) return; - String newClassName = newFolder == null ? null : FileUtil.getRelativePath(srcRoot, newFolder); + String newClassName = newFolder == null ? null : + FileUtil.getRelativePath(srcRoot, newFolder); + if (newClassName != null) { if (newClassName.length() > 0) newClassName = newClassName.replace('/', '.') + '.'; newClassName += file.getName(); @@ -104,7 +106,7 @@ public class ApplicationDescriptorHandle public void handleDelete(final FileObject file) { if (!isJava(file)) return; final Project p = findProject(file); - final String className = calculateClassName(getSrcRoot(p), file); + final String className = calculateClassName(getSrcRoot(p, file), file); if (className != null) postChangeRequest(p, className, null); } @@ -117,12 +119,11 @@ public class ApplicationDescriptorHandle return p instanceof J2MEProject ? p : null; } - private FileObject getSrcRoot(final Project p) { - if (p == null) return null; - final AntProjectHelper helper = p.getLookup().lookup(AntProjectHelper.class); - if (helper == null) return null; - final String srcDir = helper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - return srcDir == null ? null : helper.resolveFileObject(srcDir); + private FileObject getSrcRoot(final Project p, FileObject file) { + J2MESources src = p.getLookup().lookup (J2MESources.class); + assert src != null : "Null J2MESources from lookup of project at " + + p.getProjectDirectory().getPath(); + return src.rootFor(file); } private String calculateClassName(final FileObject root, final FileObject file) { diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/Bundle.properties --- a/mobility.project/src/org/netbeans/modules/mobility/project/Bundle.properties Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/Bundle.properties Wed Nov 26 00:47:25 2008 -0500 @@ -83,3 +83,12 @@ LBL_Cfg_TemplateSuffix=_template EmptyConfigurationTemplate= +#Updater +TXT_ProjectUpdate=Project Needs Upgrading\n\ + This project was created in an earlier version of NetBeans IDE. If you\n\ + edit its properties in NetBeans IDE {0}, the project will be upgraded and\n\ + will no longer work in earlier versions of the IDE.\n\n\ + Do you want to upgrade your project to version {0}? +TXT_ProjectUpdateTitle=Change Project Properties +CTL_UpdateOption=Upgrade Project +AD_UpdateOption=N/A diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/CDCMainClassHelper.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/CDCMainClassHelper.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/CDCMainClassHelper.java Wed Nov 26 00:47:25 2008 -0500 @@ -52,7 +52,6 @@ import org.netbeans.api.java.classpath.C import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; -import org.netbeans.modules.mobility.project.queries.CompiledSourceForBinaryQuery; import org.netbeans.spi.project.support.ant.AntProjectEvent; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.AntProjectListener; @@ -73,11 +72,13 @@ public class CDCMainClassHelper implemen final private AntProjectHelper helper; private String mainClass; private FileObject lastMain=null; + private final J2MEProject project; /** Creates a new instance of CDCMainClassHelper */ - public CDCMainClassHelper(AntProjectHelper helper) + public CDCMainClassHelper(J2MEProject project, AntProjectHelper helper) { this.helper = helper; + this.project = project; EditableProperties ep=helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); mainClass=ep.getProperty("main.class"); if (mainClass != null) @@ -145,13 +146,20 @@ public class CDCMainClassHelper implemen { public void run() { - final FileObject root = helper.getProjectDirectory().getFileObject(helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(DefaultPropertiesDescriptor.SRC_DIR)); - if (root != null) + J2MESources sources = project.getLookup().lookup(J2MESources.class); + FileObject[] roots = sources == null ? new FileObject[0] : + sources.getSourceRoots(); + if (roots != null && roots.length > 0) { - final ClassPath path1 = ClassPath.getClassPath (root, ClassPath.SOURCE); - final ClassPath path2 = ClassPath.getClassPath (root, ClassPath.COMPILE); + //Should be able to get same classpaths from any root + final ClassPath path1 = ClassPath.getClassPath (roots[0], ClassPath.SOURCE); + final ClassPath path2 = ClassPath.getClassPath (roots[0], ClassPath.COMPILE); final ClassPath path = org.netbeans.spi.java.classpath.support.ClassPathSupport.createProxyClassPath(new ClassPath[] { path1, path2 } ); - FileObject o=path.findResource(str.replace('.','/')+".java"); + FileObject o = path.findResource(str.replace('.','/')+".java"); //NOI18N + + //XXX this looks like a memory leak that will hold the + //a reference to the project. However, not sure if it will + //break something to use a weak listener instead if (lastMain != null) lastMain.removeFileChangeListener(CDCMainClassHelper.this); if (o!=null) diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MEActionProvider.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/J2MEActionProvider.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MEActionProvider.java Wed Nov 26 00:47:25 2008 -0500 @@ -214,15 +214,20 @@ public class J2MEActionProvider implemen String activeConfiguration = confs.getActiveConfiguration() != confs.getDefaultConfiguration() ? confs.getActiveConfiguration().getDisplayName() : null; Properties p = new Properties(); if ( command.equals( COMMAND_COMPILE_SINGLE ) ) { - String sDir = helper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - if (sDir != null) { - FileObject srcDir = helper.resolveFileObject(sDir); - if (srcDir != null) { - FileObject[] files = findSourcesAndPackages(context, srcDir); - if (files != null) { - p.setProperty("javac.includes", ActionUtils.antIncludesList(files, srcDir)); // NOI18N + J2MESources sources = project.getLookup().lookup (J2MESources.class); + assert sources != null; + StringBuilder includes = new StringBuilder(); + for (FileObject root : sources.getSourceRoots()) { + FileObject[] found = findSourcesAndPackages(context, root); + if (found != null) { + if (includes.length() != 0) { + includes.append (','); } + includes.append(ActionUtils.antIncludesList(found, root)); } + } + if (includes.length() > 0) { + p.setProperty ("javac.includes", includes.toString()); } } else if (COMMAND_DEBUG.equals(command)) { p.put(DefaultPropertiesDescriptor.OBFUSCATION_LEVEL, "0"); //NOI18N diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MEAntLogger.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/J2MEAntLogger.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MEAntLogger.java Wed Nov 26 00:47:25 2008 -0500 @@ -42,6 +42,7 @@ package org.netbeans.modules.mobility.pr package org.netbeans.modules.mobility.project; import java.io.File; import java.util.HashMap; +import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.tools.ant.module.spi.AntEvent; import org.apache.tools.ant.module.spi.AntLogger; @@ -60,6 +61,8 @@ public final class J2MEAntLogger extends public final class J2MEAntLogger extends AntLogger { private static final String separator = File.separatorChar == '\\' ? "\\\\" : "/"; //NOI18N + //PENDING: Determine if : is safe + private static final char PATH_SEPARATOR = ':'; //NOI18N private static final Pattern PREPROCESSED = Pattern.compile( "^.*" + separator + "build(?:" + separator + "[a-zA-Z_$][a-zA-Z0-9_$]*)?" + separator + "preprocessed" + separator); // NOI18N @@ -78,23 +81,40 @@ public final class J2MEAntLogger extends return session.getVerbosity() < AntEvent.LOG_DEBUG; } + @Override public boolean interestedInScript(File script, AntSession session) { FileObject projfile = FileUtil.toFileObject(FileUtil.normalizeFile(script)); if (projfile == null) return false; Project proj = FileOwnerQuery.getOwner(projfile); if (proj == null) return false; + J2MESources sources = proj.getLookup().lookup (J2MESources.class); + if (sources == null) return false; + FileObject[] sourceRootFolders = sources.getSourceRoots(); + + if (sourceRootFolders.length == 0) return false; AntProjectHelper helper = proj.getLookup().lookup(AntProjectHelper.class); if (helper == null) return false; - String sourceRoot = helper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - if (sourceRoot == null) return false; - File srcRoot = helper.resolveFile(sourceRoot); - if (srcRoot == null) return false; + + File[] rootsAsFiles = new File[sourceRootFolders.length]; + StringBuilder paths = new StringBuilder(); + for (int i = 0; i < rootsAsFiles.length; i++) { + rootsAsFiles[i] = FileUtil.toFile(sourceRootFolders[i]); + if (rootsAsFiles[i] == null) { + return false; + } + if (paths.length() > 0) { + paths.append (PATH_SEPARATOR); + } + paths.append (rootsAsFiles[i].getAbsolutePath().replaceAll(CHARSTOESCAPE, ESCAPESEQUENCE)); + paths.append (separator); + } + HashMap roots = (HashMap)session.getCustomData(this); if (roots == null) { roots = new HashMap(); session.putCustomData(this, roots); } - roots.put(script, srcRoot.getAbsolutePath().replaceAll(CHARSTOESCAPE, ESCAPESEQUENCE) + separator); + roots.put(script, paths.toString()); return true; } @@ -122,7 +142,12 @@ public final class J2MEAntLogger extends srcRoot = (String)cd; if (srcRoot == null) return; String message = event.getMessage(); - String newMessage = PREPROCESSED.matcher(message).replaceFirst(srcRoot); + + Matcher matcher = PREPROCESSED.matcher(message); + String newMessage = message; + for (String path : srcRoot.split(":")) { + newMessage = matcher.replaceFirst(path); + } if (!message.equals(newMessage)) { event.consume(); event.getSession().deliverMessageLogged(event, newMessage, event.getLogLevel()); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MEProject.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProject.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProject.java Wed Nov 26 00:47:25 2008 -0500 @@ -38,8 +38,8 @@ * 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.mobility.project; -package org.netbeans.modules.mobility.project; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; @@ -83,7 +83,6 @@ import org.netbeans.spi.mobility.project import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; import org.netbeans.spi.project.ProjectConfiguration; import org.netbeans.api.project.ui.OpenProjects; -import org.netbeans.modules.mobility.project.classpath.J2MEProjectClassPathExtender; import org.netbeans.spi.project.ui.ProjectOpenedHook; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; @@ -95,19 +94,23 @@ import org.openide.util.ImageUtilities; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.RequestProcessor; -import org.netbeans.modules.mobility.project.ui.J2MECustomizerProvider; import org.netbeans.modules.mobility.project.ui.J2MEPhysicalViewProvider; -import org.netbeans.modules.mobility.project.queries.CompiledSourceForBinaryQuery; -import org.netbeans.modules.mobility.project.queries.JavadocForBinaryQueryImpl; import org.netbeans.spi.project.AuxiliaryConfiguration; import org.netbeans.api.project.ProjectInformation; import org.netbeans.modules.j2me.cdc.platform.CDCPlatform; +import org.netbeans.modules.java.api.common.SourceRoots; +import org.netbeans.modules.java.api.common.ant.UpdateHelper; +import org.netbeans.modules.java.api.common.queries.QuerySupport; import org.netbeans.modules.mobility.project.classpath.J2MEClassPathProvider; +import org.netbeans.modules.mobility.project.classpath.J2MEProjectClassPathExtender; import org.netbeans.modules.mobility.project.deployment.DeploymentPropertiesHandler; -import org.netbeans.modules.mobility.project.queries.SourceLevelQueryImpl; +import org.netbeans.modules.mobility.project.queries.CompiledSourceForBinaryQuery; import org.netbeans.modules.mobility.project.queries.FileBuiltQueryImpl; import org.netbeans.modules.mobility.project.queries.FileEncodingQueryImpl; +import org.netbeans.modules.mobility.project.queries.JavadocForBinaryQueryImpl; +import org.netbeans.modules.mobility.project.queries.SourceLevelQueryImpl; import org.netbeans.modules.mobility.project.security.KeyStoreRepository; +import org.netbeans.modules.mobility.project.ui.J2MECustomizerProvider; import org.netbeans.modules.mobility.project.ui.customizer.J2MEProjectProperties; import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport; import org.netbeans.spi.mobility.deployment.DeploymentPlugin; @@ -117,7 +120,11 @@ import org.netbeans.spi.project.support. import org.netbeans.spi.project.support.ant.*; import org.netbeans.spi.project.ui.RecommendedTemplates; import org.netbeans.spi.project.ui.PrivilegedTemplates; +import org.netbeans.spi.project.ui.support.UILookupMergerSupport; +import org.netbeans.spi.queries.FileEncodingQueryImplementation; +import org.netbeans.spi.queries.SharabilityQueryImplementation; import org.openide.ErrorManager; +import org.openide.util.Exceptions; import org.openide.util.LookupEvent; import org.openide.util.LookupListener; import org.openide.util.Mutex; @@ -134,47 +141,56 @@ import org.w3c.dom.Node; * @author Jesse Glick, Adam Sotona, Tim Boudreau */ public final class J2MEProject implements Project, AntProjectListener { + final Icon J2ME_PROJECT_ICON = new ImageIcon(ImageUtilities.loadImage( - "org/netbeans/modules/mobility/project/ui/resources/mobile-project.png" )); // NOI18N + "org/netbeans/modules/mobility/project/ui/resources/mobile-project.png")); // NOI18N private static final URLStreamHandler COMPOSED_STREAM_HANDLER = new URLStreamHandler() { + protected URLConnection openConnection(URL u) throws IOException { return new ComposedConnection(u); } }; - static final String CONFIGS_NAME = "configurations"; // NOI18N static final String CONFIG_NAME = "configuration"; // NOI18N static final String CONFIGS_NS = "http://www.netbeans.org/ns/project-configurations/1"; // NOI18N static final String CLASSPATH = "classpath"; // NOI18N - final AuxiliaryConfiguration aux; final AntProjectHelper helper; final GeneratedFilesHelper genFilesHelper; Lookup lookup; - final MIDletsCacheHelper midletsCacheHelper; + final MIDletsCacheHelper midletsCacheHelper; final ProjectConfigurationsHelper configHelper; - + private final SourceRoots sourceRoots; + private final SourceRoots testSourceRoots; + + //XXX This pointlessly leaks FileObjects. Cache paths instead. -Tim private static final Set roots = new HashSet(); private static final Map folders = new WeakHashMap(); private final ReferenceHelper refHelper; private final PropertyChangeSupport pcs; - private TextSwitcher textSwitcher; - + private final UpdateHelper updater; + /* Side effect of this methosd is modification of fo - is this correct? */ public static boolean isJ2MEFile(FileObject fo) { - if (fo == null) return false; + if (fo == null) { + return false; + } final FileObject archiveRoot = FileUtil.getArchiveFile(fo); if (archiveRoot != null) { fo = archiveRoot; } return isJ2MEFolder(fo.getParent()); } - - private static boolean isJ2MEFolder(FileObject fo) { - if (fo == null) return false; + + private static boolean isJ2MEFolder(FileObject fo) { + if (fo == null) { + return false; + } synchronized (roots) { - if (roots.contains(fo)) return true; + if (roots.contains(fo)) { + return true; + } } Boolean result; synchronized (folders) { @@ -184,8 +200,10 @@ public final class J2MEProject implement FileObject xml; if (fo.isFolder() && (xml = fo.getFileObject("nbproject/project.xml")) != null) { result = isJ2MEProjectXML(xml); - if (result) synchronized (roots) { - roots.add(fo); + if (result) { + synchronized (roots) { + roots.add(fo); + } } } else { result = isJ2MEFolder(fo.getParent()); @@ -197,15 +215,15 @@ public final class J2MEProject implement return result; } - public boolean isConfigBroken (ProjectConfiguration cfg) { + public boolean isConfigBroken(ProjectConfiguration cfg) { cfg = cfg == null ? configHelper.getActiveConfiguration() : cfg; - String[] breakableConfigProperties = getBreakableProperties (cfg); - String[] breakableConfigPlatformProperties = getBreakablePlatformProperties (cfg); - boolean result = BrokenReferencesSupport.isBroken( helper, refHelper, + String[] breakableConfigProperties = getBreakableProperties(cfg); + String[] breakableConfigPlatformProperties = getBreakablePlatformProperties(cfg); + boolean result = BrokenReferencesSupport.isBroken(helper, refHelper, breakableConfigProperties, breakableConfigPlatformProperties); //also check for unresolved ant properties return result || breakableConfigProperties != null && - breakableConfigProperties[1] != null && + breakableConfigProperties[1] != null && breakableConfigProperties[1].contains("${"); } @@ -239,7 +257,7 @@ public final class J2MEProject implement if (libs == null) { libs = DefaultPropertiesDescriptor.PLATFORM_ACTIVE; } else { - libs = J2MEProjectProperties.CONFIG_PREFIX + + libs = J2MEProjectProperties.CONFIG_PREFIX + cfg.getDisplayName() + "." + DefaultPropertiesDescriptor.PLATFORM_ACTIVE; } @@ -248,25 +266,25 @@ public final class J2MEProject implement } private String[] getBreakablePlatformProperties(ProjectConfiguration cfg) { - String s[]=new String[1]; - s[0]=usedActive(cfg); + String s[] = new String[1]; + s[0] = usedActive(cfg); return s; } public String[] getBreakableProperties() { final ProjectConfiguration pc[] = configHelper.getConfigurations().toArray( new ProjectConfiguration[0]); - String s[] = new String[2*pc.length+1]; + String s[] = new String[2 * pc.length + 1]; s[0] = DefaultPropertiesDescriptor.SRC_DIR; - for (int i= 0; i"+J2MEProjectType.TYPE+"") >= 0) return true; //NOI18N + if (s.indexOf("" + J2MEProjectType.TYPE + "") >= 0) { + return true; //NOI18N + } } } finally { - if (in != null) in.close(); + if (in != null) { + in.close(); + } } - } catch (IOException ioe) {} + } catch (IOException ioe) { + } return false; } - + J2MEProject(AntProjectHelper helper) { this.helper = helper; - addRoots(helper); aux = helper.createAuxiliaryConfiguration(); refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator()); configHelper = new ProjectConfigurationsHelper(helper, this); genFilesHelper = new GeneratedFilesHelper(helper); midletsCacheHelper = new MIDletsCacheHelper(helper, configHelper); - helper.addAntProjectListener(new CDCMainClassHelper(helper)); + helper.addAntProjectListener(new CDCMainClassHelper(this, helper)); pcs = new PropertyChangeSupport(this); + helper.addAntProjectListener(this); + //XXX should be possible to make these more lazy + updater = new UpdateHelper(new Updater(this, helper, aux), helper); + this.sourceRoots = SourceRoots.create( + updater, + evaluator(), + refHelper, + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "source-roots", false, "src.{0}{1}.dir"); //NOI18N + this.testSourceRoots = SourceRoots.create( + updater, + evaluator(), + refHelper, + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "test-roots", false, "src.{0}{1}.dir"); //NOI18N + if (sourceRoots == null) { + throw new NullPointerException ("SourceRoots.create() returned null"); + } + + assert sourceRoots != null; + assert testSourceRoots != null; this.lookup = this.createLookup(aux); - helper.addAntProjectListener(this); + addRoots(helper, sourceRoots); } - + + public PropertyEvaluator evaluator() { + return helper.getStandardPropertyEvaluator(); + } + public void hookNewProjectCreated() { midletsCacheHelper.refresh(); } - + public FileObject getProjectDirectory() { return helper.getProjectDirectory(); } - + public Lookup getLookup() { return this.lookup; } - + public ProjectConfigurationsHelper getConfigurationHelper() { return configHelper; } private Lookup createLookup(final AuxiliaryConfiguration aux) { - final SourcesHelper sourcesHelper = new SourcesHelper(helper, helper.getStandardPropertyEvaluator()); - sourcesHelper.addPrincipalSourceRoot("${src.dir}", NbBundle.getMessage(J2MEProject.class, "LBL_J2MEProject_Source_Packages"), null, null); //NOI18N - sourcesHelper.addTypedSourceRoot("${src.dir}", JavaProjectConstants.SOURCES_TYPE_JAVA, NbBundle.getMessage(J2MEProject.class, "LBL_J2MEProject_Source_Packages"), null, null); //NOI18N + FileEncodingQueryImplementation encodingQuery = + QuerySupport.createFileEncodingQuery(evaluator(), + J2MEProjectProperties.SOURCE_ENCODING); final SubprojectProvider spp = refHelper.createSubprojectProvider(); - - Object stdLookups[]=new Object[] { + //XXX does not handle deployment.copy.target yet + // helper.createSharabilityQuery(evaluator(), + // new String[]{"${src.dir}"}, + // new String[]{"${dist.root.dir}", + // "${build.root.dir}", + // "${deployment.copy.target}"}), //NOI18N + assert sourceRoots != null; + assert helper != null; + assert evaluator() != null; + assert sourceRoots != null; + assert testSourceRoots != null; + SharabilityQueryImplementation sharability = + QuerySupport.createSharabilityQuery(helper, evaluator(), + sourceRoots, testSourceRoots); + + Object stdLookups[] = new Object[]{ new Info(), aux, spp, configHelper, + updater, + encodingQuery, helper, midletsCacheHelper, refHelper, - new FileBuiltQueryImpl(helper, configHelper), - new J2MEActionProvider( this, helper ), + new J2MEClassPathProvider(helper, getSourceRoots(), getTestSourceRoots()), + sharability, + new J2MESources(helper, evaluator(), sourceRoots, getTestSourceRoots()), + UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()), + QuerySupport.createTemplateAttributesProvider(helper, encodingQuery), + new FileBuiltQueryImpl(this, helper, configHelper), + new J2MEActionProvider(this, helper), new J2MEPhysicalViewProvider(this, helper, refHelper, configHelper), - new J2MECustomizerProvider( this, helper, refHelper, configHelper), - new J2MEClassPathProvider(helper), + new J2MECustomizerProvider(this, helper, refHelper, configHelper), new CompiledSourceForBinaryQuery(this, helper), new AntArtifactProviderImpl(), new ProjectXmlSavedHookImpl(), new ProjectOpenedHookImpl(), new JavadocForBinaryQueryImpl(this, helper), - helper.createSharabilityQuery(helper.getStandardPropertyEvaluator(), new String[]{"${src.dir}"}, new String[]{"${dist.root.dir}", "${build.root.dir}", "${deployment.copy.target}"}), //NOI18N - sourcesHelper.createSources(), new RecommendedTemplatesImpl(), new SourceLevelQueryImpl(helper), new J2MEProjectClassPathExtender(this, helper, refHelper, configHelper), @@ -419,23 +492,30 @@ public final class J2MEProject implement new PreprocessorFileFilterImplementation(configHelper, helper), new FileEncodingQueryImpl(helper) }; - ArrayList list=new ArrayList(); + ArrayList list = new ArrayList(); list.addAll(Arrays.asList(stdLookups)); - for (ProjectLookupProvider provider : Lookup.getDefault().lookupAll(ProjectLookupProvider.class)) - { - list.addAll(provider.createLookupElements(this,helper,refHelper,configHelper)); + for (ProjectLookupProvider provider : Lookup.getDefault().lookupAll(ProjectLookupProvider.class)) { + list.addAll(provider.createLookupElements(this, helper, refHelper, configHelper)); } return Lookups.fixed(list.toArray()); -// return new AnalysisLookup (list.toArray()); } - + + public SourceRoots getSourceRoots() { + return this.sourceRoots; + } + + public SourceRoots getTestSourceRoots() { + return this.testSourceRoots; + } + /** Store configured project name. */ public void setName(final String name) { ProjectManager.mutex().writeAccess(new Mutex.Action() { + public Object run() { final Element data = helper.getPrimaryConfigurationData(true); // XXX replace by XMLUtil when that has findElement, findText, etc. - final NodeList nl = data.getElementsByTagNameNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); + final NodeList nl = data.getElementsByTagNameNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "name"); Element nameEl; if (nl.getLength() == 1) { nameEl = (Element) nl.item(0); @@ -444,8 +524,8 @@ public final class J2MEProject implement nameEl.removeChild(deadKids.item(0)); } } else { - nameEl = data.getOwnerDocument().createElementNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); - data.insertBefore(nameEl, /* OK if null */data.getChildNodes().item(0)); + nameEl = data.getOwnerDocument().createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "name"); + data.insertBefore(nameEl, /* OK if null */ data.getChildNodes().item(0)); } nameEl.appendChild(data.getOwnerDocument().createTextNode(name)); helper.putPrimaryConfigurationData(data, true); @@ -453,39 +533,39 @@ public final class J2MEProject implement } }); } - + public void addPropertyChangeListener(final PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } - + public void removePropertyChangeListener(final PropertyChangeListener listener) { pcs.removePropertyChangeListener(listener); } - + public void configurationXmlChanged(final AntProjectEvent ev) { if (ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) { // Could be various kinds of changes, but name & displayName might have changed. - final Info info = (Info)getLookup().lookup(ProjectInformation.class); + final Info info = (Info) getLookup().lookup(ProjectInformation.class); info.firePropertyChange(ProjectInformation.PROP_NAME); info.firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME); } } - + public void propertiesChanged(@SuppressWarnings("unused") - final AntProjectEvent ev) { + final AntProjectEvent ev) { // currently ignored } - - + protected void refreshPrivateProperties() throws IOException { try { ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() { - public Object run() { + + public Object run() { boolean modified = false; EditableProperties proj = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); EditableProperties priv = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); - priv.setProperty("netbeans.user", System.getProperty("netbeans.user")); //NOI18N - for (ProjectPropertiesDescriptor p : Lookup.getDefault().lookup(new Lookup.Template(ProjectPropertiesDescriptor.class)).allInstances() ) { + priv.setProperty("netbeans.user", System.getProperty("netbeans.user")); //NOI18N + for (ProjectPropertiesDescriptor p : Lookup.getDefault().lookup(new Lookup.Template(ProjectPropertiesDescriptor.class)).allInstances()) { for (PropertyDescriptor d : p.getPropertyDescriptors()) { if (d.getDefaultValue() != null) { EditableProperties ep = d.isShared() ? proj : priv; @@ -500,7 +580,8 @@ public final class J2MEProject implement if (!cfgs.isEmpty()) { modified = true; cfgs.addAll(Arrays.asList(proj.getProperty(DefaultPropertiesDescriptor.ALL_CONFIGURATIONS).split(","))); - cfgs.remove(" "); cfgs.remove(""); //NOI18N + cfgs.remove(" "); + cfgs.remove(""); //NOI18N StringBuffer sb = new StringBuffer(" "); //NOI18N for (String s : cfgs) { sb.append(',').append(s); @@ -508,7 +589,9 @@ public final class J2MEProject implement proj.setProperty(DefaultPropertiesDescriptor.ALL_CONFIGURATIONS, sb.toString()); } helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, priv); - if (modified) helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, proj); + if (modified) { + helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, proj); + } try { refHelper.addExtraBaseDirectory("netbeans.user"); //NOI18N } catch (IllegalArgumentException iae) { @@ -518,7 +601,7 @@ public final class J2MEProject implement } }); } catch (MutexException e) { - throw (IOException)e.getException(); + throw (IOException) e.getException(); } // Probably unnecessary, but just in case: try { @@ -527,18 +610,18 @@ public final class J2MEProject implement ErrorManager.getDefault().notify(e); } } - + private Set removeConfigurationsFromProjectXml() { TreeSet cfgs = new TreeSet(); Element configs = aux.getConfigurationFragment(CONFIGS_NAME, CONFIGS_NS, true); if (configs != null) { try { NodeList subEls = configs.getElementsByTagNameNS(CONFIGS_NS, CONFIG_NAME); - for (int i=0; i() { + public String run() { final Element data = helper.getPrimaryConfigurationData(true); // XXX replace by XMLUtil when that has findElement, findText, etc. - NodeList nl = data.getElementsByTagNameNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N + NodeList nl = data.getElementsByTagNameNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N + if (nl.getLength() == 0) { + nl = data.getElementsByTagNameNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); + } if (nl.getLength() == 1) { nl = nl.item(0).getChildNodes(); if (nl.getLength() == 1 && nl.item(0).getNodeType() == Node.TEXT_NODE) { @@ -570,88 +657,85 @@ public final class J2MEProject implement } }); } - + // Private innerclasses ---------------------------------------------------- - private final class ProjectXmlSavedHookImpl extends ProjectXmlSavedHook { - + ProjectXmlSavedHookImpl() { // Just to avoid creating accessor class } - + protected void projectXmlSaved() throws IOException { refreshBuildScripts(false); } - } - + private final class ProjectOpenedHookImpl extends ProjectOpenedHook implements LookupListener { - + private boolean skipCloseHook = false; private PropertyChangeListener platformListener; private Lookup.Result deployments; //We need those listners to be able to check for changes on paltform bootclasspath - private final class PlatformInstalledListener implements PropertyChangeListener - { + private final class PlatformInstalledListener implements PropertyChangeListener { + final List knownPlatforms; - private final PropertyChangeListener platformChange = new PropertyChangeListener() - { - public void propertyChange(PropertyChangeEvent evt) - { - if (CLASSPATH.equals(evt.getPropertyName()) && evt.getSource() instanceof CDCPlatform) - { - CDCPlatform platform = (CDCPlatform)evt.getSource(); - if (platform != null) - { - List configs = J2MEProject.this.getMatchingConfigs((String)platform.getProperties().get("platform.ant.name")); - J2MEProject.this.updateBootClassPathProperty(configs, platform); - } + private final PropertyChangeListener platformChange = new PropertyChangeListener() { + + public void propertyChange(PropertyChangeEvent evt) { + if (CLASSPATH.equals(evt.getPropertyName()) && evt.getSource() instanceof CDCPlatform) { + CDCPlatform platform = (CDCPlatform) evt.getSource(); + if (platform != null) { + List configs = J2MEProject.this.getMatchingConfigs((String) platform.getProperties().get("platform.ant.name")); + J2MEProject.this.updateBootClassPathProperty(configs, platform); + } } } }; - PlatformInstalledListener(JavaPlatform known[]) - { - knownPlatforms=new ArrayList(Arrays.asList(known)); + PlatformInstalledListener(JavaPlatform known[]) { + knownPlatforms = new ArrayList(Arrays.asList(known)); - for (JavaPlatform plat : knownPlatforms) - { + for (JavaPlatform plat : knownPlatforms) { plat.addPropertyChangeListener(platformChange); List configs = J2MEProject.this.getMatchingConfigs(plat.getProperties().get("platform.ant.name")); - J2MEProject.this.updateBootClassPathProperty(configs, (CDCPlatform)plat); + J2MEProject.this.updateBootClassPathProperty(configs, (CDCPlatform) plat); } } - public void propertyChange(PropertyChangeEvent evt) - { - if (evt.getPropertyName().equals(JavaPlatformManager.PROP_INSTALLED_PLATFORMS)) - { - JavaPlatform[] known=JavaPlatformManager.getDefault().getPlatforms(null, new Specification (CDCPlatform.PLATFORM_CDC,null)); - List list=Arrays.asList(known); + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(JavaPlatformManager.PROP_INSTALLED_PLATFORMS)) { + JavaPlatform[] known = JavaPlatformManager.getDefault().getPlatforms(null, new Specification(CDCPlatform.PLATFORM_CDC, null)); + List list = Arrays.asList(known); List added = new ArrayList(Arrays.asList(known)); added.removeAll(knownPlatforms); knownPlatforms.removeAll(list); - for (JavaPlatform platform : knownPlatforms) - { + for (JavaPlatform platform : knownPlatforms) { platform.removePropertyChangeListener(platformChange); } - for (JavaPlatform platform : added) - { + for (JavaPlatform platform : added) { platform.addPropertyChangeListener(platformChange); } knownPlatforms.clear(); knownPlatforms.addAll(list); - } + } } }; - - + ProjectOpenedHookImpl() { // Just to avoid creating accessor class } - + protected synchronized void projectOpened() { + UpdateHelper updater = getLookup().lookup(UpdateHelper.class); + assert updater != null; + try { + if (!updater.isCurrent()) { + updater.requestUpdate(); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } //inicialize deployment plugins deployments = Lookup.getDefault().lookup(new Lookup.Template(DeploymentPlugin.class)); deployments.addLookupListener(this); @@ -659,33 +743,44 @@ public final class J2MEProject implement //init keystore, safer than warmup KeyStoreRepository.getDefault(); // Check up on build scripts. - addRoots(helper); + addRoots(helper, getSourceRoots()); final SourcesHelper sourcesHelper = getLookup().lookup(SourcesHelper.class); - final String srcDir = helper.getStandardPropertyEvaluator().getProperty(DefaultPropertiesDescriptor.SRC_DIR); - final FileObject srcRoot = srcDir == null ? null : helper.resolveFileObject(srcDir); - final Project other = srcRoot == null ? null : FileOwnerQuery.getOwner(srcRoot); - if (other != null && !J2MEProject.this.equals(other)) { - if (Arrays.asList(OpenProjects.getDefault().getOpenProjects()).contains(other)) { - final ProjectInformation pi = other.getLookup().lookup(ProjectInformation.class); - final String name = pi == null ? other.getProjectDirectory().getPath() : pi.getDisplayName(); - if (NotifyDescriptor.OK_OPTION.equals(DialogDisplayer.getDefault().notify( - new NotifyDescriptor.Confirmation(NbBundle.getMessage(J2MEProject.class, "MSG_ClashingSourceRoots", J2MEProject.this.getName(), name), NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.WARNING_MESSAGE)))) { //NOI18N - OpenProjects.getDefault().close(new Project[]{other}); - } else { - skipCloseHook = true; - OpenProjects.getDefault().close(new Project[]{J2MEProject.this}); - return; + + J2MESources sources = getLookup().lookup(J2MESources.class); + Set notified = new HashSet(); + for (FileObject srcRoot : sources.getSourceRoots()) { + Project other = srcRoot == null ? null : FileOwnerQuery.getOwner(srcRoot); + if (other != null && !J2MEProject.this.equals(other) && !notified.contains(other)) { + if (Arrays.asList(OpenProjects.getDefault().getOpenProjects()).contains(other)) { + notified.add(other); + final ProjectInformation pi = other.getLookup().lookup(ProjectInformation.class); + final String name = pi == null ? other.getProjectDirectory().getPath() : pi.getDisplayName(); + if (NotifyDescriptor.OK_OPTION.equals(DialogDisplayer.getDefault().notify( + new NotifyDescriptor.Confirmation(NbBundle.getMessage(J2MEProject.class, "MSG_ClashingSourceRoots", J2MEProject.this.getName(), name), NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.WARNING_MESSAGE)))) { //NOI18N + OpenProjects.getDefault().close(new Project[]{other}); + } else { + skipCloseHook = true; + OpenProjects.getDefault().close(new Project[]{J2MEProject.this}); + return; + } } } + final FileObject sourceRoot = srcRoot; + ProjectManager.mutex().postWriteRequest(new Runnable() { + + public void run() { + try { + if (sourcesHelper != null) { + sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); + } + } catch (IllegalStateException ise) { + } + if (sourceRoot != null) { + FileOwnerQuery.markExternalOwner(sourceRoot, J2MEProject.this, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); + } + } + }); } - ProjectManager.mutex().postWriteRequest(new Runnable() { - public void run() { - try { - if (sourcesHelper != null) sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - } catch (IllegalStateException ise) {} - if (srcRoot != null) FileOwnerQuery.markExternalOwner(srcRoot, J2MEProject.this, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - } - }); try { refreshBuildScripts(true); refreshPrivateProperties(); @@ -693,26 +788,28 @@ public final class J2MEProject implement } catch (IOException e) { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } - + // register project's classpaths to GlobalPathRegistry final J2MEClassPathProvider cpProvider = lookup.lookup(J2MEClassPathProvider.class); assert cpProvider != null; - GlobalPathRegistry.getDefault().register(ClassPath.BOOT, new ClassPath[] {cpProvider.getBootClassPath()}); - GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {cpProvider.getSourcepath()}); - GlobalPathRegistry.getDefault().register(ClassPath.COMPILE, new ClassPath[] {cpProvider.getCompileTimeClasspath()}); - + GlobalPathRegistry.getDefault().register(ClassPath.BOOT, new ClassPath[]{cpProvider.getBootClassPath()}); + GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[]{cpProvider.getSourcepath()}); + GlobalPathRegistry.getDefault().register(ClassPath.COMPILE, new ClassPath[]{cpProvider.getCompileTimeClasspath()}); + configHelper.addPropertyChangeListener(textSwitcher = new TextSwitcher(J2MEProject.this, helper)); - final J2MEPhysicalViewProvider phvp = lookup.lookup(J2MEPhysicalViewProvider.class); + final J2MEPhysicalViewProvider phvp = lookup.lookup(J2MEPhysicalViewProvider.class); if (hasBrokenLinks()) { BrokenReferencesSupport.showAlert(); } - + midletsCacheHelper.refresh(); } - + protected synchronized void projectClosed() { - if (skipCloseHook) return; + if (skipCloseHook) { + return; + } //do not listen on deployments for this project deployments.removeLookupListener(this); @@ -722,45 +819,46 @@ public final class J2MEProject implement } catch (IOException e) { ErrorManager.getDefault().notify(e); } - + configHelper.removePropertyChangeListener(textSwitcher); // unregister project's classpaths to GlobalPathRegistry final J2MEClassPathProvider cpProvider = lookup.lookup(J2MEClassPathProvider.class); - GlobalPathRegistry.getDefault().unregister(ClassPath.BOOT, new ClassPath[] {cpProvider.getBootClassPath()}); - GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {cpProvider.getSourcepath()}); - GlobalPathRegistry.getDefault().unregister(ClassPath.COMPILE, new ClassPath[] {cpProvider.getCompileTimeClasspath()}); - + GlobalPathRegistry.getDefault().unregister(ClassPath.BOOT, new ClassPath[]{cpProvider.getBootClassPath()}); + GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[]{cpProvider.getSourcepath()}); + GlobalPathRegistry.getDefault().unregister(ClassPath.COMPILE, new ClassPath[]{cpProvider.getCompileTimeClasspath()}); + JavaPlatformManager.getDefault().removePropertyChangeListener(platformListener); } - - private void refreshBootClasspath() - { - + private void refreshBootClasspath() { + JavaPlatform[] installedPlatforms = JavaPlatformManager.getDefault(). - getPlatforms(null, new Specification (CDCPlatform.PLATFORM_CDC,null)); //NOI18N + getPlatforms(null, new Specification(CDCPlatform.PLATFORM_CDC, null)); //NOI18N platformListener = new PlatformInstalledListener(installedPlatforms); JavaPlatformManager.getDefault().addPropertyChangeListener(platformListener); } - + public void resultChanged(final LookupEvent e) { final Collection result = ((Lookup.Result) e.getSource()).allInstances(); RequestProcessor.getDefault().post(new Runnable() { + public void run() { DeploymentPropertiesHandler.loadDeploymentProperties(result); } }, 200); - } + } } - + private void refreshBuildScripts(final boolean checkForProjectXmlModified) { RequestProcessor.getDefault().post(new Runnable() { + public void run() { final FileObject root = Repository.getDefault().getDefaultFileSystem().findResource("Buildsystem/org.netbeans.modules.kjava.j2meproject"); //NOI18N final LinkedList files = new LinkedList(); files.addAll(Arrays.asList(root.getChildren())); ProjectManager.mutex().postWriteRequest(new Runnable() { + public void run() { try { ProjectManager.getDefault().saveProject(J2MEProject.this); @@ -768,24 +866,35 @@ public final class J2MEProject implement ErrorManager.getDefault().notify(ioe); } URL u = null; - while (!files.isEmpty()) try { - FileObject fo = files.removeFirst(); - if (fo.getExt().equals("xml") && isAuthorized(fo)) { //NOI18N - u = fo.isData() ? fo.getURL() : new URL("", null, -1, fo.getPath(), COMPOSED_STREAM_HANDLER); //NOI18N - genFilesHelper.refreshBuildScript(FileUtil.getRelativePath(root, fo), u, checkForProjectXmlModified); - } else if (fo.isFolder()) { - files.addAll(Arrays.asList(fo.getChildren())); - } - } catch (IOException ioe) { - ErrorManager.getDefault().notify(ioe); - BufferedReader br = null; - if (u != null) try { - br = new BufferedReader(new InputStreamReader(u.openStream())); - String s; - while ((s = br.readLine()) != null) ErrorManager.getDefault().log(ErrorManager.ERROR, s); - } catch (Exception e) { - } finally { - if (br != null) try {br.close();} catch (IOException e) {} + while (!files.isEmpty()) { + try { + FileObject fo = files.removeFirst(); + if (fo.getExt().equals("xml") && isAuthorized(fo)) { //NOI18N + u = fo.isData() ? fo.getURL() : new URL("", null, -1, fo.getPath(), COMPOSED_STREAM_HANDLER); //NOI18N + genFilesHelper.refreshBuildScript(FileUtil.getRelativePath(root, fo), u, checkForProjectXmlModified); + } else if (fo.isFolder()) { + files.addAll(Arrays.asList(fo.getChildren())); + } + } catch (IOException ioe) { + ErrorManager.getDefault().notify(ioe); + BufferedReader br = null; + if (u != null) { + try { + br = new BufferedReader(new InputStreamReader(u.openStream())); + String s; + while ((s = br.readLine()) != null) { + ErrorManager.getDefault().log(ErrorManager.ERROR, s); + } + } catch (Exception e) { + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + } + } + } + } } } } @@ -793,154 +902,155 @@ public final class J2MEProject implement } }); } - + /** * Exports the main JAR as an official build product for use from other scripts. * The type of the artifact will be {@link AntArtifact#TYPE_JAR}. */ private final class AntArtifactProviderImpl implements AntArtifactProvider { - - private AntArtifactProviderImpl() - { + + private AntArtifactProviderImpl() { // Just to avoid creating accessor class } - + public AntArtifact[] getBuildArtifacts() { final ProjectConfiguration cfgs[] = configHelper.getConfigurations().toArray(new ProjectConfiguration[0]); AntArtifact art[] = new AntArtifact[cfgs.length]; - for (int i=0; i result = new HashSet(); for (FileObject fo : root.getChildren()) { String s = (String) fo.getAttribute("RecommendedTemplates"); //NOI18N - if (s != null) result.addAll(Arrays.asList(s.split(","))); //NOI18N + if (s != null) { + result.addAll(Arrays.asList(s.split(","))); //NOI18N + } } return result.toArray(new String[result.size()]); } - + public String[] getPrivilegedTemplates() { //priviledged templates are ordered by module layer DataFolder root = DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().findResource(LOCATION)); ArrayList result = new ArrayList(); for (DataObject ch : root.getChildren()) { String s = (String) ch.getPrimaryFile().getAttribute("PriviledgedTemplates"); //NOI18N - if (s != null) result.addAll(Arrays.asList(s.split(","))); //NOI18N + if (s != null) { + result.addAll(Arrays.asList(s.split(","))); //NOI18N + } } return result.toArray(new String[result.size()]); } - } - + private static final class ComposedConnection extends URLConnection { - + private static WeakHashMap cache = new WeakHashMap(); - + public ComposedConnection(URL u) { super(u); } @@ -953,18 +1063,20 @@ public final class J2MEProject implement DataObject mainParts[] = root.getChildren(); StringBuffer sb = new StringBuffer(); String lastTarget = ""; //NOI18N - for (int i=0; i FRIENDS_JARS = collectFriendJars(); // // private static Set getFriends() { @@ -1038,7 +1154,6 @@ public final class J2MEProject implement // } // return jars; // } - private static boolean isAuthorized(FileObject fo) { // if (fo.isFolder() || FRIENDS_JARS == null) return true; // URL u = null; @@ -1070,87 +1185,78 @@ public final class J2MEProject implement // } return true; } - - - private static String normalizePath (File path, File jdkHome, String propName) { + + private static String normalizePath(File path, File jdkHome, String propName) { String jdkLoc = jdkHome.getAbsolutePath(); if (!jdkLoc.endsWith(File.separator)) { jdkLoc = jdkLoc + File.separator; } String loc = path.getAbsolutePath(); if (loc.startsWith(jdkLoc)) { - return "${"+propName+"}"+File.separator+loc.substring(jdkLoc.length()); //NOI18N + return "${" + propName + "}" + File.separator + loc.substring(jdkLoc.length()); //NOI18N } return loc; } - + private List getMatchingConfigs(final String actualPlatformId) { List configs = new ArrayList(); - - for (ProjectConfiguration config : getConfigurationHelper().getConfigurations()) - { - boolean useDef= config.equals(getConfigurationHelper().getDefaultConfiguration()); - String platformProp=VisualPropertySupport.translatePropertyName(config.getDisplayName(), - DefaultPropertiesDescriptor.PLATFORM_ACTIVE, useDef); - String platformId=helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(platformProp); - + + for (ProjectConfiguration config : getConfigurationHelper().getConfigurations()) { + boolean useDef = config.equals(getConfigurationHelper().getDefaultConfiguration()); + String platformProp = VisualPropertySupport.translatePropertyName(config.getDisplayName(), + DefaultPropertiesDescriptor.PLATFORM_ACTIVE, useDef); + String platformId = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(platformProp); + //platformId is null when non default config, which use default values, is queried //This one is not important for us as the change will be/have been done using DefaultConfiguration - if (platformId != null && platformId.equals(actualPlatformId)) - { + if (platformId != null && platformId.equals(actualPlatformId)) { configs.add(config); } } return configs; } - - private void generatePlatformProperties (CDCPlatform platform,ProjectConfiguration config, String activeDevice, String activeProfile, EditableProperties props) { + + private void generatePlatformProperties(CDCPlatform platform, ProjectConfiguration config, String activeDevice, String activeProfile, EditableProperties props) { Collection installFolders = platform.getInstallFolders(); - if (installFolders.size()>0) { - File jdkHome = FileUtil.toFile (installFolders.iterator().next()); + if (installFolders.size() > 0) { + File jdkHome = FileUtil.toFile(installFolders.iterator().next()); StringBuffer sbootcp = new StringBuffer(); ClassPath bootCP = platform.getBootstrapLibrariesForProfile(activeDevice, activeProfile); - for (ClassPath.Entry entry : (List)bootCP.entries()) { + for (ClassPath.Entry entry : (List) bootCP.entries()) { URL url = entry.getURL(); if ("jar".equals(url.getProtocol())) { //NOI18N url = FileUtil.getArchiveFile(url); } - File root = new File (URI.create(url.toExternalForm())); - if (sbootcp.length()>0) { + File root = new File(URI.create(url.toExternalForm())); + if (sbootcp.length() > 0) { sbootcp.append(File.pathSeparator); } sbootcp.append(normalizePath(root, jdkHome, "platform.home")); } - boolean useDef= config.equals(getConfigurationHelper().getDefaultConfiguration()); + boolean useDef = config.equals(getConfigurationHelper().getDefaultConfiguration()); props.setProperty(VisualPropertySupport.translatePropertyName(config.getDisplayName(), - DefaultPropertiesDescriptor.PLATFORM_BOOTCLASSPATH,useDef),sbootcp.toString()); //NOI18N + DefaultPropertiesDescriptor.PLATFORM_BOOTCLASSPATH, useDef), sbootcp.toString()); //NOI18N } } - private void updateBootClassPathProperty(List configs, CDCPlatform platform) - { - if (configs != null) - { - try - { - EditableProperties props=helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); - for (ProjectConfiguration config : configs) - { - boolean useDef= config.equals(getConfigurationHelper().getDefaultConfiguration()); + private void updateBootClassPathProperty(List configs, CDCPlatform platform) { + if (configs != null) { + try { + EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); + for (ProjectConfiguration config : configs) { + boolean useDef = config.equals(getConfigurationHelper().getDefaultConfiguration()); generatePlatformProperties( platform, config, - props.getProperty(VisualPropertySupport.translatePropertyName(config.getDisplayName(),DefaultPropertiesDescriptor.PLATFORM_DEVICE,useDef)), - props.getProperty(VisualPropertySupport.translatePropertyName(config.getDisplayName(),DefaultPropertiesDescriptor.PLATFORM_PROFILE,useDef)), - props - ); + props.getProperty(VisualPropertySupport.translatePropertyName(config.getDisplayName(), DefaultPropertiesDescriptor.PLATFORM_DEVICE, useDef)), + props.getProperty(VisualPropertySupport.translatePropertyName(config.getDisplayName(), DefaultPropertiesDescriptor.PLATFORM_PROFILE, useDef)), + props); } - helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props); + helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); ProjectManager.getDefault().saveProject(this); - } catch (IOException ex) - { + } catch (IOException ex) { ErrorManager.getDefault().notify(ex); - } + } } } } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectGenerator.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectGenerator.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectGenerator.java Wed Nov 26 00:47:25 2008 -0500 @@ -40,7 +40,6 @@ */ package org.netbeans.modules.mobility.project; -import java.awt.EventQueue; import org.netbeans.api.java.platform.JavaPlatform; import org.netbeans.api.java.platform.JavaPlatformManager; import org.netbeans.api.java.platform.Profile; @@ -82,15 +81,32 @@ import org.xml.sax.InputSource; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import java.io.*; import java.text.MessageFormat; -import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.jar.Manifest; import java.util.jar.Attributes; import java.util.regex.Pattern; import java.beans.PropertyVetoException; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Set; import javax.swing.DefaultComboBoxModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -223,10 +239,10 @@ public class J2MEProjectGenerator { final AntProjectHelper oldHelper = oldProject.getLookup().lookup(AntProjectHelper.class); final Element data = h.getPrimaryConfigurationData(true); final Document doc = data.getOwnerDocument(); - final Element nameEl = doc.createElementNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, NAME); // NOI18N + final Element nameEl = doc.createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, NAME); // NOI18N nameEl.appendChild(doc.createTextNode(name)); data.appendChild(nameEl); - final Element minant = doc.createElementNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "minimum-ant-version"); // NOI18N + final Element minant = doc.createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "minimum-ant-version"); // NOI18N minant.appendChild(doc.createTextNode("1.6")); // NOI18N data.appendChild(minant); h.putPrimaryConfigurationData(data, true); @@ -347,12 +363,20 @@ public class J2MEProjectGenerator { final AntProjectHelper h = ProjectGenerator.createProject(projectLocation, J2MEProjectType.TYPE); final Element data = h.getPrimaryConfigurationData(true); final Document doc = data.getOwnerDocument(); - final Element nameEl = doc.createElementNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, NAME); // NOI18N + final Element nameEl = doc.createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, NAME); // NOI18N nameEl.appendChild(doc.createTextNode(name)); data.appendChild(nameEl); - final Element minant = doc.createElementNS(J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "minimum-ant-version"); // NOI18N + + final Element srcRoots = doc.createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "source-roots"); + final Element defaultRoot = doc.createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "root"); + defaultRoot.setAttribute("id", "src.dir"); + srcRoots.appendChild(defaultRoot); + data.appendChild(srcRoots); + + final Element minant = doc.createElementNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, "minimum-ant-version"); // NOI18N minant.appendChild(doc.createTextNode("1.6")); // NOI18N data.appendChild(minant); + h.putPrimaryConfigurationData(data, true); EditableProperties ep = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); EditableProperties priv = h.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); @@ -812,6 +836,7 @@ public class J2MEProjectGenerator { return null; } + @SuppressWarnings("empty-statement") private static FileObject createProjectLocation(File dir) throws IOException { dir = dir.getCanonicalFile(); File rootF = dir; @@ -1075,7 +1100,7 @@ public class J2MEProjectGenerator { protected static void fillMissingMIDlets(final Project project, final AntProjectHelper helper) { final ReferenceHelper refHelper = project.getLookup().lookup(ReferenceHelper.class); final ProjectConfigurationsHelper confHelper = project.getLookup().lookup(ProjectConfigurationsHelper.class); - final MIDletScanner scanner = MIDletScanner.getDefault(new J2MEProjectProperties(project, helper, refHelper, confHelper)); + final MIDletScanner scanner = MIDletScanner.getDefault(new J2MEProjectProperties((J2MEProject) project, helper, refHelper, confHelper)); final DefaultComboBoxModel midlets = new DefaultComboBoxModel(); scanner.scan(midlets, null, null, new ChangeListener() { diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectOperations.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectOperations.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectOperations.java Wed Nov 26 00:47:25 2008 -0500 @@ -43,6 +43,7 @@ import java.io.File; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import org.apache.tools.ant.module.api.support.ActionUtils; @@ -92,13 +93,8 @@ public class J2MEProjectOperations imple } public List getDataFiles() { - final List files = new ArrayList(); - final String srcRoot = helper.getStandardPropertyEvaluator().getProperty("src.dir"); - if (srcRoot != null) { - final FileObject src = helper.resolveFileObject(srcRoot); - if (src != null) files.add(src); - } - return files; + J2MESources sources = project.getLookup().lookup (J2MESources.class); + return Arrays.asList (sources.getSourceRoots()); } public void notifyDeleting() throws IOException { diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectType.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectType.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MEProjectType.java Wed Nov 26 00:47:25 2008 -0500 @@ -24,7 +24,7 @@ * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * 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 @@ -53,7 +53,9 @@ public final class J2MEProjectType imple public static final String TYPE = "org.netbeans.modules.kjava.j2meproject"; //NOI18N private static final String PROJECT_CONFIGURATION_NAME = "data"; //NOI18N + @Deprecated public static final String PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2me-project"; //NOI18N + public static final String MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/multiroot-j2me-project"; //NOI18N private static final String PRIVATE_CONFIGURATION_NAME = "data"; //NOI18N private static final String PRIVATE_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2me-project-private"; //NOI18N @@ -70,7 +72,8 @@ public final class J2MEProjectType imple } public String getPrimaryConfigurationDataElementNamespace(final boolean shared) { - return shared ? PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE; +// return shared ? PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE; + return shared ? MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE; } } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/J2MESources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/J2MESources.java Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,230 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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-2006 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.mobility.project; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeEvent; +import java.io.File; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.openide.util.Mutex; +import org.netbeans.api.project.Sources; +import org.netbeans.api.project.SourceGroup; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.java.project.JavaProjectConstants; +import org.netbeans.modules.java.api.common.SourceRoots; +import org.netbeans.modules.mobility.project.ui.customizer.J2MEProjectProperties; +import org.netbeans.spi.project.support.GenericSources; +import org.netbeans.spi.project.support.ant.SourcesHelper; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.ChangeSupport; +import org.openide.util.NbBundle; + +/** + * Copied from J2SEProject with modifications. + */ +public class J2MESources implements Sources, PropertyChangeListener, ChangeListener { + + private static final String BUILD_DIR_PROP = + "${" + J2MEProjectProperties.BUILD_DIR + "}"; //NOI18N + private static final String DIST_DIR_PROP = + "${" + J2MEProjectProperties.DIST_DIR + "}"; //NOI18N + private final AntProjectHelper helper; + private final PropertyEvaluator evaluator; + private final SourceRoots sourceRoots; + private final SourceRoots testRoots; + private SourcesHelper sourcesHelper; + private Sources delegate; + /** + * Flag to forbid multiple invocation of {@link SourcesHelper#registerExternalRoots} + **/ + private boolean externalRootsRegistered; + private final ChangeSupport changeSupport = new ChangeSupport(this); + + J2MESources(AntProjectHelper helper, PropertyEvaluator evaluator, + SourceRoots sourceRoots, SourceRoots testRoots) { + this.helper = helper; + this.evaluator = evaluator; + this.sourceRoots = sourceRoots; + this.testRoots = testRoots; + this.sourceRoots.addPropertyChangeListener(this); + this.testRoots.addPropertyChangeListener(this); + this.evaluator.addPropertyChangeListener(this); + initSources(); // have to register external build roots eagerly + } + + public FileObject[] getSourceRoots() { + return sourceRoots.getRoots(); + } + + /** + * Returns an array of SourceGroup of given type. It delegates to {@link SourcesHelper}. + * This method firstly acquire the {@link ProjectManager#mutex} in read mode then it enters + * into the synchronized block to ensure that just one instance of the {@link SourcesHelper} + * is created. These instance is cleared also in the synchronized block by the + * {@link J2SESources#fireChange} method. + */ + public SourceGroup[] getSourceGroups(final String type) { + return ProjectManager.mutex().readAccess(new Mutex.Action() { + + public SourceGroup[] run() { + Sources _delegate; + synchronized (J2MESources.this) { + if (delegate == null) { + delegate = initSources(); + delegate.addChangeListener(J2MESources.this); + } + _delegate = delegate; + } + SourceGroup[] groups = _delegate.getSourceGroups(type); + if (type.equals(Sources.TYPE_GENERIC)) { + FileObject libLoc = getSharedLibraryFolderLocation(); + if (libLoc != null) { + SourceGroup[] grps = new SourceGroup[groups.length + 1]; + System.arraycopy(groups, 0, grps, 0, groups.length); + grps[grps.length - 1] = GenericSources.group(null, libLoc, + "sharedlibraries", // NOI18N + NbBundle.getMessage(J2MESources.class, "LibrarySourceGroup_DisplayName"), + null, null); + return grps; + } + } + return groups; + } + }); + } + + private FileObject getSharedLibraryFolderLocation() { + String libLoc = helper.getLibrariesLocation(); + if (libLoc != null) { + String libLocEval = evaluator.evaluate(libLoc); + File file = null; + if (libLocEval != null) { + file = helper.resolveFile(libLocEval); + } + FileObject libLocFO = FileUtil.toFileObject(file); + if (libLocFO != null) { + //#126366 this can happen when people checkout the project but not the libraries description + //that is located outside the project + FileObject libLocParent = libLocFO.getParent(); + return libLocParent; + } + } + return null; + } + + private Sources initSources() { + this.sourcesHelper = new SourcesHelper(helper, evaluator); //Safe to pass APH + register(sourceRoots); + register(testRoots); + this.sourcesHelper.addNonSourceRoot(BUILD_DIR_PROP); + this.sourcesHelper.addNonSourceRoot(DIST_DIR_PROP); + externalRootsRegistered = false; + ProjectManager.mutex().postWriteRequest(new Runnable() { + + public void run() { + if (!externalRootsRegistered) { + sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); + externalRootsRegistered = true; + } + } + }); + return this.sourcesHelper.createSources(); + } + + private void register(SourceRoots roots) { + String[] propNames = roots.getRootProperties(); + String[] rootNames = roots.getRootNames(); + for (int i = 0; i < propNames.length; i++) { + String prop = propNames[i]; + String displayName = roots.getRootDisplayName(rootNames[i], prop); + String loc = "${" + prop + "}"; // NOI18N + String includes = "${" + J2MEProjectProperties.INCLUDES + "}"; // NOI18N + String excludes = "${" + J2MEProjectProperties.EXCLUDES + "}"; // NOI18N + sourcesHelper.addPrincipalSourceRoot(loc, includes, excludes, displayName, null, null); // NOI18N + sourcesHelper.addTypedSourceRoot(loc, includes, excludes, JavaProjectConstants.SOURCES_TYPE_JAVA, displayName, null, null); // NOI18N + } + } + + public void addChangeListener(ChangeListener changeListener) { + changeSupport.addChangeListener(changeListener); + } + + public void removeChangeListener(ChangeListener changeListener) { + changeSupport.removeChangeListener(changeListener); + } + + private void fireChange() { + synchronized (this) { + if (delegate != null) { + delegate.removeChangeListener(this); + delegate = null; + } + } + changeSupport.fireChange(); + } + + public void propertyChange(PropertyChangeEvent evt) { + String propName = evt.getPropertyName(); + if (SourceRoots.PROP_ROOT_PROPERTIES.equals(propName) || + J2MEProjectProperties.BUILD_DIR.equals(propName) || + J2MEProjectProperties.DIST_DIR.equals(propName)) { + this.fireChange(); + } + } + + public void stateChanged(ChangeEvent event) { + this.fireChange(); + } + + public FileObject rootFor (FileObject file) { + for (FileObject fo : getSourceRoots()) { + if (FileUtil.isParentOf(fo, file)) { + return fo; + } + } + return null; + } +} diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/TextSwitcher.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/TextSwitcher.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/TextSwitcher.java Wed Nov 26 00:47:25 2008 -0500 @@ -82,7 +82,7 @@ public class TextSwitcher implements Pro protected ProjectConfigurationsHelper pch; protected static RequestProcessor switchProcessor = new RequestProcessor(TEXT_SWITCH_SUPPORT); - protected static Object lockObserver = new Object(); + protected static final Object lockObserver = new Object(); /** Creates a new instance of TextSwitcher */ public TextSwitcher(Project p, AntProjectHelper h) { @@ -130,15 +130,18 @@ public class TextSwitcher implements Pro } if (processed == null) return; - final String srcDir = h.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - if (srcDir == null) return; - final FileObject src = h.resolveFileObject(srcDir); - if (src == null || !src.isFolder()) return; - final Enumeration ch = DataFolder.findFolder(src).children(true); - while (ch.hasMoreElements()) { - final DataObject dob = (DataObject)ch.nextElement(); - if (!processed.contains(dob)) { - doSwitch(dob,false); + + J2MESources sources = p.getLookup().lookup (J2MESources.class); + if (sources != null) { + for (FileObject root : sources.getSourceRoots()) { + if (root.isFolder()) { + for (Enumeration en = DataFolder.findFolder(root).children(true); en.hasMoreElements();) { + DataObject dob = en.nextElement(); + if (!processed.contains(dob)) { + doSwitch(dob, false); + } + } + } } } } @@ -165,14 +168,11 @@ public class TextSwitcher implements Pro identifiers.put(pch.getActiveConfiguration().getDisplayName(),null); final CommentingPreProcessor cpp =new CommentingPreProcessor(ppSrc, ppDest, identifiers) ; -// final MDRepository rep = JavaModel.getJavaRepository(); -// rep.beginTrans(false); try { doc.putProperty(TextSwitcher.SKIP_DUCUMENT_CHANGES, TextSwitcher.SKIP_DUCUMENT_CHANGES); NbDocument.runAtomic(doc, cpp); } finally { doc.putProperty(TextSwitcher.SKIP_DUCUMENT_CHANGES, null); -// rep.endTrans(); } return true; diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/Updater.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/Updater.java Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,226 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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-2006 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.mobility.project; + +import java.io.IOException; +import javax.swing.JButton; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.modules.java.api.common.ant.UpdateImplementation; +import org.netbeans.spi.project.AuxiliaryConfiguration; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.EditableProperties; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.util.Mutex; +import org.openide.util.NbBundle; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +public final class Updater implements UpdateImplementation, Mutex.Action { + + private final AuxiliaryConfiguration cfg; + private final AntProjectHelper helper; + private final J2MEProject project; + private final boolean TRANSPARENT_UPDATE = + Boolean.getBoolean("j2meproject.transparentUpdate"); // NOI18N + private final String BUILD_NUMBER = + System.getProperty("netbeans.buildnumber"); // NOI18N + private Boolean isCurrent; + private boolean asked = false; + + Updater(J2MEProject project, AntProjectHelper helper, AuxiliaryConfiguration cfg) { + super(); + this.project = project; + this.helper = helper; + this.cfg = cfg; + } + + public boolean isCurrent() { + return ProjectManager.mutex().readAccess(this).booleanValue(); + } + + public boolean canUpdate() { + if (TRANSPARENT_UPDATE) { + return true; + } + //Ask just once under a single write access + if (asked) { + return false; + } else { + boolean canUpdate = showUpdateDialog(); + if (!canUpdate) { + asked = true; + ProjectManager.mutex().postReadRequest(new Runnable() { + + public void run() { + asked = false; + } + }); + } + return canUpdate; + } + } + + private boolean showUpdateDialog() { + JButton updateOption = new JButton(NbBundle.getMessage(Updater.class, + "CTL_UpdateOption")); //NOI18N + updateOption.getAccessibleContext().setAccessibleDescription( + NbBundle.getMessage(Updater.class, "AD_UpdateOption")); //NOI18N + return DialogDisplayer.getDefault().notify( + new NotifyDescriptor(NbBundle.getMessage(Updater.class, + "TXT_ProjectUpdate", BUILD_NUMBER), //NOI18N + NbBundle.getMessage(Updater.class, "TXT_ProjectUpdateTitle"), //NOI18N + NotifyDescriptor.DEFAULT_OPTION, + NotifyDescriptor.WARNING_MESSAGE, + new Object[]{updateOption, NotifyDescriptor.CANCEL_OPTION}, + updateOption)) == updateOption; + } + + @SuppressWarnings(value = "deprecation") //NOI18N + public void saveUpdate(final EditableProperties props) throws IOException { + System.err.println("Upgrading " + project.getProjectDirectory().getPath()); + this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(), true); + this.cfg.removeConfigurationFragment("data", + J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, true); //NOI18N + ProjectManager.getDefault().saveProject(this.project); + synchronized (this) { + this.isCurrent = Boolean.TRUE; + } + } + + @SuppressWarnings(value = "deprecation") //NOI18N + public Element getUpdatedSharedConfigurationData() { + Element cachedElement = null; + if (cachedElement == null) { + @SuppressWarnings(value = "deprecation") //NOI18N + Element oldRoot = this.cfg.getConfigurationFragment("data", //NOI18N + J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, true); + if (oldRoot != null) { + Document doc = oldRoot.getOwnerDocument(); + Element newRoot = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "data"); //NOI18N + copyDocument(doc, oldRoot, newRoot); + Element sourceRoots = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "source-roots"); //NOI18N + Element root = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "root"); //NOI18N + root.setAttribute("id", "src.dir"); //NOI18N + sourceRoots.appendChild(root); + newRoot.appendChild(sourceRoots); + cachedElement = newRoot; + } else { + oldRoot = this.cfg.getConfigurationFragment("data", //NOI18N + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + true); + if (oldRoot != null) { + Document doc = oldRoot.getOwnerDocument(); + Element newRoot = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "data"); //NOI18N + copyDocument(doc, oldRoot, newRoot); + cachedElement = newRoot; + } + } + } + return cachedElement; + } + + public static void copyDocument(Document doc, Element from, Element to) { + NodeList nl = from.getChildNodes(); + int length = nl.getLength(); + for (int i = 0; i < length; i++) { + Node node = nl.item(i); + Node newNode = null; + switch (node.getNodeType()) { + case Node.ELEMENT_NODE: + Element oldElement = (Element) node; + newNode = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + oldElement.getTagName()); + NamedNodeMap m = oldElement.getAttributes(); + Element newElement = (Element) newNode; + for (int index = 0; index < m.getLength(); index++) { + Node attr = m.item(index); + newElement.setAttribute(attr.getNodeName(), + attr.getNodeValue()); + } + copyDocument(doc, oldElement, newElement); + break; + case Node.TEXT_NODE: + Text oldText = (Text) node; + newNode = doc.createTextNode(oldText.getData()); + break; + case Node.COMMENT_NODE: + Comment oldComment = (Comment) node; + newNode = doc.createComment(oldComment.getData()); + break; + } + if (newNode != null) { + to.appendChild(newNode); + } + } + } + + public EditableProperties getUpdatedProjectProperties() { + return helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); + } + + @SuppressWarnings("deprecation") + public synchronized Boolean run() { + if (isCurrent == null) { + if (cfg.getConfigurationFragment("data", //NOI18N + J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, true) != null) { + isCurrent = Boolean.FALSE; + } else { + isCurrent = Boolean.TRUE; + } + } + return isCurrent; + } +} diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/classpath/J2MEClassPathProvider.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/classpath/J2MEClassPathProvider.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/classpath/J2MEClassPathProvider.java Wed Nov 26 00:47:25 2008 -0500 @@ -41,18 +41,28 @@ package org.netbeans.modules.mobility.project.classpath; import java.lang.ref.SoftReference; +import java.util.HashMap; +import java.util.Map; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.modules.java.api.common.SourceRoots; +import org.netbeans.modules.java.api.common.classpath.ClassPathSupportFactory; +import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; +import org.netbeans.modules.mobility.project.J2MEProject; import org.netbeans.modules.mobility.project.J2MEProjectUtils; +import org.netbeans.modules.mobility.project.ui.customizer.J2MEProjectProperties; import org.netbeans.spi.java.classpath.ClassPathFactory; +import org.netbeans.spi.java.classpath.ClassPathImplementation; import org.netbeans.spi.java.classpath.ClassPathProvider; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.PropertyProvider; import org.netbeans.spi.project.support.ant.PropertyUtils; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.util.Mutex; import org.openide.util.WeakListeners; /** @@ -62,13 +72,16 @@ public class J2MEClassPathProvider imple public class J2MEClassPathProvider implements ClassPathProvider { private SoftReference ctcp, rtcp, sp, bcp; - private FileObject srcDir; protected final AntProjectHelper helper; + private final SourceRoots sourceRoots; + private final SourceRoots testSourceRoots; /** Do nothing */ - public J2MEClassPathProvider(AntProjectHelper helper) { + public J2MEClassPathProvider(AntProjectHelper helper, SourceRoots sourceRoots, SourceRoots testRoots) { this.helper = helper; + this.sourceRoots = sourceRoots; + this.testSourceRoots = testRoots; } public ClassPath findClassPath(final FileObject file, final String type) { @@ -76,19 +89,18 @@ public class J2MEClassPathProvider imple if (!checkSrcParent(file)) return null; if (type.equals(ClassPath.COMPILE)) return getCompileTimeClasspath(); if (type.equals(ClassPath.EXECUTE)) return getRunTimeClasspath(); - if (type.equals(ClassPath.SOURCE)) return getSourcepath(); + if (type.equals(ClassPath.SOURCE)) return getSourcepath(0); // Unrecognized type, ignore. return null; } public boolean checkSrcParent(final FileObject file) { - if (srcDir == null || !srcDir.isValid()) { - final String prop = helper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - if (prop != null) { - srcDir = helper.resolveFileObject(prop); + for (FileObject root : sourceRoots.getRoots()) { + if (root.equals(file) || FileUtil.isParentOf(root, file)) { + return true; } } - return (srcDir != null && file != null && (srcDir.equals(file) || FileUtil.isParentOf(srcDir, file))); + return false; } public ClassPath getCompileTimeClasspath() { @@ -107,6 +119,127 @@ public class J2MEClassPathProvider imple } return cp; } + + //COPIED FROM J2SEPROJECT + /** + * Find what a given file represents. + * @param file a file in the project + * @return one of:
+ *
0
normal source
+ *
1
test source
+ *
2
built class (unpacked)
+ *
3
built test class
+ *
4
built class (in dist JAR)
+ *
-1
something else
+ *
+ */ + private int getType(FileObject file) { + FileObject[] srcPath = getPrimarySrcPath(); + for (int i=0; i < srcPath.length; i++) { + FileObject root = srcPath[i]; + if (root.equals(file) || FileUtil.isParentOf(root, file)) { + return 0; + } + } + srcPath = getTestSrcDir(); + for (int i=0; i< srcPath.length; i++) { + FileObject root = srcPath[i]; + if (root.equals(file) || FileUtil.isParentOf(root, file)) { + return 1; + } + } + FileObject dir = getBuildClassesDir(); + if (dir != null && (dir.equals(file) || FileUtil.isParentOf(dir, file))) { + return 2; + } + dir = getDistJar(); // not really a dir at all, of course + if (dir != null && dir.equals(FileUtil.getArchiveFile(file))) { + // XXX check whether this is really the root + return 4; + } + dir = getBuildTestClassesDir(); + if (dir != null && (dir.equals(file) || FileUtil.isParentOf(dir,file))) { + return 3; + } + return -1; + } + + private static final String BUILD_CLASSES_DIR = "build.classes.dir"; // NOI18N + private static final String DIST_JAR = DefaultPropertiesDescriptor.DIST_JAR; + private static final String BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; // NOI18N + private FileObject getBuildClassesDir() { + return getDir(BUILD_CLASSES_DIR); + } + + private FileObject getDistJar() { + return getDir(DIST_JAR); + } + + private FileObject getBuildTestClassesDir() { + //XXX probably want test and build dirs the same for ME? + return getDir(BUILD_TEST_CLASSES_DIR); + } + + private final ClassPath[] cache = new ClassPath[8]; + private final Map dirCache = new HashMap(); + private FileObject getDir(final String propname) { + return ProjectManager.mutex().readAccess(new Mutex.Action() { + public FileObject run() { + synchronized (J2MEClassPathProvider.this) { + FileObject fo = (FileObject) J2MEClassPathProvider.this.dirCache.get (propname); + if (fo == null || !fo.isValid()) { + String prop = helper.getStandardPropertyEvaluator().getProperty(propname); + if (prop != null) { + fo = helper.resolveFileObject(prop); + J2MEClassPathProvider.this.dirCache.put (propname, fo); + } + } + return fo; + } + }}); + } + + private FileObject[] getPrimarySrcPath() { + return this.sourceRoots.getRoots(); + } + + private FileObject[] getTestSrcDir() { + return this.testSourceRoots.getRoots(); + } + + public ClassPath getSourcepath() { + return getSourcepath(0); + } + + private ClassPath getSourcepath(int type) { + if (type < 0 || type > 1) { + return null; + } + ClassPath cp = null;//cache[type]; //Cache causes a deadlock - not going to diagnose now + if (cp == null) { + switch (type) { + case 0: { + ClassPathImplementation impl = + ClassPathSupportFactory.createSourcePathImplementation( + sourceRoots, helper, + helper.getStandardPropertyEvaluator()); + cp = ClassPathFactory.createClassPath(impl); + break; + } + case 1: + ClassPathImplementation impl = + ClassPathSupportFactory.createSourcePathImplementation( + testSourceRoots, helper, + helper.getStandardPropertyEvaluator()); + cp = ClassPathFactory.createClassPath(impl); + break; + } + } + cache[type] = cp; + return cp; + } + + //END COPY public ClassPath getRunTimeClasspath() { ClassPath cp = null; @@ -114,28 +247,13 @@ public class J2MEClassPathProvider imple cp = ClassPathFactory.createClassPath( new ProjectClassPathImplementation(helper) { protected String evaluatePath() { - String cp = helper.getStandardPropertyEvaluator().getProperty("build.classes.dir"); //NOI18N + String cp = helper.getStandardPropertyEvaluator().getProperty( + J2MEProjectProperties.BUILD_CLASSES_DIR); if (cp != null) cp = helper.resolvePath(cp); return cp; } }); rtcp = new SoftReference(cp); - } - return cp; - } - - public ClassPath getSourcepath() { - ClassPath cp = null; - if (sp == null || (cp = sp.get()) == null) { - cp = ClassPathFactory.createClassPath( - new ProjectClassPathImplementation(helper) { - protected String evaluatePath() { - String cp = helper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - if (cp != null) cp = helper.resolvePath(cp); - return cp; - } - }); - sp = new SoftReference(cp); } return cp; } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/queries/CompiledSourceForBinaryQuery.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/queries/CompiledSourceForBinaryQuery.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/queries/CompiledSourceForBinaryQuery.java Wed Nov 26 00:47:25 2008 -0500 @@ -43,7 +43,6 @@ import java.io.File; import java.io.File; import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.openide.ErrorManager; import org.openide.filesystems.FileObject; import java.net.URL; import java.net.MalformedURLException; @@ -51,6 +50,7 @@ import java.util.Arrays; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.netbeans.api.java.queries.SourceForBinaryQuery; import org.netbeans.api.project.ProjectUtils; @@ -65,6 +65,8 @@ import org.openide.util.WeakListeners; import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; +import org.netbeans.modules.mobility.project.J2MESources; +import org.openide.util.Exceptions; import org.openide.util.RequestProcessor; public class CompiledSourceForBinaryQuery implements SourceForBinaryQueryImplementation { @@ -106,42 +108,47 @@ public class CompiledSourceForBinaryQuer } private FileObject[] createRoots() { - final ArrayList roots = new ArrayList(); + final List roots = new ArrayList(); try { final URL projectRoot = URLMapper.findURL(helper.getProjectDirectory(), URLMapper.EXTERNAL); URL distRoot = helper.resolveFile("dist").toURI().toURL(); //NOI18N URL buildRoot = helper.resolveFile("build").toURI().toURL(); //NOI18N if (J2MEProjectUtils.isParentOf(distRoot, binaryRoot) || J2MEProjectUtils.isParentOf(buildRoot, binaryRoot)) { - final String srcPath = helper.getStandardPropertyEvaluator().getProperty("src.dir"); //NOI18N - final FileObject src = srcPath == null ? null : helper.resolveFileObject(srcPath); - if (src != null) roots.add(src); + J2MESources sources = project.getLookup().lookup(J2MESources.class); final String cfg = J2MEProjectUtils.detectConfiguration(projectRoot, binaryRoot); - String path = J2MEProjectUtils.evaluateProperty(helper, "libs.classpath", cfg); //NOI18N - if (path != null) path = helper.resolvePath(path); - if (path != null) { - final String p[] = PropertyUtils.tokenizePath(path); - for (int i=0; i statuses = new WeakHashMap(); - private FileObject srcRoot = null; + private final J2MEProject project; - public FileBuiltQueryImpl(AntProjectHelper helper, ProjectConfigurationsHelper confs) { + public FileBuiltQueryImpl(J2MEProject project, AntProjectHelper helper, ProjectConfigurationsHelper confs) { this.helper = helper; + this.project = project; confs.addPropertyChangeListener(this); - } - - protected FileObject getSrcRoot() { - if (srcRoot == null) { - final String dir = helper.getStandardPropertyEvaluator().getProperty(DefaultPropertiesDescriptor.SRC_DIR); - if (dir != null) srcRoot = helper.resolveFileObject(dir); - } - return srcRoot; } public FileBuiltQuery.Status getStatus(final FileObject file) { @@ -131,10 +126,16 @@ public class FileBuiltQueryImpl implemen } private StatusImpl createStatus(final FileObject file) { - final FileObject root = getSrcRoot(); - if (root != null && file != null && FileUtil.isParentOf(root, file) && file.getExt().equals("java")) try { //NOI18N - return new StatusImpl(file); - } catch (DataObjectNotFoundException dnfe) {} + J2MESources sources = project.getLookup().lookup (J2MESources.class); + for (FileObject fo : sources.getSourceRoots()) { + if (FileUtil.isParentOf(fo, file) && file.getExt().equals("java")) { //NOI18N + try { + return new StatusImpl(file); + } catch (DataObjectNotFoundException ex) { + Exceptions.printStackTrace(ex); + } + } + } return null; } @@ -153,8 +154,9 @@ public class FileBuiltQueryImpl implemen } private synchronized File getTarget() { - final FileObject root = getSrcRoot(); + J2MESources sources = project.getLookup().lookup(J2MESources.class); final FileObject srcFile = source.getPrimaryFile(); + final FileObject root = sources.rootFor(srcFile); if (root == null || srcFile == null) return null; final String path = FileUtil.getRelativePath(root, srcFile); final String buildClasses = helper.getStandardPropertyEvaluator().getProperty("build.classes.dir"); //NOI18N diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/resources/multiroot-j2me-project.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/resources/multiroot-j2me-project.xsd Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/J2MECustomizerProvider.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/J2MECustomizerProvider.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/J2MECustomizerProvider.java Wed Nov 26 00:47:25 2008 -0500 @@ -47,6 +47,7 @@ import javax.swing.JButton; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; +import org.netbeans.modules.mobility.project.J2MEProject; import org.netbeans.modules.mobility.project.ui.customizer.J2MECustomizer; import org.netbeans.modules.mobility.project.ui.customizer.J2MEProjectProperties; import org.netbeans.modules.mobility.project.ProjectConfigurationsHelper; @@ -108,11 +109,13 @@ public class J2MECustomizerProvider impl options[ OPTION_CANCEL ].setActionCommand( COMMAND_CANCEL ); // RegisterListener - final J2MEProjectProperties j2meProperties = new J2MEProjectProperties( project, antProjectHelper, refHelper, configHelper ); + final J2MEProjectProperties j2meProperties = new J2MEProjectProperties((J2MEProject) project, antProjectHelper, refHelper, configHelper ); final ActionListener optionsListener = new OptionListener( this, project, j2meProperties ); options[ OPTION_OK ].addActionListener( optionsListener ); options[ OPTION_CANCEL ].addActionListener( optionsListener ); final J2MECustomizer customizer = addConfig ? new J2MECustomizer( j2meProperties, J2MECustomizer.ADD_CONFIG_DIALOG) : new J2MECustomizer( j2meProperties ); + + //XXX Add Sources Panel dialogDescriptor = new DialogDescriptor( customizer, // innerPane ProjectUtils.getInformation(project).getDisplayName(), // displayName diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/J2MEProjectRootNode.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/J2MEProjectRootNode.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/J2MEProjectRootNode.java Wed Nov 26 00:47:25 2008 -0500 @@ -1,3 +1,41 @@ package org.netbeans.modules.mobility.pr +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 2008 Sun Microsystems, Inc. + */ package org.netbeans.modules.mobility.project.ui; import java.awt.Image; @@ -25,7 +63,6 @@ import org.openide.actions.FindAction; import org.openide.actions.FindAction; import org.openide.filesystems.FileObject; import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.HelpCtx; import org.openide.util.ImageUtilities; @@ -51,7 +88,7 @@ final class J2MEProjectRootNode extends } private J2MEProjectRootNode(J2MEProject project, ProjectRootNodeChildren childFactory) { - super(Children.create(childFactory, true), Lookups.singleton(project)); + super(childFactory, Lookups.singleton(project)); this.broken = project.hasBrokenLinks(); this.nodeUpdateTask = RequestProcessor.getDefault().create(this); setName(ProjectUtils.getInformation(project).getDisplayName()); @@ -62,11 +99,6 @@ final class J2MEProjectRootNode extends this.ref3 = WeakListeners.propertyChange(this, LibraryManager.getDefault()); LibraryManager.getDefault().addPropertyChangeListener(ref3); JavaPlatformManager.getDefault().addPropertyChangeListener(ref1); - } - - protected boolean testSourceRoot() { - AntProjectHelper helper = getLookup().lookup(J2MEProject.class).getLookup().lookup(AntProjectHelper.class); - return helper.resolveFileObject(helper.getStandardPropertyEvaluator().getProperty("src.dir")) != null; } protected void checkBroken() { diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/ProjectRootNodeChildren.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/ProjectRootNodeChildren.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/ProjectRootNodeChildren.java Wed Nov 26 00:47:25 2008 -0500 @@ -38,29 +38,26 @@ */ package org.netbeans.modules.mobility.project.ui; -import java.util.Arrays; -import java.util.List; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collections; import org.netbeans.api.java.project.JavaProjectConstants; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; +import org.netbeans.modules.java.api.common.SourceRoots; import org.netbeans.modules.mobility.project.J2MEProject; import org.netbeans.modules.mobility.project.ui.ProjectRootNodeChildren.ChildKind; import org.netbeans.spi.java.project.support.ui.PackageView; -import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; -import org.openide.nodes.FilterNode; import org.openide.nodes.Node; -import org.openide.util.NbBundle; -import org.openide.util.lookup.Lookups; +import org.openide.util.RequestProcessor; /** * * @author Tim Boudreau */ -public class ProjectRootNodeChildren extends ChildFactory { +public class ProjectRootNodeChildren extends Children.Keys implements PropertyChangeListener, Runnable { private final J2MEProject project; @@ -74,13 +71,20 @@ public class ProjectRootNodeChildren ext this.project = project; } - protected boolean createKeys(List toPopulate) { - toPopulate.addAll(Arrays.asList(ChildKind.values())); - return true; + @Override + protected void addNotify() { + setKeys (ChildKind.values()); + project.getSourceRoots().addPropertyChangeListener(this); } @Override - protected Node[] createNodesForKey(ChildKind key) { + protected void removeNotify() { + setKeys (Collections.EMPTY_SET); + project.getSourceRoots().removePropertyChangeListener(this); + } + + @Override + protected Node[] createNodes(ChildKind key) { switch (key) { case Configurations: return new Node[]{createConfigurationsNode()}; @@ -108,11 +112,22 @@ public class ProjectRootNodeChildren ext final SourceGroup sg[] = src.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); result = new Node[sg.length]; int ix = 0; - //in preparation for multiple source roots for (SourceGroup group : sg) { - result[ix++] = PackageView.createPackageView(sg[0]); + result[ix++] = PackageView.createPackageView(group); } } - return result.length == 0 ? new Node[] { Node.EMPTY } : result; + return result.length == 0 ? new Node[0] : result; + } + + public void propertyChange(PropertyChangeEvent evt) { + System.err.println("Got change from source roots: " + evt.getPropertyName()); + if (SourceRoots.PROP_ROOTS.equals(evt.getPropertyName())) { + //Get this out of the way of ProjectManager.mutex() + RequestProcessor.getDefault().post(this); + } + } + + public void run() { + refreshKey(ChildKind.Sources); } } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/Bundle.properties --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/Bundle.properties Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/Bundle.properties Wed Nov 26 00:47:25 2008 -0500 @@ -111,6 +111,7 @@ LBL_Customizer_Category=&Category\: # Configuration node labels Customizer/org.netbeans.modules.kjava.j2meproject/general=General Customizer/org.netbeans.modules.kjava.j2meproject/general/general=General +Customizer/org.netbeans.modules.kjava.j2meproject/Sources=Sources Customizer/org.netbeans.modules.kjava.j2meproject/Platform=Platform Customizer/org.netbeans.modules.kjava.j2meproject/Platform/CLDC=CLDC/MIDP Customizer/org.netbeans.modules.kjava.j2meproject/Abilities=Abilities @@ -691,7 +692,7 @@ LBL_CustPlatform_NoCustomizer=No customi LBL_CustPlatform_NoCustomizer=No customizer for selected platform type is available. LBL_CustMain_AppVersion=&Application Version Number\: LBL_CustMain_AppCounter=Application &Version Counter\: -LBL_CustMain_AutoIncrement=Automated Appl&ication Version Incrementation +LBL_CustMain_AutoIncrement=Automatically Increment Appl&ication Version LBL_NewConfigPanel_ConfigurationPrefix=&New Configurations Prefix\: LBL_NewConfigPanel_ConfigurationSuffix=&Suffix\: ACSN_jButtonAddMore=Add more @@ -706,8 +707,8 @@ ACSD_CustMain_AppVersion=Application Ver ACSD_CustMain_AppVersion=Application Version Number ACSN_CustMain_AppCounter=Application Version Counter ACSD_CustMain_AppCounter=Application Version Counter -ACSN_CustMain_AutoIncrement=Automated Application Version Incrementation -ACSD_CustMain_AutoIncrement=Select for Automated Application Version Incrementation +ACSN_CustMain_AutoIncrement=Automatically Increment Application Version +ACSD_CustMain_AutoIncrement=Select to automatically increment application version ACSN_CustomizeGeneral_UsePreprocessor=Use Preprocessor ACSD_CustomizeGeneral_UsePreprocessor=Select to use Preprocessor ACSN_CustGeneral_RequiredProjects=Required Projects @@ -737,3 +738,67 @@ ACSD_UseDefault=Uses Values from "Defaul ACSD_UseDefault=Uses Values from "DefaultConfiguration" ACSN_SelectPlatform=Select platform type ACSD_SelectPlatform=Chooses platform type from list + + +#CustomizerSources +CTL_ProjectFolder=Project Folder +TITLE_InvalidRoot=Add Package Folder +MSG_InvalidRoot=Package Folder Already Used in Project\n\ + Following folders you selected are already used in this or another\n\ + project. One package folder can only be used in one project in one\n\ + package folder list (source packages or test packages). +LBL_InvalidRoot=Package folders already in use: +MNE_InvalidRoot=A +MSG_InvalidRoot2=Those folders cannot be added to the project. +AD_InvalidRoot=N/A +AD_InvalidRootDlg=N/A +CTL_J2SESourceRootsUi_Close=Close +AD_J2SESourceRootsUi_Close=N/A +CTL_ChangePlatform=Change Platform +AD_ChangePlatform=N/A +TXT_ChangePlatform=Incompatible Source Level Value {0}\n\ + The source level version for this project ({0}) is higher than the\n\ + Java Platform version you just selected ({1}). Changing the Java\n\ + Platform will update the project''s source level to version {1}.\n\n\ + Do you want to change the Java Platform and update the source level\n\ + version? +TXT_ChangePlatformTitle=Change Java Platform +CustomizerSources.includeExcludeButton= +CustomizerSources.title.includeExclude=Configure Includes & Excludes +MSG_EncodingWarning=Changing project encoding might result in some characters in existing files not being read and written correctly. +CTL_ProjectFolder_1=Project Folder +CTL_SourceRoots=Source Roots +CTL_TestRoots=Test Roots +TXT_SourceLevel=Source Level +TXT_Encoding=Encoding +CTL_AddSourceRoot=Add Source Root +CTL_RemoveSourceRoot=Remove Source Root +CTL_UpSourceRoot=Up +CTL_DownSourceRoot=Down +CTL_AddTestRoot=Add Test Source Root +CTL_RemoveTestRoot=Remove Test Source Root +CTL_UpTestRoot=Up +CTL_DownTestRoot=Down +CustomizerSources.includeExcludeButton_1=&Includes/Excludes... + + +##################################### +#J2MESourceRootsUI +##################################### +CTL_PackageFolders=Package Folder +CTL_PackageLabels=Label +CTL_J2SESourceRootsUi_Close=Close +AD_J2SESourceRootsUi_Close=N/A +CTL_ProjectFolder=Project Folder +TITLE_InvalidRoot=Add Package Folder +MSG_InvalidRoot=Package Folder Already Used in Project\n\ + Following folders you selected are already used in this or another\n\ + project. One package folder can only be used in one project in one\n\ + package folder list (source packages or test packages). +LBL_InvalidRoot=Package folders already in use: +MNE_InvalidRoot=A +MSG_InvalidRoot2=Those folders cannot be added to the project. +LBL_SourceFolder_DialogTitle=Add Source Folder +LBL_TestFolder_DialogTitle=Add Test Folder +TXT_RootOwnedByProject={0} (owned by {1}) +DEFAULT_PACKAGE= diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerAbilities.form --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerAbilities.form Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerAbilities.form Wed Nov 26 00:47:25 2008 -0500 @@ -1,8 +1,10 @@ -
+ + + diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerAbilities.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerAbilities.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerAbilities.java Wed Nov 26 00:47:25 2008 -0500 @@ -65,6 +65,7 @@ import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.spi.project.ProjectConfiguration; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; @@ -89,7 +90,7 @@ public class CustomizerAbilities extends final protected JTable table; final protected StorableTableModel tableModel; private VisualPropertySupport vps; - private ProjectProperties props; + private MultiRootProjectProperties props; /** Creates new form CustomizerConfigs */ public CustomizerAbilities() { @@ -204,7 +205,7 @@ public class CustomizerAbilities extends getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerAbilities.class, "ACSD_CustAbilities")); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.props = props; vps = VisualPropertySupport.getDefault(props); vps.register(cDefault, configuration, this); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerCompile.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerCompile.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerCompile.java Wed Nov 26 00:47:25 2008 -0500 @@ -44,6 +44,7 @@ import java.util.Arrays; import java.util.Arrays; import java.util.Comparator; import javax.swing.JPanel; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -76,7 +77,7 @@ public class CustomizerCompile extends J Arrays.sort(ENCODINGS, new EncodingComparator()); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(defaultCheck, configuration, this); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerDeploy.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerDeploy.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerDeploy.java Wed Nov 26 00:47:25 2008 -0500 @@ -61,6 +61,7 @@ import javax.swing.JSlider; import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.text.JTextComponent; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.modules.mobility.project.deployment.MobilityDeploymentManagerPanel; @@ -86,7 +87,7 @@ public class CustomizerDeploy extends JP private MobilityDeploymentProperties mdp = new MobilityDeploymentProperties(); private String config; - private ProjectProperties pp; + private MultiRootProjectProperties pp; private Component cComp = null; /** Creates new form CustomizerConfigs */ @@ -213,7 +214,7 @@ public class CustomizerDeploy extends JP getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerRun.class, "ACSD_CustDeploy")); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { for ( DeploymentPlugin p : Lookup.getDefault().lookup(new Lookup.Template(DeploymentPlugin.class)).allInstances() ){ if (p instanceof CustomizerPanel){ ((CustomizerPanel)p).initValues(props, configuration); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerFiltering.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerFiltering.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerFiltering.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,25 +50,37 @@ import java.awt.Dimension; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.beans.PropertyChangeListener; +import java.beans.PropertyVetoException; +import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Map; import java.util.regex.Pattern; +import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JPanel; import javax.swing.plaf.basic.BasicBorders; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; +import org.netbeans.api.project.SourceGroup; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.modules.mobility.project.ui.customizer.regex.CheckedTreeBeanView; import org.netbeans.modules.mobility.project.ui.customizer.regex.FileObjectCookie; +import org.netbeans.spi.java.project.support.ui.PackageView; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; import org.openide.explorer.ExplorerManager; import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileStateInvalidException; import org.openide.filesystems.FileUtil; +import org.openide.filesystems.LocalFileSystem; +import org.openide.filesystems.MultiFileSystem; import org.openide.loaders.DataObject; -import org.openide.loaders.DataObjectNotFoundException; import org.openide.nodes.FilterNode; import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** @@ -91,7 +103,7 @@ public class CustomizerFiltering extends private Pattern filter; private Map properties; private String configuration; - private FileObject srcRoot; + private FileObject[] srcRoots; private String excludesTranslatedPropertyName; /** Creates new form CustomizerConfigs */ @@ -211,12 +223,14 @@ public class CustomizerFiltering extends treeView.getAccessibleContext().setAccessibleDescription( jLabelTree.getText() ); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.vps = VisualPropertySupport.getDefault(props); this.properties = props; this.configuration = configuration; - this.srcRoot = props.getSourceRoot(); - treeView.setSrcRoot(srcRoot); + + this.srcRoots = props.getSourceRoots(); + + treeView.setSrcRoots(srcRoots); vps.register(defaultCheck, configuration, this); } @@ -255,14 +269,91 @@ public class CustomizerFiltering extends } } this.filter = Pattern.compile(sFilter); - try { - final DataObject dob = DataObject.find(srcRoot); - manager.setRootContext(new FOBNode(dob.getNodeDelegate().cloneNode(), dob.getPrimaryFile())); - } catch (DataObjectNotFoundException dnfe) { - manager.setRootContext(Node.EMPTY); - } +// Node rootNode = new AbstractNode (Children.create(new RootNodeFactory(), false)); + Node rootNode = new FOBNode(PackageView.createPackageView(new FakeSourceGroup(srcRoots)), null); + manager.setRootContext(rootNode); treeView.registerProperty(properties, excludesTranslatedPropertyName, filter); } + + private static final class FakeSourceGroup implements SourceGroup { + private final FileObject[] roots; + private final MultiFileSystem fs; + FakeSourceGroup(FileObject[] roots) { + this.roots = roots; + LocalFileSystem[] perRoot = new LocalFileSystem[roots.length]; + for (int i = 0; i < perRoot.length; i++) { + perRoot[i] = new LocalFileSystem(); + try { + perRoot[i].setRootDirectory(FileUtil.toFile(roots[i])); + } catch (PropertyVetoException ex) { + Exceptions.printStackTrace(ex); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + fs = new MultiFileSystem (perRoot); + } + + public FileObject getRootFolder() { + return fs.getRoot(); + } + + public String getName() { + return "X"; + } + + public String getDisplayName() { + return getName(); + } + + public Icon getIcon(boolean opened) { + //Not visible, doesn't matter, but renderer will throw an exception + return new ImageIcon(ImageUtilities.loadImage( + "org/netbeans/modules/mobility/project/ui/resources/config.gif")); + } + + public boolean contains(FileObject file) throws IllegalArgumentException { + try { + return file.getFileSystem() == fs; + } catch (FileStateInvalidException ex) { + Exceptions.printStackTrace(ex); + return false; + } + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + //do nothing + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + //do nothing + } + + } + +// private final class RootNodeFactory extends ChildFactory { +// @Override +// protected Node createNodeForKey(ClassPath.Entry key) { +//// try { +//// DataObject dob = DataObject.find(key); +//// return new FOBNode(dob.getNodeDelegate(), key); +//// } catch (DataObjectNotFoundException ex) { +//// Exceptions.printStackTrace(ex); +//// return null; +//// } +// } +// +// @Override +// protected boolean createKeys(List toPopulate) { +// ClassPath path = ClassPathFactory.createClassPath(new CPI(srcRoots)); +// +// for (FileObject fo : srcRoots) { +// toPopulate.addAll(path.entries()); +// } +//// toPopulate.addAll (Arrays.asList (srcRoots)); +// } +// } + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox defaultCheck; @@ -275,7 +366,15 @@ public class CustomizerFiltering extends // End of variables declaration//GEN-END:variables boolean acceptFileObject(final FileObject fo) { - final String path = FileUtil.getRelativePath(srcRoot, fo); +// FileObject root = null; +// for (FileObject test : srcRoots) { +// if (fo.getPath().startsWith(test.getPath())) { +// root = test; +// } +// } +// assert root != null : fo.getPath() + " not a child of any of the " + +// "following project source roots: " + Arrays.asList(srcRoots); + final String path = fo.getPath(); return path != null && !filter.matcher(path).matches(); } @@ -287,11 +386,14 @@ public class CustomizerFiltering extends private class FOBNode extends FilterNode implements FileObjectCookie { private final FileObject fo; public FOBNode(Node n, FileObject fo) { - super(n, fo.isData() ? org.openide.nodes.Children.LEAF : new FOBChildren(n)); + super(n, fo != null && fo.isData() ? org.openide.nodes.Children.LEAF : new FOBChildren(n)); this.fo = fo; disableDelegation(DELEGATE_SET_NAME | DELEGATE_GET_NAME | DELEGATE_SET_DISPLAY_NAME | DELEGATE_GET_DISPLAY_NAME); - setName(fo.getNameExt()); - setDisplayName(fo.getNameExt()); +// setName(fo == null ? "" : fo.getNameExt()); + setName (fo == null ? "" : fo.getPath()); + setDisplayName(fo == null || "".equals(getName()) ? NbBundle.getMessage(FOBNode.class, + "DEFAULT_PACKAGE") : fo.getNameExt()); + setShortDescription(getName()); } public Node.Cookie getCookie(final Class type) { @@ -300,7 +402,7 @@ public class CustomizerFiltering extends } public FileObject getFileObject() { - return fo; + return fo == null ? getLookup().lookup(DataObject.class).getPrimaryFile() : fo; } } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerGeneral.form --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerGeneral.form Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerGeneral.form Wed Nov 26 00:47:25 2008 -0500 @@ -97,47 +97,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -224,11 +183,6 @@ - - - - - @@ -251,11 +205,6 @@ - - - - - diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerGeneral.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerGeneral.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerGeneral.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,7 +50,7 @@ import javax.swing.DefaultListModel; import javax.swing.DefaultListModel; import javax.swing.JPanel; import javax.swing.JSpinner; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.ant.AntArtifact; @@ -71,7 +71,7 @@ import org.openide.util.NbBundle; */ public class CustomizerGeneral extends JPanel implements CustomizerPanel, ActionListener { - private ProjectProperties props; + private MultiRootProjectProperties props; /** Creates new form CustomizerCompile */ public CustomizerGeneral() { @@ -79,13 +79,12 @@ public class CustomizerGeneral extends J initAccessibility(); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.props = props; final VisualPropertySupport vps = VisualPropertySupport.getDefault(props); vps.register(jTextFieldDisplayName, J2MEProjectProperties.J2ME_PROJECT_NAME); vps.register(rebuildCheckBox, DefaultPropertiesDescriptor.NO_DEPENDENCIES); - vps.register(jTextFieldSrcRoot, DefaultPropertiesDescriptor.SRC_DIR); vps.register(jTextFieldAppVersion, DefaultPropertiesDescriptor.APP_VERSION_NUMBER); vps.register(jSpinnerCounter, DefaultPropertiesDescriptor.APP_VERSION_COUNTER); vps.register(jCheckBoxAutoIncrement, DefaultPropertiesDescriptor.APP_VERSION_AUTOINCREMENT); @@ -190,8 +189,6 @@ public class CustomizerGeneral extends J jTextFieldDisplayName = new javax.swing.JTextField(); jLabel3 = new javax.swing.JLabel(); jTextFieldProjectFolder = new javax.swing.JTextField(); - jLabel4 = new javax.swing.JLabel(); - jTextFieldSrcRoot = new javax.swing.JTextField(); jLabel5 = new javax.swing.JLabel(); jTextFieldAppVersion = new javax.swing.JTextField(); jLabel6 = new javax.swing.JLabel(); @@ -247,25 +244,6 @@ public class CustomizerGeneral extends J jTextFieldProjectFolder.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CustomizerGeneral.class, "ACSN_CustGeneral_PrjFolder")); // NOI18N jTextFieldProjectFolder.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerGeneral.class, "ACSD_CustGeneral_PrjFolder")); // NOI18N - jLabel4.setLabelFor(jTextFieldSrcRoot); - org.openide.awt.Mnemonics.setLocalizedText(jLabel4, NbBundle.getMessage(CustomizerGeneral.class, "LBL_CustomizeGeneral_SrcDir")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - gridBagConstraints.insets = new java.awt.Insets(11, 0, 0, 12); - add(jLabel4, gridBagConstraints); - jLabel4.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CustomizerGeneral.class, "ACSN_CustomizeGeneral_SrcDir")); // NOI18N - jLabel4.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CustomizerGeneral.class, "ACSD_CustomizeGeneral_SrcDir")); // NOI18N - - jTextFieldSrcRoot.setEditable(false); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); - add(jTextFieldSrcRoot, gridBagConstraints); - jTextFieldSrcRoot.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CustomizerGeneral.class, "ACSN_CustGeneral_PrjSources")); // NOI18N - jTextFieldSrcRoot.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerGeneral.class, "ACSD_CustGeneral_PrjSources")); // NOI18N - jLabel5.setLabelFor(jTextFieldAppVersion); org.openide.awt.Mnemonics.setLocalizedText(jLabel5, NbBundle.getMessage(CustomizerGeneral.class, "LBL_CustMain_AppVersion")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); @@ -309,7 +287,6 @@ public class CustomizerGeneral extends J jSpinnerCounter.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CustomizerGeneral.class, "ACSD_AppVersionCounter")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jCheckBoxAutoIncrement, NbBundle.getMessage(CustomizerGeneral.class, "LBL_CustMain_AutoIncrement")); // NOI18N - jCheckBoxAutoIncrement.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); jCheckBoxAutoIncrement.setMargin(new java.awt.Insets(0, 0, 0, 0)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -323,7 +300,6 @@ public class CustomizerGeneral extends J jCheckBoxAutoIncrement.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CustomizerGeneral.class, "ACSD_CustMain_AutoIncrement")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jCheckBoxUsePreprocessor, NbBundle.getMessage(CustomizerGeneral.class, "LBL_CustomizeGeneral_UsePreprocessor")); // NOI18N - jCheckBoxUsePreprocessor.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); jCheckBoxUsePreprocessor.setMargin(new java.awt.Insets(0, 0, 0, 0)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -386,7 +362,6 @@ public class CustomizerGeneral extends J private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; - private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JScrollPane jScrollPane1; @@ -394,7 +369,6 @@ public class CustomizerGeneral extends J private javax.swing.JTextField jTextFieldAppVersion; private javax.swing.JTextField jTextFieldDisplayName; private javax.swing.JTextField jTextFieldProjectFolder; - private javax.swing.JTextField jTextFieldSrcRoot; private javax.swing.JList projectList; private javax.swing.JCheckBox rebuildCheckBox; // End of variables declaration//GEN-END:variables diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJad.form --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJad.form Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJad.form Wed Nov 26 00:47:25 2008 -0500 @@ -1,7 +1,9 @@ - + + + diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJad.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJad.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJad.java Wed Nov 26 00:47:25 2008 -0500 @@ -49,7 +49,6 @@ import java.awt.Dialog; import java.awt.Dialog; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; @@ -61,7 +60,7 @@ import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.VisualPropertyGroup; @@ -300,7 +299,7 @@ public class CustomizerJad extends JPane table.getSelectionModel().setSelectionInterval(max - 1, max - 1); }//GEN-LAST:event_bRemoveActionPerformed - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.configuration = configuration; configurationProfileValue = (String) props.get(VisualPropertySupport.translatePropertyName(configuration, "platform.profile", false)); defaultProfileValue = (String) props.get("platform.profile"); //NOI18N diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJar.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJar.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJar.java Wed Nov 26 00:47:25 2008 -0500 @@ -41,6 +41,7 @@ package org.netbeans.modules.mobility.project.ui.customizer; import javax.swing.JPanel; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -67,7 +68,7 @@ public class CustomizerJar extends JPane } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { vps = VisualPropertySupport.getDefault(props); vps.register(defaultCheck, configuration, this); } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJavadoc.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJavadoc.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerJavadoc.java Wed Nov 26 00:47:25 2008 -0500 @@ -41,6 +41,7 @@ package org.netbeans.modules.mobility.project.ui.customizer; import javax.swing.JPanel; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -78,7 +79,7 @@ public class CustomizerJavadoc extends J } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.vps = VisualPropertySupport.getDefault(props); vps.register(defaultCheck, configuration, this); } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerLibraries.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerLibraries.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerLibraries.java Wed Nov 26 00:47:25 2008 -0500 @@ -52,7 +52,7 @@ import java.util.Set; import java.util.Set; import javax.swing.JPanel; import javax.swing.UIManager; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.modules.mobility.project.ui.customizer.VisualClassPathItem; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; @@ -72,7 +72,7 @@ public class CustomizerLibraries extends private VisualPropertySupport vps; final private VisualClasspathSupport vcs; private String configuration; - private ProjectProperties props; + private MultiRootProjectProperties props; /** Creates new form CustomizerConfigs */ public CustomizerLibraries() { @@ -231,7 +231,7 @@ public class CustomizerLibraries extends getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerLibraries.class, "ACSD_CustLibs")); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.vps = VisualPropertySupport.getDefault(props); this.props = props; this.configuration = configuration; diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerMIDP.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerMIDP.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerMIDP.java Wed Nov 26 00:47:25 2008 -0500 @@ -61,7 +61,7 @@ import org.netbeans.api.java.platform.Pl import org.netbeans.api.java.platform.PlatformsCustomizer; import org.netbeans.api.java.platform.Profile; import org.netbeans.api.java.platform.Specification; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; import org.netbeans.modules.mobility.cldcplatform.J2MEPlatform; @@ -226,7 +226,7 @@ final public class CustomizerMIDP extend } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.props = props; this.vps = VisualPropertySupport.getDefault(props); this.configuration = configuration; diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerMIDlets.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerMIDlets.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerMIDlets.java Wed Nov 26 00:47:25 2008 -0500 @@ -56,6 +56,7 @@ import javax.swing.event.*; import javax.swing.event.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -318,7 +319,7 @@ public class CustomizerMIDlets extends J } }//GEN-LAST:event_addButtonActionPerformed - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.vps = VisualPropertySupport.getDefault(props); classes = icons = null; final MIDletScanner scanner = MIDletScanner.getDefault(props); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerObfuscate.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerObfuscate.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerObfuscate.java Wed Nov 26 00:47:25 2008 -0500 @@ -50,6 +50,7 @@ import javax.swing.*; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -194,7 +195,7 @@ public class CustomizerObfuscate extends getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerObfuscate.class, "ACSD_CustomizerObfuscate")); } - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.vps = VisualPropertySupport.getDefault(props); vps.register(defaultCheck, configuration, this); } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerPermissions.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerPermissions.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerPermissions.java Wed Nov 26 00:47:25 2008 -0500 @@ -60,7 +60,7 @@ import javax.swing.event.ListSelectionLi import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport; @@ -227,7 +227,7 @@ public class CustomizerPermissions exten table.getSelectionModel().setSelectionInterval(max - 1, max - 1); }//GEN-LAST:event_bRemoveActionPerformed - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.configuration = configuration; configurationProfileValue = (String) props.get(VisualPropertySupport.translatePropertyName(configuration, "platform.profile", false)); // NOI18N defaultProfileValue = (String) props.get("platform.profile"); //NOI18N diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerPlatform.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerPlatform.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerPlatform.java Wed Nov 26 00:47:25 2008 -0500 @@ -52,7 +52,7 @@ import javax.swing.JList; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.spi.mobility.project.ui.customizer.ComposedCustomizerPanel; import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; @@ -73,7 +73,7 @@ public class CustomizerPlatform extends public class CustomizerPlatform extends JPanel implements ComposedCustomizerPanel, VisualPropertyGroup, ActionListener { private final ArrayList typeElements = new ArrayList(); - private ProjectProperties props; + private MultiRootProjectProperties props; private boolean useDefault; private HelpCtxCallback callback; @@ -163,7 +163,7 @@ public class CustomizerPlatform extends add(jPanel1, gridBagConstraints); }// //GEN-END:initComponents - public void initValues(ProjectProperties props, String configuration) { + public void initValues(MultiRootProjectProperties props, String configuration) { this.props = props; for (int i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerSources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/CustomizerSources.java Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,732 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Deve1loper of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 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.mobility.project.ui.customizer; + +import java.awt.Component; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.io.File; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.IllegalCharsetNameException; +import java.util.logging.Logger; +import javax.swing.DefaultCellEditor; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; +import javax.swing.UIManager; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; +import javax.swing.plaf.UIResource; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; +import org.netbeans.modules.mobility.project.J2MEProject; +import org.netbeans.spi.mobility.project.ui.customizer.CustomizerPanel; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; + +/** + * Customizer panel "Sources": source roots, level, includes/excludes. + * @author Tomas Zezula + */ +public class CustomizerSources extends javax.swing.JPanel implements HelpCtx.Provider, CustomizerPanel { + //Copied from J2SEProject + private String originalEncoding; + private boolean notified; + + private J2MEProjectProperties uiProperties; + + public CustomizerSources() { + initComponents(); + } + + public void initValues(MultiRootProjectProperties props, String configuration) { + this.uiProperties = (J2MEProjectProperties) props; + jScrollPane1.getViewport().setBackground( sourceRoots.getBackground() ); + jScrollPane2.getViewport().setBackground( testRoots.getBackground() ); + + sourceRoots.setModel( uiProperties.SOURCE_ROOTS_MODEL ); + testRoots.setModel( uiProperties.TEST_ROOTS_MODEL ); + sourceRoots.getTableHeader().setReorderingAllowed(false); + testRoots.getTableHeader().setReorderingAllowed(false); + J2MEProject project = ((J2MEProjectProperties) uiProperties).getProject(); + + FileObject projectFolder = project.getProjectDirectory(); + File pf = FileUtil.toFile( projectFolder ); + this.projectLocation.setText( pf == null ? "" : pf.getPath() ); // NOI18N + + + J2MESourceRootsUi.EditMediator emSR = J2MESourceRootsUi.registerEditMediator( + project, + project.getSourceRoots(), + sourceRoots, + addSourceRoot, + removeSourceRoot, + upSourceRoot, + downSourceRoot, + new LabelCellEditor(sourceRoots, testRoots)); + + J2MESourceRootsUi.EditMediator emTSR = J2MESourceRootsUi.registerEditMediator( + project, + project.getTestSourceRoots(), + testRoots, + addTestRoot, + removeTestRoot, + upTestRoot, + downTestRoot, + new LabelCellEditor(sourceRoots, testRoots)); + + emSR.setRelatedEditMediator( emTSR ); + emTSR.setRelatedEditMediator( emSR ); + this.sourceLevel.setEditable(false); + this.sourceLevel.setModel(uiProperties.JAVAC_SOURCE_MODEL); + this.sourceLevel.setRenderer(uiProperties.JAVAC_SOURCE_RENDERER); + uiProperties.JAVAC_SOURCE_MODEL.addListDataListener(new ListDataListener () { + public void intervalAdded(ListDataEvent e) { + enableSourceLevel (); + } + + public void intervalRemoved(ListDataEvent e) { + enableSourceLevel (); + } + + public void contentsChanged(ListDataEvent e) { + enableSourceLevel (); + } + }); + enableSourceLevel (); + this.originalEncoding = project.evaluator().getProperty(J2MEProjectProperties.SOURCE_ENCODING); + if (this.originalEncoding == null) { + this.originalEncoding = Charset.defaultCharset().name(); + } + + this.encoding.setModel(new EncodingModel(this.originalEncoding)); + this.encoding.setRenderer(new EncodingRenderer()); + final String lafid = UIManager.getLookAndFeel().getID(); + if (!"Aqua".equals(lafid)) { //NOI18N + this.encoding.putClientProperty ("JComboBox.isTableCellEditor", Boolean.TRUE); //NOI18N + this.encoding.addItemListener(new java.awt.event.ItemListener(){ + public void itemStateChanged(java.awt.event.ItemEvent e){ + javax.swing.JComboBox combo = (javax.swing.JComboBox)e.getSource(); + combo.setPopupVisible(false); + } + }); + } + this.encoding.addActionListener(new ActionListener () { + public void actionPerformed(ActionEvent arg0) { + handleEncodingChange(); + } + }); + initTableVisualProperties(sourceRoots); + initTableVisualProperties(testRoots); + } + + private class TableColumnSizeComponentAdapter extends ComponentAdapter { + private JTable table = null; + + public TableColumnSizeComponentAdapter(JTable table){ + this.table = table; + } + + public void componentResized(ComponentEvent evt){ + double pw = table.getParent().getParent().getSize().getWidth(); + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + TableColumn column = table.getColumnModel().getColumn(0); + column.setWidth( ((int)pw/2) - 1 ); + column.setPreferredWidth( ((int)pw/2) - 1 ); + column = table.getColumnModel().getColumn(1); + column.setWidth( ((int)pw/2) - 1 ); + column.setPreferredWidth( ((int)pw/2) - 1 ); + } + } + + private void initTableVisualProperties(JTable table) { + + table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + table.setIntercellSpacing(new java.awt.Dimension(0, 0)); + // set the color of the table's JViewport + table.getParent().setBackground(table.getBackground()); + + //we'll get the parents width so we can use that to set the column sizes. + double pw = table.getParent().getParent().getPreferredSize().getWidth(); + + //#88174 - Need horizontal scrollbar for library names + //ugly but I didn't find a better way how to do it + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + TableColumn column = table.getColumnModel().getColumn(0); + column.setMinWidth(226); + column.setWidth( ((int)pw/2) - 1 ); + column.setPreferredWidth( ((int)pw/2) - 1 ); + column.setMinWidth(75); + column = table.getColumnModel().getColumn(1); + column.setMinWidth(226); + column.setWidth( ((int)pw/2) - 1 ); + column.setPreferredWidth( ((int)pw/2) - 1 ); + column.setMinWidth(75); + this.addComponentListener(new TableColumnSizeComponentAdapter(table)); + } + + private void handleEncodingChange () { + Charset enc = (Charset) encoding.getSelectedItem(); + String encName; + if (enc != null) { + encName = enc.name(); + } + else { + encName = originalEncoding; + } + if (!notified && encName!=null && !encName.equals(originalEncoding)) { + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( + NbBundle.getMessage(CustomizerSources.class,"MSG_EncodingWarning"), NotifyDescriptor.WARNING_MESSAGE)); + notified=true; + } + this.uiProperties.put(J2MEProjectProperties.SOURCE_ENCODING, encName); + } + + public HelpCtx getHelpCtx() { + return new HelpCtx (CustomizerSources.class); + } + + private void enableSourceLevel () { + this.sourceLevel.setEnabled(sourceLevel.getItemCount()>0); + } + + + private static class EncodingRenderer extends JLabel implements ListCellRenderer, UIResource { + + public EncodingRenderer() { + setOpaque(true); + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + assert value instanceof Charset; + setName("ComboBox.listRenderer"); // NOI18N + setText(((Charset) value).displayName()); + setIcon(null); + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + return this; + } + + @Override + public String getName() { + String name = super.getName(); + return name == null ? "ComboBox.renderer" : name; // NOI18N + } + + } + + private static class EncodingModel extends DefaultComboBoxModel { + + public EncodingModel (String originalEncoding) { + Charset defEnc = null; + for (Charset c : Charset.availableCharsets().values()) { + if (c.name().equals(originalEncoding)) { + defEnc = c; + } + addElement(c); + } + if (defEnc == null) { + //Create artificial Charset to keep the original value + //May happen when the project was set up on the platform + //which supports more encodings + try { + defEnc = new UnknownCharset (originalEncoding); + addElement(defEnc); + } catch (IllegalCharsetNameException e) { + //The source.encoding property is completely broken + Logger.getLogger(this.getClass().getName()).info("IllegalCharsetName: " + originalEncoding); + } + } + if (defEnc == null) { + defEnc = Charset.defaultCharset(); + } + setSelectedItem(defEnc); + } + } + + private static class UnknownCharset extends Charset { + + UnknownCharset (String name) { + super (name, new String[0]); + } + + public boolean contains(Charset c) { + throw new UnsupportedOperationException(); + } + + public CharsetDecoder newDecoder() { + throw new UnsupportedOperationException(); + } + + public CharsetEncoder newEncoder() { + throw new UnsupportedOperationException(); + } +} + + private static class ResizableRowHeightTable extends JTable { + + private boolean needResize = true; + + @Override + public void setFont(Font font) { + needResize = true; + super.setFont(font); + } + + @Override + public void paint(Graphics g) { + if(needResize) { + this.setRowHeight(g.getFontMetrics(this.getFont()).getHeight()); + needResize = false; + } + super.paint(g); + } + + } + + private static class LabelCellEditor extends DefaultCellEditor { + + private JTable sourceRoots; + private JTable testRoots; + + public LabelCellEditor(JTable sourceRoots, JTable testRoots) { + super(new JTextField()); + this.sourceRoots = sourceRoots; + this.testRoots = testRoots; + } + + @Override + public boolean stopCellEditing() { + JTextField field = (JTextField) getComponent(); + String text = field.getText(); + boolean validCell = true; + TableModel model = sourceRoots.getModel(); + int rowCount = model.getRowCount(); + for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) { + String value = (String) model.getValueAt(rowIndex, 1); + if (text.equals(value)) { + validCell = false; + } + } + model = testRoots.getModel(); + rowCount = model.getRowCount(); + for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) { + String value = (String) model.getValueAt(rowIndex, 1); + if (text.equals(value)) { + validCell = false; + } + } + + return validCell == false ? validCell : super.stopCellEditing(); + } + + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel1 = new javax.swing.JLabel(); + projectLocation = new javax.swing.JTextField(); + sourceRootsPanel = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + sourceRoots = new ResizableRowHeightTable(); + addSourceRoot = new javax.swing.JButton(); + removeSourceRoot = new javax.swing.JButton(); + upSourceRoot = new javax.swing.JButton(); + downSourceRoot = new javax.swing.JButton(); + testRootsPanel = new javax.swing.JPanel(); + jLabel3 = new javax.swing.JLabel(); + jScrollPane2 = new javax.swing.JScrollPane(); + testRoots = new ResizableRowHeightTable(); + addTestRoot = new javax.swing.JButton(); + removeTestRoot = new javax.swing.JButton(); + upTestRoot = new javax.swing.JButton(); + downTestRoot = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jLabel4 = new javax.swing.JLabel(); + sourceLevel = new javax.swing.JComboBox(); + jLabel5 = new javax.swing.JLabel(); + encoding = new javax.swing.JComboBox(); + jPanel2 = new javax.swing.JPanel(); + + setLayout(new java.awt.GridBagLayout()); + + jLabel1.setLabelFor(projectLocation); + jLabel1.setText(org.openide.util.NbBundle.getBundle(CustomizerSources.class).getString("CTL_ProjectFolder")); // NOI18N + add(jLabel1, new java.awt.GridBagConstraints()); + + projectLocation.setEditable(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + add(projectLocation, gridBagConstraints); + projectLocation.getAccessibleContext().setAccessibleDescription("null"); + + sourceRootsPanel.setLayout(new java.awt.GridBagLayout()); + + jLabel2.setLabelFor(sourceRoots); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/netbeans/modules/mobility/project/ui/customizer/Bundle"); // NOI18N + jLabel2.setText(bundle.getString("CTL_SourceRoots")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0); + sourceRootsPanel.add(jLabel2, gridBagConstraints); + + jScrollPane1.setPreferredSize(new java.awt.Dimension(450, 150)); + + sourceRoots.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null}, + {null, null}, + {null, null}, + {null, null} + }, + new String [] { + "Package Folder", "Label" + } + ) { + Class[] types = new Class [] { + java.lang.Object.class, java.lang.String.class + }; + boolean[] canEdit = new boolean [] { + false, false + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jScrollPane1.setViewportView(sourceRoots); + sourceRoots.getAccessibleContext().setAccessibleDescription("null"); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12); + sourceRootsPanel.add(jScrollPane1, gridBagConstraints); + + addSourceRoot.setText(bundle.getString("CTL_AddSourceRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + sourceRootsPanel.add(addSourceRoot, gridBagConstraints); + addSourceRoot.getAccessibleContext().setAccessibleDescription("null"); + + removeSourceRoot.setText(bundle.getString("CTL_RemoveSourceRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0); + sourceRootsPanel.add(removeSourceRoot, gridBagConstraints); + removeSourceRoot.getAccessibleContext().setAccessibleDescription("null"); + + upSourceRoot.setText(bundle.getString("CTL_UpSourceRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); + sourceRootsPanel.add(upSourceRoot, gridBagConstraints); + upSourceRoot.getAccessibleContext().setAccessibleDescription("null"); + + downSourceRoot.setText(bundle.getString("CTL_DownSourceRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0); + sourceRootsPanel.add(downSourceRoot, gridBagConstraints); + downSourceRoot.getAccessibleContext().setAccessibleDescription("null"); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.45; + gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); + add(sourceRootsPanel, gridBagConstraints); + + testRootsPanel.setLayout(new java.awt.GridBagLayout()); + + jLabel3.setLabelFor(testRoots); + jLabel3.setText(bundle.getString("CTL_TestRoots")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0); + testRootsPanel.add(jLabel3, gridBagConstraints); + + jScrollPane2.setPreferredSize(new java.awt.Dimension(450, 150)); + + testRoots.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null}, + {null, null}, + {null, null}, + {null, null} + }, + new String [] { + "Package Folder", "Label" + } + ) { + Class[] types = new Class [] { + java.lang.Object.class, java.lang.String.class + }; + boolean[] canEdit = new boolean [] { + false, false + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jScrollPane2.setViewportView(testRoots); + testRoots.getAccessibleContext().setAccessibleDescription("null"); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.5; + testRootsPanel.add(jScrollPane2, gridBagConstraints); + + addTestRoot.setText(bundle.getString("CTL_AddTestRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 12, 6, 0); + testRootsPanel.add(addTestRoot, gridBagConstraints); + addTestRoot.getAccessibleContext().setAccessibleDescription("null"); + + removeTestRoot.setText(bundle.getString("CTL_RemoveTestRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 12, 12, 0); + testRootsPanel.add(removeTestRoot, gridBagConstraints); + removeTestRoot.getAccessibleContext().setAccessibleDescription("null"); + + upTestRoot.setText(bundle.getString("CTL_UpTestRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 12, 6, 0); + testRootsPanel.add(upTestRoot, gridBagConstraints); + upTestRoot.getAccessibleContext().setAccessibleDescription("null"); + + downTestRoot.setText(bundle.getString("CTL_DownTestRoot")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0); + testRootsPanel.add(downTestRoot, gridBagConstraints); + downTestRoot.getAccessibleContext().setAccessibleDescription("null"); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.45; + gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); + add(testRootsPanel, gridBagConstraints); + + jPanel1.setLayout(new java.awt.GridBagLayout()); + + jLabel4.setLabelFor(sourceLevel); + org.openide.awt.Mnemonics.setLocalizedText(jLabel4, bundle.getString("TXT_SourceLevel")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12); + jPanel1.add(jLabel4, gridBagConstraints); + + sourceLevel.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1.4", "1.5" })); + sourceLevel.setMinimumSize(this.sourceLevel.getPreferredSize()); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.weightx = 1.0; + jPanel1.add(sourceLevel, gridBagConstraints); + sourceLevel.getAccessibleContext().setAccessibleName("null"); + sourceLevel.getAccessibleContext().setAccessibleDescription("null"); + + jLabel5.setLabelFor(encoding); + org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(CustomizerSources.class, "TXT_Encoding")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(8, 0, 0, 12); + jPanel1.add(jLabel5, gridBagConstraints); + jLabel5.getAccessibleContext().setAccessibleDescription("null"); + + encoding.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(8, 0, 0, 0); + jPanel1.add(encoding, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + jPanel1.add(jPanel2, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); + add(jPanel1, gridBagConstraints); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addSourceRoot; + private javax.swing.JButton addTestRoot; + private javax.swing.JButton downSourceRoot; + private javax.swing.JButton downTestRoot; + private javax.swing.JComboBox encoding; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JTextField projectLocation; + private javax.swing.JButton removeSourceRoot; + private javax.swing.JButton removeTestRoot; + private javax.swing.JComboBox sourceLevel; + private javax.swing.JTable sourceRoots; + private javax.swing.JPanel sourceRootsPanel; + private javax.swing.JTable testRoots; + private javax.swing.JPanel testRootsPanel; + private javax.swing.JButton upSourceRoot; + private javax.swing.JButton upTestRoot; + // End of variables declaration//GEN-END:variables + +} diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/J2MEProjectProperties.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/J2MEProjectProperties.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/J2MEProjectProperties.java Wed Nov 26 00:47:25 2008 -0500 @@ -42,7 +42,10 @@ package org.netbeans.modules.mobility.pr package org.netbeans.modules.mobility.project.ui.customizer; import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -54,9 +57,13 @@ import java.util.List; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Vector; +import javax.swing.ComboBoxModel; +import javax.swing.DefaultComboBoxModel; +import javax.swing.ListCellRenderer; +import javax.swing.table.DefaultTableModel; import org.netbeans.api.mobility.project.PropertyDescriptor; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; -import org.netbeans.api.project.Project; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.project.ProjectManager; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.queries.FileEncodingQuery; @@ -67,29 +74,34 @@ import org.netbeans.spi.mobility.project import org.netbeans.spi.mobility.project.PropertyParser; import org.netbeans.spi.mobility.project.support.DefaultPropertyParsers; import org.netbeans.api.queries.CollocationQuery; +import org.netbeans.modules.java.api.common.SourceRoots; +import org.netbeans.modules.java.api.common.ui.PlatformUiSupport; +import org.netbeans.modules.mobility.project.J2MEProject; +import org.netbeans.modules.mobility.project.J2MEProjectType; import org.netbeans.modules.mobility.project.ProjectConfigurationsHelper; +import org.netbeans.spi.project.AuxiliaryConfiguration; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.EditableProperties; import org.netbeans.spi.project.support.ant.PropertyUtils; import org.netbeans.spi.project.support.ant.ReferenceHelper; -import org.openide.ErrorManager; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.filesystems.URLMapper; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.MutexException; import org.openide.util.Mutex; import org.openide.util.NbBundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; /** Helper class. Defines constants for properties. Knows the proper * place where to store the properties. * * @author Petr Hrebejk, Adam Sotona */ -public class J2MEProjectProperties implements ProjectProperties { - - - +public class J2MEProjectProperties extends MultiRootProjectProperties { // Special properties of the project public static final String J2ME_PROJECT_NAME = "j2me.project.name"; //NOI18N @@ -99,6 +111,14 @@ public class J2MEProjectProperties imple private static final String LIBS="${libs."; + public static final String SOURCE_ENCODING = "source.encoding"; // NOI18N + public static final String BUILD_DIR = "build.dir"; // NOI18N + public static final String INCLUDES = "includes"; // NOI18N + public static final String EXCLUDES = "excludes"; // NOI18N + public static final String BUILD_CLASSES_DIR = "build.classes.dir"; + + //XXX DIST_DIR probably wrong for ME projects + public static final String DIST_DIR = "dist.dir"; // NOI18N // Info about the property destination private final Set PROPERTY_DESCRIPTORS = new HashSet(); @@ -132,22 +152,34 @@ public class J2MEProjectProperties imple // Private fields ---------------------------------------------------------- - private Project project; + private J2MEProject project; protected ReferenceHelper refHelper; protected AntProjectHelper antProjectHelper; protected HashMap properties; protected ProjectConfigurationsHelper configHelper; protected ProjectConfiguration devConfigs[]; + public DefaultTableModel SOURCE_ROOTS_MODEL; + public DefaultTableModel TEST_ROOTS_MODEL; + public ComboBoxModel JAVAC_SOURCE_MODEL; + public ListCellRenderer JAVAC_SOURCE_RENDERER; - public J2MEProjectProperties( Project project, AntProjectHelper antProjectHelper, ReferenceHelper refHelper, ProjectConfigurationsHelper configHelper) { + public J2MEProjectProperties( J2MEProject project, AntProjectHelper antProjectHelper, ReferenceHelper refHelper, ProjectConfigurationsHelper configHelper) { this.project = project; this.properties = new HashMap(); this.antProjectHelper = antProjectHelper; this.refHelper = refHelper; this.configHelper = configHelper; + SOURCE_ROOTS_MODEL = J2MESourceRootsUi.createModel( project.getSourceRoots() ); + TEST_ROOTS_MODEL = J2MESourceRootsUi.createModel( project.getTestSourceRoots() ); + JAVAC_SOURCE_MODEL = new DefaultComboBoxModel(); //XXX for testing. Covered somewhere else already? + JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer (); initPropertyDescriptors(); read(); + } + + public J2MEProject getProject() { + return project; } public synchronized void setActiveConfiguration(final ProjectConfiguration cfg) { @@ -252,7 +284,18 @@ public class J2MEProjectProperties imple } public FileObject getSourceRoot() { - return antProjectHelper.resolveFileObject(antProjectHelper.getStandardPropertyEvaluator().getProperty("src.dir")); //NOI18N + throw new UnsupportedOperationException ("getSourceRoot() deprecated. " + + "Use getSourceRoots() instead."); + } + + @Override + public FileObject[] getSourceRoots() { + URL[] urls = project.getSourceRoots().getRootURLs(); + FileObject[] result = new FileObject[urls.length]; + for (int i=0; i < urls.length; i++) { + result[i] = URLMapper.findFileObject(urls[i]); + } + return result; } /** Reads all the properties of the project and converts them to objects @@ -341,22 +384,128 @@ public class J2MEProjectProperties imple //storing global default encoding by dcurrent project (see issue #97855) String enc = sharedProps.getProperty(DefaultPropertiesDescriptor.JAVAC_ENCODING); - if (enc != null) FileEncodingQuery.setDefaultEncoding(Charset.forName(enc)); + if (enc != null) { + try { + FileEncodingQuery.setDefaultEncoding(Charset.forName(enc)); + } catch (UnsupportedCharsetException e) { + //When the encoding is not supported by JVM do not set it as default + } + } + + Vector srcRoots = SOURCE_ROOTS_MODEL.getDataVector(); +// Element dataElement = getUpdatedConfiguration (srcRoots, antProjectHelper); +// antProjectHelper.putPrimaryConfigurationData(dataElement, true); + SourceRoots roots = project.getSourceRoots(); + updateSourceRoots (roots, srcRoots); // save the project under write lock try { ProjectManager.getDefault().saveProject(project); } catch (IOException ex) { - ErrorManager.getDefault().notify(ex); + Exceptions.printStackTrace(ex); } return null; } }); } catch (MutexException e) { - ErrorManager.getDefault().notify(e.getException()); + Exceptions.printStackTrace(e); } - + } + + private final void updateSourceRoots(SourceRoots roots, List srcRoots) { + int max = srcRoots.size(); + URL[] urls = new URL[max]; + String[] names = new String[max]; + try { + for (int i=0; i < max; i++) { + Vector v = (Vector) srcRoots.get(i); + File dir = (File) v.get(0); + String name = (String) v.get(1); + urls[i] = dir.toURI().toURL(); + names[i] = name; + } + roots.putRoots(urls, names); + } catch (MalformedURLException mre) { + Exceptions.printStackTrace(mre); + } + + } + + private final Element getUpdatedConfiguration (List srcRoots, AntProjectHelper helper) { + assert ProjectManager.mutex().isWriteAccess() : "Saving roots outside" + + " of project manager mutex"; + AuxiliaryConfiguration cfg = project.getLookup().lookup(AuxiliaryConfiguration.class); + assert cfg != null; + EditableProperties publicProps = + helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); + EditableProperties privateProps = + helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); + Element dataElement = cfg.getConfigurationFragment("data", //NOI18N + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, true); + if (dataElement == null) { + //XXX recreate + throw new IllegalStateException ("Configuration missing section"); + } + Document doc = dataElement.getOwnerDocument(); + Element srcRootsElement = findSingleChild (dataElement, "source-roots"); + dataElement.removeChild(srcRootsElement); + srcRootsElement = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "source-roots"); //NOI18N + boolean pubChanged = false; + boolean privChanged = false; + for (Object o : srcRoots) { + Vector v = (Vector) o; + File dir = (File) v.get(0); + String name = (String) v.get(1); + Element root = doc.createElementNS( + J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, + "root"); //NOI18N + String id; + if (isStandardSrcDir (dir)) { + id = "src.dir"; + } else { + id = "src." + dir.getName() + ".dir"; + } + root.setAttribute("id", id); //NOI18N + if (!name.equals(dir.getName())) { + root.setAttribute ("name", name); + } + srcRootsElement.appendChild (root); + if (!dir.exists()) { + if (!dir.mkdirs()) { + throw new IllegalStateException ("Could not create " + dir); + } + } + FileObject asFileObject = FileUtil.toFileObject (FileUtil.normalizeFile(dir)); + FileObject projDir = project.getProjectDirectory(); + String relPath = FileUtil.getRelativePath(projDir, asFileObject); + if (relPath == null) { //not under the project + privateProps.put (id, dir.getPath().replace('\\', '/')); + } else { + publicProps.put(id, relPath); + } + } + if (pubChanged) { + helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, publicProps); + } + if (privChanged) { + helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, privateProps); + } + dataElement.appendChild(srcRootsElement); + return dataElement; + } + + private boolean isStandardSrcDir (File file) { + FileObject asFo = FileUtil.toFileObject (file); + FileObject standardDir = project.getProjectDirectory().getFileObject("src"); + return standardDir != null && standardDir.equals(asFo); + } + + private static Element findSingleChild (Element parent, String name) { + NodeList l = parent.getElementsByTagNameNS(J2MEProjectType.MULTIROOT_PROJECT_CONFIGURATION_NAMESPACE, name); + return (Element) ((Element) (l.getLength() == 0 ? null : l.item(0))); } /** Finds out what are new and removed project dependencies and diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/J2MESourceRootsUi.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/J2MESourceRootsUi.java Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,608 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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-2006 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.mobility.project.ui.customizer; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.util.Iterator; +import java.util.HashSet; +import java.util.Set; +import java.util.Vector; +import java.text.MessageFormat; +import java.util.Arrays; +import javax.swing.*; +import javax.swing.JButton; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.CellEditorListener; +import javax.swing.event.ChangeEvent; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import org.netbeans.api.java.project.JavaProjectConstants; +import org.netbeans.api.project.ProjectUtils; +import org.netbeans.api.project.SourceGroup; +import org.netbeans.api.project.Sources; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectInformation; +import org.netbeans.modules.java.api.common.SourceRoots; +import org.netbeans.modules.mobility.project.J2MEProject; +import org.openide.DialogDisplayer; +import org.openide.DialogDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.NbBundle; + +/** Handles adding, removing, reordering of source roots. + * + * @author Tomas Zezula + */ +public final class J2MESourceRootsUi { + + //Copied from J2SEProject + + public static DefaultTableModel createModel( SourceRoots roots ) { + + String[] rootLabels = roots.getRootNames(); + String[] rootProps = roots.getRootProperties(); + URL[] rootURLs = roots.getRootURLs(); + Object[][] data = new Object[rootURLs.length] [2]; + for (int i=0; i< rootURLs.length; i++) { + data[i][0] = new File (URI.create (rootURLs[i].toExternalForm())); + data[i][1] = roots.getRootDisplayName(rootLabels[i], rootProps[i]); + } + return new SourceRootsModel(data); + + } + + public static EditMediator registerEditMediator( J2MEProject master, + SourceRoots sourceRoots, + JTable rootsList, + JButton addFolderButton, + JButton removeButton, + JButton upButton, + JButton downButton, + CellEditor rootsListEditor) { + + EditMediator em = new EditMediator( master, + sourceRoots, + rootsList, + addFolderButton, + removeButton, + upButton, + downButton); + + // Register the listeners + // On all buttons + addFolderButton.addActionListener( em ); + removeButton.addActionListener( em ); + upButton.addActionListener( em ); + downButton.addActionListener( em ); + // On list selection + rootsList.getSelectionModel().addListSelectionListener( em ); + DefaultCellEditor editor = (DefaultCellEditor) rootsListEditor; + if (editor == null) { + editor = new DefaultCellEditor(new JTextField()); + } + editor.addCellEditorListener (em); + rootsList.setDefaultRenderer( File.class, new FileRenderer (FileUtil.toFile(master.getProjectDirectory()))); + rootsList.setDefaultEditor(String.class, editor); + // Set the initial state of the buttons + em.valueChanged( null ); + + DefaultTableModel model = (DefaultTableModel)rootsList.getModel(); + String[] columnNames = new String[2]; + columnNames[0] = NbBundle.getMessage( J2MESourceRootsUi.class,"CTL_PackageFolders"); + columnNames[1] = NbBundle.getMessage( J2MESourceRootsUi.class,"CTL_PackageLabels"); + model.setColumnIdentifiers(columnNames); + rootsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + return em; + } + + public static EditMediator registerEditMediator( J2MEProject master, + SourceRoots sourceRoots, + JTable rootsList, + JButton addFolderButton, + JButton removeButton, + JButton upButton, + JButton downButton ) { + return registerEditMediator(master, sourceRoots, rootsList, addFolderButton, + removeButton, upButton, downButton, null); + } + + /** + * Opens the standard dialog for warning an user about illegal source roots. + * @param roots the set of illegal source/test roots + */ + public static void showIllegalRootsDialog (Set/**/ roots) { + JButton closeOption = new JButton (NbBundle.getMessage(J2MESourceRootsUi.class,"CTL_J2SESourceRootsUi_Close")); + closeOption.getAccessibleContext ().setAccessibleDescription (NbBundle.getMessage(J2MESourceRootsUi.class,"AD_J2SESourceRootsUi_Close")); + JPanel warning = new WarningDlg (roots); + String message = NbBundle.getMessage(J2MESourceRootsUi.class,"MSG_InvalidRoot"); + JOptionPane optionPane = new JOptionPane (new Object[] {message, warning}, + JOptionPane.WARNING_MESSAGE, + 0, + null, + new Object[0], + null); + optionPane.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(J2MESourceRootsUi.class,"AD_InvalidRootDlg")); + DialogDescriptor dd = new DialogDescriptor (optionPane, + NbBundle.getMessage(J2MESourceRootsUi.class,"TITLE_InvalidRoot"), + true, + new Object[] { + closeOption, + }, + closeOption, + DialogDescriptor.DEFAULT_ALIGN, + null, + null); + DialogDisplayer.getDefault().notify(dd); + } + + // Private innerclasses ---------------------------------------------------- + + public static class EditMediator implements ActionListener, ListSelectionListener, CellEditorListener { + + + final JTable rootsList; + final JButton addFolderButton; + final JButton removeButton; + final JButton upButton; + final JButton downButton; + private final Project project; + private final SourceRoots sourceRoots; + private final Set ownedFolders; + private DefaultTableModel rootsModel; + private EditMediator relatedEditMediator; + private File lastUsedDir; //Last used current folder in JFileChooser + + + public EditMediator( J2MEProject master, + SourceRoots sourceRoots, + JTable rootsList, + JButton addFolderButton, + JButton removeButton, + JButton upButton, + JButton downButton) { + + if ( !( rootsList.getModel() instanceof DefaultTableModel ) ) { + throw new IllegalArgumentException( "Jtable's model has to be of class DefaultTableModel" ); // NOI18N + } + + this.rootsList = rootsList; + this.addFolderButton = addFolderButton; + this.removeButton = removeButton; + this.upButton = upButton; + this.downButton = downButton; + this.ownedFolders = new HashSet(); + + this.project = master; + this.sourceRoots = sourceRoots; + + this.ownedFolders.clear(); + this.rootsModel = (DefaultTableModel)rootsList.getModel(); + Vector data = rootsModel.getDataVector(); + for (Iterator it = data.iterator(); it.hasNext();) { + Vector row = (Vector) it.next (); + File f = (File) row.elementAt(0); + this.ownedFolders.add (f); + } + } + + public void setRelatedEditMediator(EditMediator rem) { + this.relatedEditMediator = rem; + } + + // Implementation of ActionListener ------------------------------------ + + /** Handles button events + */ + public void actionPerformed( ActionEvent e ) { + + Object source = e.getSource(); + + if ( source == addFolderButton ) { + + // Let user search for the Jar file + JFileChooser chooser = new JFileChooser(); + FileUtil.preventFileChooserSymlinkTraversal(chooser, null); + chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY ); + chooser.setMultiSelectionEnabled( true ); + if (this.sourceRoots.isTest()) { + chooser.setDialogTitle( NbBundle.getMessage( J2MESourceRootsUi.class, "LBL_TestFolder_DialogTitle" )); // NOI18N + } + else { + chooser.setDialogTitle( NbBundle.getMessage( J2MESourceRootsUi.class, "LBL_SourceFolder_DialogTitle" )); // NOI18N + } + File curDir = this.lastUsedDir; + if (curDir == null) { + curDir = FileUtil.toFile(this.project.getProjectDirectory()); + } + if (curDir != null) { + chooser.setCurrentDirectory (curDir); + } + int option = chooser.showOpenDialog( SwingUtilities.getWindowAncestor( addFolderButton ) ); // Sow the chooser + + if ( option == JFileChooser.APPROVE_OPTION ) { + curDir = chooser.getCurrentDirectory(); + if (curDir != null) { + this.lastUsedDir = curDir; + if (this.relatedEditMediator != null) { + this.relatedEditMediator.lastUsedDir = curDir; + } + } + File files[] = chooser.getSelectedFiles(); + addFolders( files ); + } + + } + else if ( source == removeButton ) { + removeElements(); + } + else if ( source == upButton ) { + moveUp(); + } + else if ( source == downButton ) { + moveDown(); + } + } + + // Selection listener implementation ---------------------------------- + + /** Handles changes in the selection + */ + public void valueChanged( ListSelectionEvent e ) { + + int[] si = rootsList.getSelectedRows(); + + // addJar allways enabled + + // addLibrary allways enabled + + // addArtifact allways enabled + + // edit enabled only if selection is not empty + boolean edit = si != null && si.length > 0; + + // remove enabled only if selection is not empty + boolean remove = si != null && si.length > 0; + // and when the selection does not contain unremovable item + + // up button enabled if selection is not empty + // and the first selected index is not the first row + boolean up = si != null && si.length > 0 && si[0] != 0; + + // up button enabled if selection is not empty + // and the laset selected index is not the last row + boolean down = si != null && si.length > 0 && si[si.length-1] !=rootsList.getRowCount() - 1; + + removeButton.setEnabled( remove ); + upButton.setEnabled( up ); + downButton.setEnabled( down ); + + //System.out.println("Selection changed " + edit + ", " + remove + ", " + + ", " + + ", "); + + } + + public void editingCanceled(ChangeEvent e) { + + } + + public void editingStopped(ChangeEvent e) { + // fireActionPerformed(); + } + + private void addFolders( File files[] ) { + System.err.println("Add folders " + Arrays.asList(files)); + int[] si = rootsList.getSelectedRows(); + int lastIndex = si == null || si.length == 0 ? -1 : si[si.length - 1]; + ListSelectionModel selectionModel = this.rootsList.getSelectionModel(); + selectionModel.clearSelection(); + Set rootsFromOtherProjects = new HashSet (); + Set rootsFromRelatedSourceRoots = new HashSet(); +out: for( int i = 0; i < files.length; i++ ) { + File normalizedFile = FileUtil.normalizeFile(files[i]); + Project p; + if (ownedFolders.contains(normalizedFile)) { + Vector dataVector = rootsModel.getDataVector(); + for (int j=0; j 0 || rootsFromRelatedSourceRoots.size() > 0) { + rootsFromOtherProjects.addAll(rootsFromRelatedSourceRoots); + showIllegalRootsDialog (rootsFromOtherProjects); + } + } + + private void removeElements() { + + int[] si = rootsList.getSelectedRows(); + + if( si == null || si.length == 0 ) { + assert false : "Remove button should be disabled"; // NOI18N + } + + // Remove the items + for( int i = si.length - 1 ; i >= 0 ; i-- ) { + this.ownedFolders.remove(((Vector)rootsModel.getDataVector().elementAt(si[i])).elementAt(0)); + rootsModel.removeRow( si[i] ); + } + + + if ( rootsModel.getRowCount() != 0) { + // Select reasonable item + int selectedIndex = si[si.length - 1] - si.length + 1; + if ( selectedIndex > rootsModel.getRowCount() - 1) { + selectedIndex = rootsModel.getRowCount() - 1; + } + rootsList.setRowSelectionInterval( selectedIndex, selectedIndex ); + } + + // fireActionPerformed(); + + } + + private void moveUp() { + + int[] si = rootsList.getSelectedRows(); + + if( si == null || si.length == 0 ) { + assert false : "MoveUp button should be disabled"; // NOI18N + } + + // Move the items up + ListSelectionModel selectionModel = this.rootsList.getSelectionModel(); + selectionModel.clearSelection(); + for( int i = 0; i < si.length; i++ ) { + Vector item = (Vector) rootsModel.getDataVector().elementAt(si[i]); + int newIndex = si[i]-1; + rootsModel.removeRow( si[i] ); + rootsModel.insertRow( newIndex, item ); + selectionModel.addSelectionInterval(newIndex,newIndex); + } + // fireActionPerformed(); + } + + private void moveDown() { + + int[] si = rootsList.getSelectedRows(); + + if( si == null || si.length == 0 ) { + assert false : "MoveDown button should be disabled"; // NOI18N + } + + // Move the items up + ListSelectionModel selectionModel = this.rootsList.getSelectionModel(); + selectionModel.clearSelection(); + for( int i = si.length -1 ; i >= 0 ; i-- ) { + Vector item = (Vector) rootsModel.getDataVector().elementAt(si[i]); + int newIndex = si[i] + 1; + rootsModel.removeRow( si[i] ); + rootsModel.insertRow( newIndex, item ); + selectionModel.addSelectionInterval(newIndex,newIndex); + } + // fireActionPerformed(); + } + + + } + + private static class SourceRootsModel extends DefaultTableModel { + + public SourceRootsModel (Object[][] data) { + super (data,new Object[]{"location","label"});//NOI18N + } + + public boolean isCellEditable(int row, int column) { + return column == 1; + } + + public Class getColumnClass(int columnIndex) { + switch (columnIndex) { + case 0: + return File.class; + case 1: + return String.class; + default: + return super.getColumnClass (columnIndex); + } + } + } + + private static class FileRenderer extends DefaultTableCellRenderer { + + private File projectFolder; + + public FileRenderer (File projectFolder) { + this.projectFolder = projectFolder; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row, int column) { + String displayName; + if (value instanceof File) { + File root = (File) value; + String pfPath = projectFolder.getAbsolutePath() + File.separatorChar; + String srPath = root.getAbsolutePath(); + if (srPath.startsWith(pfPath)) { + displayName = srPath.substring(pfPath.length()); + } + else { + displayName = srPath; + } + } + else { + displayName = null; + } + Component c = super.getTableCellRendererComponent(table, displayName, isSelected, hasFocus, row, column); + if (c instanceof JComponent) { + ((JComponent) c).setToolTipText (displayName); + } + return c; + } + + } + + private static class WarningDlg extends JPanel { + + public WarningDlg (Set invalidRoots) { + this.initGui (invalidRoots); + } + + private void initGui (Set invalidRoots) { + setLayout( new GridBagLayout ()); + JLabel label = new JLabel (); + label.setText (NbBundle.getMessage(J2MESourceRootsUi.class,"LBL_InvalidRoot")); + label.setDisplayedMnemonic(NbBundle.getMessage(J2MESourceRootsUi.class,"MNE_InvalidRoot").charAt(0)); + GridBagConstraints c = new GridBagConstraints(); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = GridBagConstraints.RELATIVE; + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.NORTHWEST; + c.weightx = 1.0; + c.insets = new Insets (12,0,6,0); + ((GridBagLayout)this.getLayout()).setConstraints(label,c); + this.add (label); + JList roots = new JList (invalidRoots.toArray()); + roots.setCellRenderer (new InvalidRootRenderer(true)); + JScrollPane p = new JScrollPane (roots); + c = new GridBagConstraints(); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = GridBagConstraints.RELATIVE; + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.BOTH; + c.anchor = GridBagConstraints.NORTHWEST; + c.weightx = c.weighty = 1.0; + c.insets = new Insets (0,0,12,0); + ((GridBagLayout)this.getLayout()).setConstraints(p,c); + this.add (p); + label.setLabelFor(roots); + roots.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(J2MESourceRootsUi.class,"AD_InvalidRoot")); + JLabel label2 = new JLabel (); + label2.setText (NbBundle.getMessage(J2MESourceRootsUi.class,"MSG_InvalidRoot2")); + c = new GridBagConstraints(); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = GridBagConstraints.RELATIVE; + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.NORTHWEST; + c.weightx = 1.0; + c.insets = new Insets (0,0,0,0); + ((GridBagLayout)this.getLayout()).setConstraints(label2,c); + this.add (label2); + } + + private static class InvalidRootRenderer extends DefaultListCellRenderer { + + private boolean projectConflict; + + public InvalidRootRenderer (boolean projectConflict) { + this.projectConflict = projectConflict; + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + File f = (File) value; + String message = f.getAbsolutePath(); + if (projectConflict) { + Project p = FileOwnerQuery.getOwner(f.toURI()); + if (p!=null) { + ProjectInformation pi = ProjectUtils.getInformation(p); + String projectName = pi.getDisplayName(); + message = MessageFormat.format (NbBundle.getMessage(J2MESourceRootsUi.class,"TXT_RootOwnedByProject"), new Object[] { + message, + projectName}); + } + } + return super.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus); + } + } + } + +} diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/MIDletScanner.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/MIDletScanner.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/MIDletScanner.java Wed Nov 26 00:47:25 2008 -0500 @@ -54,6 +54,7 @@ import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; @@ -67,6 +68,8 @@ import org.netbeans.api.java.platform.Ja import org.netbeans.api.java.platform.JavaPlatform; import org.netbeans.api.java.platform.JavaPlatformManager; import org.netbeans.api.java.platform.Specification; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; import org.netbeans.api.project.ant.AntArtifact; import org.netbeans.api.project.libraries.Library; @@ -86,7 +89,7 @@ import org.openide.util.RequestProcessor */ public class MIDletScanner implements Runnable { - private final ProjectProperties props; + private final MultiRootProjectProperties props; private J2MEPlatform activePlatform; private final HashMap> roots2icons = new HashMap>(); private final HashMap> roots2midlets = new HashMap>(); @@ -97,7 +100,7 @@ public class MIDletScanner implements Ru private static Reference cache = new WeakReference(null); - public static MIDletScanner getDefault(ProjectProperties props) { + public static MIDletScanner getDefault(MultiRootProjectProperties props) { MIDletScanner sc = cache.get(); if (sc == null || sc.props != props) { sc = new MIDletScanner(props); @@ -106,7 +109,7 @@ public class MIDletScanner implements Ru return sc; } - private MIDletScanner(ProjectProperties props) { + private MIDletScanner(MultiRootProjectProperties props) { this.props = props; } @@ -175,7 +178,8 @@ public class MIDletScanner implements Ru private HashSet getRootsFor(final String configuration) { final HashSet roots = new HashSet(); - roots.add(props.getSourceRoot()); + FileObject[] all = ((MultiRootProjectProperties) props).getSourceRoots(); + roots.addAll(Arrays.asList(all)); List cpItems = (List)props.get(VisualPropertySupport.translatePropertyName(configuration, DefaultPropertiesDescriptor.LIBS_CLASSPATH, true)); if (cpItems == null) cpItems = (List)props.get(DefaultPropertiesDescriptor.LIBS_CLASSPATH); if (cpItems == null) return roots; diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/regex/CheckedNodeEditor.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/regex/CheckedNodeEditor.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/regex/CheckedNodeEditor.java Wed Nov 26 00:47:25 2008 -0500 @@ -52,7 +52,6 @@ import java.awt.event.ItemListener; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import java.util.EventObject; -import org.openide.filesystems.FileObject; /** * User: suchys @@ -144,15 +143,21 @@ public class CheckedNodeEditor extends A if (editor instanceof CheckedNodeRenderer.RendererComponent){ ((CheckedNodeRenderer.RendererComponent)editor).removeItemListener(itemListener); } +// final Node node = Visualizer.findNode(value); +// final FileObjectCookie doj = (FileObjectCookie) node.getCookie(FileObjectCookie.class); +// if (doj != null){ +// final FileObject fo = doj.getFileObject(); +// storage.setState(fo, CheckedTreeBeanView.UNSELECTED == storage.getState(fo)); +// final TreePath path = tree.getAnchorSelectionPath(); +// ((DefaultTreeModel)tree.getModel()).reload(); +// tree.setAnchorSelectionPath(path); +// } final Node node = Visualizer.findNode(value); - final FileObjectCookie doj = (FileObjectCookie) node.getCookie(FileObjectCookie.class); - if (doj != null){ - final FileObject fo = doj.getFileObject(); - storage.setState(fo, CheckedTreeBeanView.UNSELECTED == storage.getState(fo)); - final TreePath path = tree.getAnchorSelectionPath(); - ((DefaultTreeModel)tree.getModel()).reload(); - tree.setAnchorSelectionPath(path); - } + String path = node.getName().replace('.', '/'); + storage.setState(path, CheckedTreeBeanView.UNSELECTED == storage.getState(path)); + final TreePath treePath = tree.getAnchorSelectionPath(); + ((DefaultTreeModel)tree.getModel()).reload(); + tree.setAnchorSelectionPath(treePath); } } }; diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/regex/CheckedTreeBeanView.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/regex/CheckedTreeBeanView.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/customizer/regex/CheckedTreeBeanView.java Wed Nov 26 00:47:25 2008 -0500 @@ -40,6 +40,7 @@ */ package org.netbeans.modules.mobility.project.ui.customizer.regex; +import org.openide.explorer.ExplorerManager.Provider; import org.openide.explorer.view.BeanTreeView; import java.awt.event.FocusListener; @@ -49,9 +50,11 @@ import java.util.Map; import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Pattern; +import javax.swing.SwingUtilities; import javax.swing.UIManager; +import org.openide.explorer.ExplorerManager; import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; +import org.openide.nodes.Node; /** * User: suchys @@ -60,7 +63,7 @@ import org.openide.filesystems.FileUtil; */ public class CheckedTreeBeanView extends BeanTreeView { - private FileObject root; + private FileObject[] roots; private Pattern filter; private Map data; final private CheckedNodeRenderer renderer; @@ -98,24 +101,87 @@ public class CheckedTreeBeanView extends tree.setBackground(UIManager.getDefaults().getColor(editable ? "Tree.background" : "TextField.inactiveBackground")); //NOI18N } - public void setSrcRoot(final FileObject root) { - this.root = root; + public void setSrcRoots(final FileObject[] roots) { + this.roots = roots; + } + + Object getState(String path) { + return data.get(path); + } + + void setState(String path, boolean selected) { + System.err.println("set state " + path + " to " + selected); + if (path == null) return; // invalid file object + data.put(path, selected ? SELECTED : UNSELECTED); // set the one + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + do { // clean the path to parent + int ix = path.lastIndexOf('/'); + if (ix > 0) { + path = path.substring(0, ix); + } else { + break; + } + data.remove(path); + System.err.println("path now " + path); + } while (!"".equals(path) && !"/".equals(path)); + updateState(path); +// fo = fo.getParent(); +// while (fo != null && !"".equals(fo.getPath())) { +// data.remove (fo.getPath()); +// } +// while (fo != null && !root.equals(fo)) { // clean the path to parent +// data.remove(FileUtil.getRelativePath(root, fo)); +// fo = fo.getParent(); +// } +// updateState(root); // renew the path from parent + if (properties != null && propertyName != null) properties.put(propertyName, getExcludesRegex()); } private boolean acceptPath(final String path) { return path != null && (path.length()==0 || !this.filter.matcher(path).matches()); } + private synchronized Object updateState(final FileObject fo) { - final String path = FileUtil.getRelativePath(root, fo); + final String path = fo.getPath(); + return updateState (path); + } + + private FileObject rootFo () { + Provider provider = (Provider) SwingUtilities.getAncestorOfClass(ExplorerManager.Provider.class, this); + if (provider != null) { + Node n = provider.getExplorerManager().getRootContext(); + FileObjectCookie ck = n.getCookie(FileObjectCookie.class); + if (ck != null) { + return ck.getFileObject(); + } + } + return null; + } + + private synchronized Object updateState (String path) { + if (!acceptPath(path)) return null; // null means invalid Object state = data.get(path); final boolean forceState = state == SELECTED || state == UNSELECTED; + FileObject fo = rootFo().getFileObject(path); + System.err.println("Root fo is " + rootFo()); + System.err.println("path is " + path); + System.err.println(" child is " + fo); + System.err.println(" is data? " + fo.isData()); + if (fo.isData()) { + if (acceptPath(path)) { + data.put (path, state); + } + return state; + } final Enumeration en = fo.getChildren(forceState); while (en.hasMoreElements()) { final FileObject ch = (FileObject)en.nextElement(); if (forceState) { - final String cp = FileUtil.getRelativePath(root, ch); + final String cp = ch.getPath(); if (acceptPath(cp)) data.put(cp, state); } else { final Object childState = updateState(ch); @@ -131,32 +197,28 @@ public class CheckedTreeBeanView extends } public Object getState(final FileObject fo) { // finds first SELECTED or UNSELECTED from root - final String path = FileUtil.getRelativePath(root, fo); + String path = fo == null ? "" : fo.getPath(); if (!acceptPath(path)) return null; //invalid return data.get(path); } public synchronized void setState(FileObject fo, final boolean selected) { - final String path = FileUtil.getRelativePath(root, fo); - if (path == null) return; // invalid file object - data.put(path, selected ? SELECTED : UNSELECTED); // set the one - fo = fo.getParent(); - while (fo != null && !root.equals(fo)) { // clean the path to parent - data.remove(FileUtil.getRelativePath(root, fo)); - fo = fo.getParent(); - } - updateState(root); // renew the path from parent - if (properties != null && propertyName != null) properties.put(propertyName, getExcludesRegex()); + final String path = fo.getPath(); + setState (path, selected); } public String getExcludesRegex() { - final StringBuffer sb = new StringBuffer(); - addExcludes(root, sb); + final StringBuilder sb = new StringBuilder(); + for (FileObject root : roots) { + addExcludes(root, sb); + } return sb.toString(); } - private void addExcludes(final FileObject fo, final StringBuffer sb) { - final String path = FileUtil.getRelativePath(root, fo); + private void addExcludes(final FileObject fo, final StringBuilder sb) { +// FileObject root = rootOf (fo); +// final String path = FileUtil.getRelativePath(root, fo); + String path = fo.getPath(); if (!acceptPath(path)) return; final Object state = data.get(path); if ((path.length() > 0 && state == null) || state == SELECTED) return; @@ -184,7 +246,10 @@ public class CheckedTreeBeanView extends if (exclude.indexOf('*') < 0) data.put(exclude, UNSELECTED); } } - updateState(root); +// for (FileObject root : roots) { +// updateState(root); +// } + updateState(""); renderer.setContentStorage(this); editor.setContentStorage(this); } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/buildscript/compile --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/buildscript/compile Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/buildscript/compile Wed Nov 26 00:47:25 2008 -0500 @@ -5,11 +5,27 @@ Must set build.classes.dir - - - - + + ${javac.source} + ${javac.target} + ${javac.deprecation} + ${javac.optimize} + ${build.classes.dir} + ${javac.debug} + ${platform.bootclasspath} + ${javac.encoding} + false + + + ${}: + + + + + + + @@ -32,7 +48,12 @@ Must select some files in the IDE or set javac.includes - + + + ${}: + + diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/buildscript/head --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/buildscript/head Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/buildscript/head Wed Nov 26 00:47:25 2008 -0500 @@ -44,6 +44,7 @@ made subject to such option by the copyr xmlns:project="http://www.netbeans.org/ns/project/1" xmlns:xalan="http://xml.apache.org/xslt" xmlns:j2meproject="http://www.netbeans.org/ns/j2me-project" + xmlns:multiroot="http://www.netbeans.org/ns/multiroot-j2me-project" xmlns:projdeps="http://www.netbeans.org/ns/ant-project-references/1" xmlns:projdeps2="http://www.netbeans.org/ns/ant-project-references/2" xmlns:configs="http://www.netbeans.org/ns/project-configurations/1" diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/layer.xml --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/layer.xml Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/resources/layer.xml Wed Nov 26 00:47:25 2008 -0500 @@ -365,6 +365,13 @@ made subject to such option by the copyr + + + + + + + @@ -527,6 +534,7 @@ made subject to such option by the copyr + diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/Bundle.properties --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/Bundle.properties Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/Bundle.properties Wed Nov 26 00:47:25 2008 -0500 @@ -194,3 +194,13 @@ TXT_MobileLibrary=Mobile Class Library #Sample project iterator TXT_SampleProject=Sample Java ME Project +LBL_File_PackageRoot=Package Root\: +MNM_File_PackageRoot=R +MSG_DISAMBIGUATE_MULTI_FOLDERS=The target package exists under multiple \ + source root folders. Choose a source root folder. +MSG_DISAMBIGUATE_NO_FOLDERS=The target package does not exist under any \ + source root folder. Choose a source root folder. +TTL_DISAMBIGUATE=Ambiguous Target Folder + +#LocalizationTargetDisambiguationPanel +TargetDisambiguationDialog.jTextArea1.text=Select a source root diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/MIDPTargetChooserPanel.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/MIDPTargetChooserPanel.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/MIDPTargetChooserPanel.java Wed Nov 26 00:47:25 2008 -0500 @@ -44,18 +44,20 @@ import java.io.File; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.project.Project; +import org.netbeans.modules.mobility.project.ui.wizard.TargetDisambiguationDialog; import org.netbeans.spi.project.ui.templates.support.Templates; import org.openide.WizardDescriptor; -import org.openide.ErrorManager; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.TemplateWizard; +import org.openide.util.Exceptions; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.Utilities; @@ -150,18 +152,33 @@ final class MIDPTargetChooserPanel imple public void storeSettings(final Object settings) { templateWizard = (TemplateWizard) settings; if( isValid() ) { - - final FileObject rootFolder = gui.getRootFolder(); + List folders = new LinkedList(); + FileObject folder = null; final String packageFileName = gui.getPackageFileName(); - FileObject folder = rootFolder.getFileObject(packageFileName); - if (folder == null) { + FileObject[] roots = gui.getRootFolders(); + FileObject createIn = null; + for (FileObject root : roots) { + FileObject test = root.getFileObject (packageFileName); + if (test != null && test.isFolder()) { + if (folders.isEmpty()) { + folder = test; + } + folders.add (test); + } + } + if (folders.size() > 1 || (folder == null && roots.length > 1)) { + while ((createIn = TargetDisambiguationDialog.disambiguate (roots, folders, folder)) == null){} + } + + if (folder == null && createIn != null) { try { - folder = FileUtil.createFolder(rootFolder, packageFileName); + folder = FileUtil.createFolder(createIn, packageFileName); } catch (IOException e) { - ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); + Exceptions.printStackTrace(e); return; } } + Templates.setTargetFolder(templateWizard, folder); Templates.setTargetName(templateWizard, gui.getTargetName()); diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/MIDPTargetChooserPanelGUI.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/MIDPTargetChooserPanelGUI.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/MIDPTargetChooserPanelGUI.java Wed Nov 26 00:47:25 2008 -0500 @@ -45,6 +45,7 @@ import java.awt.event.ActionListener; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; import java.util.List; import javax.swing.*; @@ -59,6 +60,7 @@ import org.netbeans.api.java.project.Jav import org.netbeans.api.java.project.JavaProjectConstants; import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.modules.mobility.project.J2MEProjectUtils; +import org.netbeans.modules.mobility.project.J2MESources; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.netbeans.spi.java.project.support.ui.PackageView; @@ -194,9 +196,13 @@ public class MIDPTargetChooserPanelGUI e cIcon.setSelectedItem("");//NOI18N RequestProcessor.getDefault().post(new Runnable() { public void run() { - final ArrayList roots = new ArrayList(); - roots.add(helper.resolveFileObject(helper.getStandardPropertyEvaluator().getProperty("src.dir"))); //NOI18N - final String libs = J2MEProjectUtils.evaluateProperty(helper, DefaultPropertiesDescriptor.LIBS_CLASSPATH); + final List roots = new ArrayList(); + J2MESources sources = project.getLookup().lookup (J2MESources.class); + if (sources != null) { + roots.addAll (Arrays.asList (sources.getSourceRoots())); + } + final String libs = J2MEProjectUtils.evaluateProperty(helper, + DefaultPropertiesDescriptor.LIBS_CLASSPATH); if (libs != null) { final String elements[] = PropertyUtils.tokenizePath(helper.resolvePath(libs)); for (int i=0; i 0) { + final File rootFile = FileUtil.toFile(roots[0]); //XXX + if (rootFile != null) { + return new File(rootFile, getPackageFileName()); + } + } + return null; } public String getPackageFileName() { diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/TargetDisambiguationDialog.form --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/TargetDisambiguationDialog.form Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,109 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/TargetDisambiguationDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/TargetDisambiguationDialog.java Wed Nov 26 00:47:25 2008 -0500 @@ -0,0 +1,214 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 2008 Sun Microsystems, Inc. + */ +package org.netbeans.modules.mobility.project.ui.wizard; + +import java.util.List; +import javax.swing.DefaultListModel; +import javax.swing.ListSelectionModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import org.openide.DialogDescriptor; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectNotFoundException; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; + +/** + * Shows a dialog that asks the user which root folder a new file should be + * put in, if either the requested package does not exist in any root, + * or it exists in multiple roots. + * + * @author Tim Boudreau + */ +public class TargetDisambiguationDialog extends javax.swing.JPanel implements ListSelectionListener { + private ChangeListener listener; + + private TargetDisambiguationDialog(FileObject[] rootFolders, List candidates, FileObject defaultChoice) { + initComponents(); + String msg; + assert candidates.size() == 0 || candidates.size() > 1 : "If only one" + + " folder is found, disambiguation is not needed"; + if (candidates.isEmpty()) { + msg = NbBundle.getMessage(TargetDisambiguationDialog.class, + "MSG_DISAMBIGUATE_NO_FOLDERS"); //NOI18N + } else { + msg = NbBundle.getMessage(TargetDisambiguationDialog.class, + "MSG_DISAMBIGUATE_MULTI_FOLDERS"); //NOI18N + } + jTextArea1.setText (msg); + DefaultListModel mdl = new DefaultListModel (); + Item sel = null; + for (int i = 0; i < rootFolders.length; i++) { + Item item = new Item (rootFolders[i]); + mdl.addElement(item); + if (defaultChoice != null && defaultChoice.equals(rootFolders[i])) { + sel = item; + } + } + jList1.setModel (mdl); + jList1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + if (sel != null) { + jList1.setSelectedValue(sel, true); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + jTextArea1 = new javax.swing.JTextArea(); + jScrollPane2 = new javax.swing.JScrollPane(); + jList1 = new javax.swing.JList(); + + jScrollPane1.setBackground(javax.swing.UIManager.getDefaults().getColor("control")); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jScrollPane1.setViewportBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + + jTextArea1.setBackground(javax.swing.UIManager.getDefaults().getColor("control")); + jTextArea1.setColumns(20); + jTextArea1.setLineWrap(true); + jTextArea1.setRows(5); + jTextArea1.setText(org.openide.util.NbBundle.getBundle(TargetDisambiguationDialog.class).getString("TargetDisambiguationDialog.jTextArea1.text")); // NOI18N + jTextArea1.setWrapStyleWord(true); + jTextArea1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jTextArea1.setOpaque(false); + jScrollPane1.setViewportView(jTextArea1); + + jList1.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + jScrollPane2.setViewportView(jList1); + + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE) + .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 137, Short.MAX_VALUE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JList jList1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JTextArea jTextArea1; + // End of variables declaration//GEN-END:variables + + public void valueChanged(ListSelectionEvent e) { + listener.stateChanged(new ChangeEvent(this)); + } + + void setListener (ChangeListener cl) { + this.listener = cl; + } + + FileObject getFolder() { + Item item = (Item) jList1.getSelectedValue(); + return item == null ? null : item.folder; + } + + boolean isOk() { + return getFolder() != null; + } + + private static final class Item { + private final FileObject folder; + private Item (FileObject folder) { + this.folder = folder; + } + + @Override + public String toString() { + try { + return DataObject.find(folder).getNodeDelegate().getDisplayName(); + } catch (DataObjectNotFoundException ex) { + Exceptions.printStackTrace(ex); + return super.toString(); + } + } + } + + public static FileObject disambiguate(FileObject[] rootFolders, List candidates, FileObject defaultChoice) { + final TargetDisambiguationDialog panel = new TargetDisambiguationDialog(rootFolders, + candidates, defaultChoice); + + final DialogDescriptor dlg = new DialogDescriptor (panel, + NbBundle.getMessage(TargetDisambiguationDialog.class, + "TTL_DISAMBIGUATE"), true, null); //NOI18N + dlg.setValid(defaultChoice != null); + ChangeListener cl = new ChangeListener() { + public void stateChanged(ChangeEvent e) { + dlg.setValid(panel.isOk()); + } + }; + panel.setListener(cl); + if (DialogDisplayer.getDefault().notify(dlg).equals(NotifyDescriptor.OK_OPTION)) { + return panel.getFolder(); + } + return null; + } +} diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/Bundle.properties --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/Bundle.properties Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/Bundle.properties Wed Nov 26 00:47:25 2008 -0500 @@ -93,5 +93,3 @@ LBL_DefaultPackage= #System file system Templates/MIDP/LocalizationSupport.java=Localization Support Class -LBL_File_PackageRoot=Package Root\: -MNM_File_PackageRoot=R diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/LocalizationSupportPanel.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/LocalizationSupportPanel.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/LocalizationSupportPanel.java Wed Nov 26 00:47:25 2008 -0500 @@ -40,6 +40,7 @@ */ package org.netbeans.modules.mobility.project.ui.wizard.i18n; +import org.netbeans.modules.mobility.project.ui.wizard.TargetDisambiguationDialog; import java.awt.Component; import java.io.File; import java.util.ArrayList; @@ -57,8 +58,9 @@ import org.openide.util.NbBundle; import org.openide.util.NbBundle; import org.openide.util.Utilities; import java.util.StringTokenizer; -import org.openide.ErrorManager; import java.io.IOException; +import java.util.LinkedList; +import org.openide.util.Exceptions; /** * @@ -135,20 +137,32 @@ public final class LocalizationSupportPa fullResourceName.append(messageFilename); return fullResourceName.toString(); } - - - + public void storeSettings(final Object settings) { if( isValid() ) { - - final FileObject rootFolder = gui.getRootFolder(); + List folders = new LinkedList(); + FileObject folder = null; final String packageFileName = gui.getPackageFileName(); - FileObject folder = rootFolder.getFileObject(packageFileName); - if (folder == null) { + FileObject[] roots = gui.getRootFolders(); + FileObject createIn = null; + for (FileObject root : roots) { + FileObject test = root.getFileObject (packageFileName); + if (test != null && test.isFolder()) { + if (folders.isEmpty()) { + folder = test; + } + folders.add (test); + } + } + if (folders.size() > 1 || (folder == null && roots.length > 1)) { + while ((createIn = TargetDisambiguationDialog.disambiguate (roots, folders, folder)) == null){} + } + + if (folder == null && createIn != null) { try { - folder = FileUtil.createFolder(rootFolder, packageFileName); + folder = FileUtil.createFolder(createIn, packageFileName); } catch (IOException e) { - ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); + Exceptions.printStackTrace(e); return; } } diff -r 6b487c15857b mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/LocalizationSupportPanelGUI.java --- a/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/LocalizationSupportPanelGUI.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/modules/mobility/project/ui/wizard/i18n/LocalizationSupportPanelGUI.java Wed Nov 26 00:47:25 2008 -0500 @@ -67,10 +67,12 @@ import java.awt.Dimension; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.LinkedList; import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.netbeans.api.java.project.JavaProjectConstants; import javax.swing.text.Document; +import org.netbeans.modules.mobility.project.J2MESources; import org.netbeans.spi.java.project.support.ui.PackageView; import org.openide.util.NbBundle; @@ -247,16 +249,25 @@ public class LocalizationSupportPanelGUI return null; } - public FileObject getRootFolder() { - return helper.resolveFileObject(helper.getStandardPropertyEvaluator().getProperty("src.dir")); // NOI18N + public FileObject[] getRootFolders() { + J2MESources sources = project.getLookup().lookup(J2MESources.class); + return sources == null ? new FileObject[0] : sources.getSourceRoots(); } public File getFolder() { - final FileObject root = getRootFolder(); - final File rootFile = FileUtil.toFile(root); - if (rootFile == null) - return null; - return new File(rootFile, getPackageFileName()); + J2MESources sources = project.getLookup().lookup(J2MESources.class); + FileObject result = null; + if (sources != null) { + //Find any source root that contains the package. We'll ask the + //user to disambiguate if there are multiple ones later. + for (FileObject root : sources.getSourceRoots()) { + result = root.getFileObject(getPackageFileName()); + if (result != null) { + break; + } + } + } + return result == null ? FileUtil.toFile(result) : null; } diff -r 6b487c15857b mobility.project/src/org/netbeans/spi/mobility/project/ui/customizer/CustomizerPanel.java --- a/mobility.project/src/org/netbeans/spi/mobility/project/ui/customizer/CustomizerPanel.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/src/org/netbeans/spi/mobility/project/ui/customizer/CustomizerPanel.java Wed Nov 26 00:47:25 2008 -0500 @@ -41,7 +41,7 @@ package org.netbeans.spi.mobility.project.ui.customizer; -import org.netbeans.api.mobility.project.ui.customizer.ProjectProperties; +import org.netbeans.api.mobility.project.ui.customizer.MultiRootProjectProperties; /** * @@ -49,6 +49,6 @@ import org.netbeans.api.mobility.project */ public interface CustomizerPanel { - public void initValues(ProjectProperties props, String configuration); + public void initValues(MultiRootProjectProperties props, String configuration); } \ No newline at end of file diff -r 6b487c15857b mobility.project/test/unit/src/org/netbeans/modules/mobility/project/J2MEActionProviderTest.java --- a/mobility.project/test/unit/src/org/netbeans/modules/mobility/project/J2MEActionProviderTest.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/test/unit/src/org/netbeans/modules/mobility/project/J2MEActionProviderTest.java Wed Nov 26 00:47:25 2008 -0500 @@ -311,7 +311,7 @@ public class J2MEActionProviderTest exte TestUtil.setHelper(hp); /* try to add another root for better code coverage */ EditableProperties ep=hp.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); - ep.setProperty("src.dir",System.getProperty("java.io.tmpdir")); + ep.setProperty(DefaultPropertiesDescriptor.SRC_DIR,System.getProperty("java.io.tmpdir")); hp.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,ep); new J2MEProject(hp); } catch (Exception e) { diff -r 6b487c15857b mobility.project/test/unit/src/org/netbeans/modules/mobility/project/queries/CompiledSourceForBinaryQueryTest.java --- a/mobility.project/test/unit/src/org/netbeans/modules/mobility/project/queries/CompiledSourceForBinaryQueryTest.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/test/unit/src/org/netbeans/modules/mobility/project/queries/CompiledSourceForBinaryQueryTest.java Wed Nov 26 00:47:25 2008 -0500 @@ -156,7 +156,7 @@ public class CompiledSourceForBinaryQuer result.addChangeListener(list); result.removeChangeListener(null); EditableProperties ep=aph.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); - ep.setProperty("src.dir","../src2"); + ep.setProperty(DefaultPropertiesDescriptor.SRC_DIR,"../src2"); aph.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,ep); //result.removeChangeListener(list); } diff -r 6b487c15857b mobility.project/test/unit/src/org/netbeans/modules/mobility/project/queries/FileBuiltQueryImplTest.java --- a/mobility.project/test/unit/src/org/netbeans/modules/mobility/project/queries/FileBuiltQueryImplTest.java Tue Nov 25 18:06:33 2008 -0500 +++ b/mobility.project/test/unit/src/org/netbeans/modules/mobility/project/queries/FileBuiltQueryImplTest.java Wed Nov 26 00:47:25 2008 -0500 @@ -63,6 +63,7 @@ import org.netbeans.junit.NbTestCase; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.java.platform.JavaPlatformProvider; import org.netbeans.modules.mobility.cldcplatform.J2MEPlatform; +import org.netbeans.modules.mobility.project.DefaultPropertiesDescriptor; import org.netbeans.modules.mobility.project.J2MEActionProvider; import org.netbeans.modules.mobility.project.J2MEProject; import org.netbeans.modules.mobility.project.J2MEProjectGenerator; @@ -266,7 +267,7 @@ public class FileBuiltQueryImplTest exte assertNull(ret,ret); EditableProperties ep=aph.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); - ep.setProperty("src.dir","src2"); + ep.setProperty(DefaultPropertiesDescriptor.SRC_DIR,"src2"); aph.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,ep);