001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: /*
043: * ImportCDCProjectPanel.java
044: *
045: * Created on April 8, 2004, 1:39 PM
046: */
047: package org.netbeans.modules.j2me.cdc.project.ui.wizards;
048:
049: import java.io.File;
050: import java.util.ArrayList;
051: import java.util.Collection;
052: import java.util.HashMap;
053: import java.util.Map;
054: import javax.swing.Icon;
055: import javax.swing.ImageIcon;
056: import javax.swing.JFileChooser;
057: import javax.swing.event.ChangeEvent;
058: import javax.swing.event.ChangeListener;
059: import javax.swing.event.DocumentListener;
060: import javax.swing.event.DocumentEvent;
061: import javax.swing.filechooser.FileFilter;
062: import javax.swing.filechooser.FileSystemView;
063: import javax.swing.filechooser.FileView;
064: import org.netbeans.api.project.ProjectManager;
065: import org.netbeans.modules.mobility.project.ui.wizard.PlatformSelectionPanel;
066: import org.netbeans.modules.mobility.project.ui.wizard.ProjectPanel;
067: import org.netbeans.spi.project.ui.support.ProjectChooser;
068: import org.netbeans.spi.project.ui.templates.support.Templates;
069: import org.openide.filesystems.FileObject;
070: import org.openide.filesystems.FileUtil;
071: import org.openide.loaders.TemplateWizard;
072: import org.openide.util.HelpCtx;
073: import org.openide.util.NbBundle;
074: import org.openide.util.Utilities;
075: import org.openide.windows.WindowManager;
076: import org.openide.xml.XMLUtil;
077: import org.w3c.dom.Document;
078: import org.w3c.dom.NodeList;
079: import org.xml.sax.InputSource;
080:
081: /**
082: *
083: * @author Lukas Waldmann
084: */
085: public class ImportCDCProjectPanel extends javax.swing.JPanel implements
086: DocumentListener {
087:
088: private static final java.awt.Dimension PREF_DIM = new java.awt.Dimension(
089: 500, 340);
090: static final String PROJECT_LOCATION = "ImportProjectLocation"; // NOI18N
091: private static String prjType;
092: private static String location;
093:
094: /**
095: * Creates new form ImportCDCProjectPanel
096: */
097: private ImportCDCProjectPanel(String type) {
098: prjType = type;
099: initComponents();
100: initAccessibility();
101: }
102:
103: public synchronized void addListener(final DocumentListener listener) {
104: tLocation.getDocument().addDocumentListener(listener);
105: }
106:
107: public synchronized void removeListener(
108: final DocumentListener listener) {
109: tLocation.getDocument().removeDocumentListener(listener);
110: }
111:
112: public synchronized void readData(final TemplateWizard object) {
113: Object tmp;
114: tmp = object.getProperty(PROJECT_LOCATION);
115: if (tmp != null) {
116: tLocation.setText((String) tmp);
117: } else {
118: final FileObject fo = Templates
119: .getExistingSourcesFolder(object);
120: final File f = fo == null ? null : FileUtil.toFile(fo);
121: tLocation.setText(f == null ? "" : f.getAbsolutePath()); // NOI18N
122: }
123: }
124:
125: public synchronized void storeData(final TemplateWizard object) {
126: final String location = tLocation.getText();
127: object.putProperty(PROJECT_LOCATION, location);
128: final String name = new File(location).getName();
129: object.putProperty(ProjectPanel.PROJECT_NAME,
130: "Imported Project"
131: + (name != null ? " - " + name + '1' : "1")); // NOI18N
132:
133: String detectedConfiguration = null;
134: String detectedProfile = null;
135: final Map<String, String> map = new HashMap<String, String>();
136: detectedConfiguration = map.get("MicroEdition-Configuration"); // NOI18N
137: detectedProfile = map.get("MicroEdition-Profile"); // NOI18N
138:
139: object.putProperty(
140: PlatformSelectionPanel.REQUIRED_CONFIGURATION,
141: detectedConfiguration);
142: object.putProperty(PlatformSelectionPanel.REQUIRED_PROFILE,
143: detectedProfile);
144: }
145:
146: public String getLocationText() {
147: return tLocation.getText();
148: }
149:
150: /** This method is called from within the constructor to
151: * initialize the form.
152: * WARNING: Do NOT modify this code. The content of this method is
153: * always regenerated by the Form Editor.
154: */
155: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
156: private void initComponents() {
157: java.awt.GridBagConstraints gridBagConstraints;
158:
159: jLabel1 = new javax.swing.JLabel();
160: jLabel2 = new javax.swing.JLabel();
161: tLocation = new javax.swing.JTextField();
162: bBrowse = new javax.swing.JButton();
163: jPanel2 = new javax.swing.JPanel();
164:
165: setName(org.openide.util.NbBundle
166: .getMessage(
167: ImportCDCProjectPanel.class,
168: "TITLE_Project",
169: prjType
170: .equals(ImportCDCProjectWizardIterator.CDC55) ? ImportCDCProjectWizardIterator.CDC55TYPE
171: : ImportCDCProjectWizardIterator.CDCTOOLKITTYPE)); // NOI18N
172: setLayout(new java.awt.GridBagLayout());
173:
174: org.openide.awt.Mnemonics
175: .setLocalizedText(
176: jLabel1,
177: org.openide.util.NbBundle
178: .getMessage(
179: ImportCDCProjectPanel.class,
180: "LBL_Import_Info",
181: prjType
182: .equals(ImportCDCProjectWizardIterator.CDC55) ? ImportCDCProjectWizardIterator.CDC55TYPE
183: : ImportCDCProjectWizardIterator.CDCTOOLKITTYPE)); // NOI18N
184: jLabel1.setVerticalAlignment(javax.swing.SwingConstants.TOP);
185: jLabel1.setPreferredSize(new java.awt.Dimension(400, 54));
186: gridBagConstraints = new java.awt.GridBagConstraints();
187: gridBagConstraints.gridwidth = 3;
188: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
189: gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
190: add(jLabel1, gridBagConstraints);
191: jLabel1
192: .getAccessibleContext()
193: .setAccessibleName(
194: org.openide.util.NbBundle
195: .getMessage(
196: ImportCDCProjectPanel.class,
197: "ASCD_Import_Info",
198: prjType
199: .equals(ImportCDCProjectWizardIterator.CDC55) ? ImportCDCProjectWizardIterator.CDC55TYPE
200: : ImportCDCProjectWizardIterator.CDCTOOLKITTYPE)); // NOI18N
201:
202: jLabel2.setLabelFor(tLocation);
203: org.openide.awt.Mnemonics.setLocalizedText(jLabel2,
204: org.openide.util.NbBundle.getMessage(
205: ImportCDCProjectPanel.class,
206: "LBL_Project_Location")); // NOI18N
207: gridBagConstraints = new java.awt.GridBagConstraints();
208: gridBagConstraints.gridx = 0;
209: gridBagConstraints.gridy = 1;
210: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
211: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
212: gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 6);
213: add(jLabel2, gridBagConstraints);
214: gridBagConstraints = new java.awt.GridBagConstraints();
215: gridBagConstraints.gridx = 1;
216: gridBagConstraints.gridy = 1;
217: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
218: gridBagConstraints.weightx = 1.0;
219: gridBagConstraints.insets = new java.awt.Insets(5, 6, 5, 6);
220: add(tLocation, gridBagConstraints);
221: tLocation
222: .getAccessibleContext()
223: .setAccessibleDescription(
224: NbBundle
225: .getMessage(
226: ImportCDCProjectPanel.class,
227: "ACSD_Project_Location",
228: prjType
229: .equals(ImportCDCProjectWizardIterator.CDC55) ? ImportCDCProjectWizardIterator.CDC55TYPE
230: : ImportCDCProjectWizardIterator.CDCTOOLKITTYPE)); // NOI18N
231:
232: org.openide.awt.Mnemonics.setLocalizedText(bBrowse,
233: org.openide.util.NbBundle.getMessage(
234: ImportCDCProjectPanel.class,
235: "LBL_Project_Browse")); // NOI18N
236: bBrowse.addActionListener(new java.awt.event.ActionListener() {
237: public void actionPerformed(java.awt.event.ActionEvent evt) {
238: bBrowseActionPerformed(evt);
239: }
240: });
241: gridBagConstraints = new java.awt.GridBagConstraints();
242: gridBagConstraints.gridx = 2;
243: gridBagConstraints.gridy = 1;
244: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
245: gridBagConstraints.insets = new java.awt.Insets(5, 6, 5, 0);
246: add(bBrowse, gridBagConstraints);
247: bBrowse.getAccessibleContext().setAccessibleDescription(
248: NbBundle.getMessage(ImportCDCProjectPanel.class,
249: "ACSD_Project_Browse1")); // NOI18N
250:
251: gridBagConstraints = new java.awt.GridBagConstraints();
252: gridBagConstraints.gridx = 0;
253: gridBagConstraints.gridy = 3;
254: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
255: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
256: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
257: gridBagConstraints.weightx = 1.0;
258: gridBagConstraints.weighty = 1.0;
259: gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
260: add(jPanel2, gridBagConstraints);
261: }// </editor-fold>//GEN-END:initComponents
262:
263: private void initAccessibility() {
264: getAccessibleContext()
265: .setAccessibleName(
266: NbBundle
267: .getMessage(
268: ImportCDCProjectPanel.class,
269: "ACSN_Project",
270: prjType
271: .equals(ImportCDCProjectWizardIterator.CDC55) ? ImportCDCProjectWizardIterator.CDC55TYPE
272: : ImportCDCProjectWizardIterator.CDCTOOLKITTYPE));
273: getAccessibleContext()
274: .setAccessibleDescription(
275: NbBundle
276: .getMessage(
277: ImportCDCProjectPanel.class,
278: "ACSD_Project",
279: prjType
280: .equals(ImportCDCProjectWizardIterator.CDC55) ? ImportCDCProjectWizardIterator.CDC55TYPE
281: : ImportCDCProjectWizardIterator.CDCTOOLKITTYPE));
282: }
283:
284: public java.awt.Dimension getPreferredSize() {
285: return PREF_DIM;
286: }
287:
288: private void bBrowseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bBrowseActionPerformed
289: if (location == null)
290: location = tLocation.getText();
291: if (location == null || "".equals(location)) // NOI18N
292: location = System.getProperty("user.home", ""); // NOI18N
293: File origLoc = ProjectChooser.getProjectsFolder();
294: ProjectChooser.setProjectsFolder(new File(location));
295: JFileChooser ch = createProjectChooser();
296: if (JFileChooser.APPROVE_OPTION == ch
297: .showOpenDialog(WindowManager.getDefault()
298: .getMainWindow())) {
299: String folder = ch.getSelectedFile().getAbsolutePath();
300: if (folder != null) {
301: tLocation.setText(folder);
302: location = new File(folder).getParent();
303: }
304: }
305: ProjectChooser.setProjectsFolder(origLoc);
306: }//GEN-LAST:event_bBrowseActionPerformed
307:
308: public void insertUpdate(DocumentEvent e) {
309: }
310:
311: public void removeUpdate(DocumentEvent e) {
312: }
313:
314: public void changedUpdate(DocumentEvent e) {
315: }
316:
317: // Variables declaration - do not modify//GEN-BEGIN:variables
318: private javax.swing.JButton bBrowse;
319: private javax.swing.JLabel jLabel1;
320: private javax.swing.JLabel jLabel2;
321: private javax.swing.JPanel jPanel2;
322: private javax.swing.JTextField tLocation;
323:
324: // End of variables declaration//GEN-END:variables
325:
326: static class WizardPanel implements TemplateWizard.FinishablePanel,
327: DocumentListener {
328:
329: ImportCDCProjectPanel component;
330: TemplateWizard wizard;
331: Collection<ChangeListener> listeners = new ArrayList<ChangeListener>();
332: boolean valid = false;
333: final String prjType;
334:
335: public WizardPanel(String type) {
336: prjType = type;
337: }
338:
339: public void addChangeListener(
340: final ChangeListener changeListener) {
341: listeners.add(changeListener);
342: }
343:
344: public void removeChangeListener(
345: final ChangeListener changeListener) {
346: listeners.remove(changeListener);
347: }
348:
349: public java.awt.Component getComponent() {
350: if (component == null) {
351: // !!! use unified workdir
352: component = new ImportCDCProjectPanel(prjType);
353: component.addListener(this );
354: checkValid();
355: }
356: return component;
357: }
358:
359: public org.openide.util.HelpCtx getHelp() {
360: return new HelpCtx(ImportCDCProjectPanel.class);
361: }
362:
363: public boolean isFinishPanel() {
364: return false;
365: }
366:
367: public void showError(final String message) {
368: if (wizard != null)
369: wizard.putProperty("WizardPanel_errorMessage", message); // NOI18N
370: }
371:
372: public boolean isValid() {
373: boolean valid;
374: File f;
375:
376: f = FileUtil.normalizeFile(new File(component
377: .getLocationText()).getAbsoluteFile());
378: valid = component.getLocationText().length() > 0
379: && f != null && f.exists() && f.isDirectory();
380: if (!valid) {
381: showError(NbBundle.getMessage(
382: ImportCDCProjectPanel.class,
383: "ERR_Project_InvalidLocation")); // NOI18N
384: return false;
385: }
386: showError(null);
387: return true;
388: }
389:
390: public void readSettings(final Object obj) {
391: wizard = (TemplateWizard) obj;
392: ((ImportCDCProjectPanel) getComponent()).readData(wizard);
393: }
394:
395: public void storeSettings(final Object obj) {
396: wizard = (TemplateWizard) obj;
397: ((ImportCDCProjectPanel) getComponent()).storeData(wizard);
398: }
399:
400: void fireStateChange() {
401: ChangeListener[] ll;
402: synchronized (this ) {
403: if (listeners.isEmpty())
404: return;
405: ll = listeners.toArray(new ChangeListener[listeners
406: .size()]);
407: }
408: final ChangeEvent ev = new ChangeEvent(this );
409: for (int i = 0; i < ll.length; i++)
410: ll[i].stateChanged(ev);
411: }
412:
413: void checkValid() {
414: if (isValid() != valid) {
415: valid ^= true;
416: fireStateChange();
417: }
418: }
419:
420: public void changedUpdate(
421: final javax.swing.event.DocumentEvent e) {
422: checkValid();
423: }
424:
425: public void insertUpdate(final javax.swing.event.DocumentEvent e) {
426: checkValid();
427: }
428:
429: public void removeUpdate(final javax.swing.event.DocumentEvent e) {
430: checkValid();
431: }
432:
433: }
434:
435: private static boolean isOldProject(FileObject fo, String type) {
436: FileObject xml = fo.getFileObject("nbproject/project.xml");
437: FileObject prop = fo
438: .getFileObject("nbproject/project.properties");
439: if (xml != null && prop != null) {
440: File file = FileUtil.toFile(xml);
441: try {
442: Document doc = XMLUtil.parse(new InputSource(file
443: .toURI().toString()), false, true, null, null);
444: NodeList nl = doc.getElementsByTagNameNS(
445: "http://www.netbeans.org/ns/project/1", "type");
446: return nl.item(0).getTextContent().equals(type);
447: } catch (Exception ex) {
448: }
449: ;
450: }
451: return false;
452: }
453:
454: private static class ProjectFileView extends FileView {
455:
456: final private FileSystemView fsv;
457: private static final Icon BADGE = new ImageIcon(
458: Utilities
459: .loadImage("org/netbeans/modules/project/ui/resources/projectBadge.gif")); // NOI18N
460: private static final Icon EMPTY = new ImageIcon(
461: Utilities
462: .loadImage("org/netbeans/modules/project/ui/resources/empty.gif")); // NOI18N
463: private Icon lastOriginal;
464: private Icon lastMerged;
465:
466: public ProjectFileView(FileSystemView fs) {
467: this .fsv = fs;
468: }
469:
470: public Icon getIcon(File _f) {
471: //return original.getIcon(f);
472:
473: if (!_f.exists()) {
474: // Can happen when a file was deleted on disk while project
475: // dialog was still open. In that case, throws an exception
476: // repeatedly from FSV.gSI during repaint.
477: return null;
478: }
479: File f = FileUtil.normalizeFile(_f);
480: Icon or = fsv.getSystemIcon(f);
481: if (or == null) {
482: // L&F (e.g. GTK) did not specify any icon.
483: or = EMPTY;
484: }
485: FileObject fo = FileUtil.toFileObject(f);
486:
487: if (fo != null
488: && ImportCDCProjectPanel.isOldProject(fo,
489: ImportCDCProjectPanel.prjType)) {
490:
491: if (or.equals(lastOriginal)) {
492: return lastMerged;
493: }
494: lastOriginal = or;
495: lastMerged = new MergedIcon(or, BADGE, -1, -1);
496: return lastMerged;
497: } else {
498: return or;
499: }
500: }
501: }
502:
503: private static class MergedIcon implements Icon {
504:
505: private Icon icon1;
506: private Icon icon2;
507: private int xMerge;
508: private int yMerge;
509:
510: MergedIcon(Icon icon1, Icon icon2, int xMerge, int yMerge) {
511:
512: this .icon1 = icon1;
513: this .icon2 = icon2;
514:
515: if (xMerge == -1) {
516: xMerge = icon1.getIconWidth() - icon2.getIconWidth();
517: }
518:
519: if (yMerge == -1) {
520: yMerge = icon1.getIconHeight() - icon2.getIconHeight();
521: }
522:
523: this .xMerge = xMerge;
524: this .yMerge = yMerge;
525: }
526:
527: public int getIconHeight() {
528: return Math.max(icon1.getIconHeight(), yMerge
529: + icon2.getIconHeight());
530: }
531:
532: public int getIconWidth() {
533: return Math.max(icon1.getIconWidth(), yMerge
534: + icon2.getIconWidth());
535: }
536:
537: public void paintIcon(java.awt.Component c,
538: java.awt.Graphics g, int x, int y) {
539: icon1.paintIcon(c, g, x, y);
540: icon2.paintIcon(c, g, x + xMerge, y + yMerge);
541: }
542: }
543:
544: /** Factory method for project chooser
545: */
546: public static JFileChooser createProjectChooser() {
547:
548: ProjectManager.getDefault().clearNonProjectCache(); // #41882
549:
550: JFileChooser chooser = new ProjectFileChooser();
551: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
552:
553: if ("GTK"
554: .equals(javax.swing.UIManager.getLookAndFeel().getID())) { // NOI18N
555: // see BugTraq #5027268
556: chooser.putClientProperty(
557: "GTKFileChooser.showDirectoryIcons", Boolean.TRUE); // NOI18N
558: //chooser.putClientProperty("GTKFileChooser.showFileIcons", Boolean.TRUE); // NOI18N
559: }
560:
561: //#61789 on old macosx (jdk 1.4.1) these two method need to be called in this order.
562: chooser.setAcceptAllFileFilterUsed(false);
563: chooser.setFileFilter(ProjectDirFilter.INSTANCE);
564:
565: File currDir = ProjectChooser.getProjectsFolder();
566: FileUtil.preventFileChooserSymlinkTraversal(chooser, currDir);
567: chooser.setFileView(new ProjectFileView(chooser
568: .getFileSystemView()));
569:
570: return chooser;
571: }
572:
573: private static class ProjectFileChooser extends JFileChooser {
574:
575: public void approveSelection() {
576: File dir = FileUtil.normalizeFile(getSelectedFile());
577: if (dir != null
578: && ImportCDCProjectPanel.isOldProject(FileUtil
579: .toFileObject(dir),
580: ImportCDCProjectPanel.prjType)) {
581: super .approveSelection();
582: } else {
583: setCurrentDirectory(dir);
584: }
585: }
586: }
587:
588: private static class ProjectDirFilter extends FileFilter {
589:
590: private static final FileFilter INSTANCE = new ProjectDirFilter();
591:
592: public boolean accept(File f) {
593:
594: if (f.isDirectory()) {
595: return true; // Directory selected
596: }
597:
598: return false;
599: }
600:
601: public String getDescription() {
602: return "";
603: }
604:
605: }
606:
607: }
|