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-2007 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: package org.netbeans.modules.apisupport.project.ui.wizard;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.Enumeration;
047: import java.util.StringTokenizer;
048: import java.util.jar.JarEntry;
049: import java.util.jar.JarFile;
050: import javax.swing.JFileChooser;
051: import javax.swing.event.DocumentEvent;
052: import javax.swing.event.DocumentListener;
053: import javax.swing.filechooser.FileFilter;
054: import org.netbeans.modules.apisupport.project.Util;
055: import org.netbeans.modules.apisupport.project.ui.ModuleUISettings;
056: import org.netbeans.modules.apisupport.project.ui.UIUtil;
057: import org.openide.ErrorManager;
058: import org.openide.util.NbBundle;
059:
060: /**
061: * First panel of the librarywrapper module wizard.
062: *
063: * @author Milos Kleint
064: */
065: final class LibraryStartVisualPanel extends
066: BasicVisualPanel.NewTemplatePanel {
067:
068: static final String PROP_LIBRARY_PATH = "LIBRARY_PATH_VALUE"; //NOI18N
069: static final String PROP_LICENSE_PATH = "LICENSE_PATH_VALUE"; //NOI18N
070:
071: private boolean listenersAttached;
072: private final DocumentListener libraryDL;
073: private final DocumentListener licenseDL;
074:
075: /** Creates new form BasicConfVisualPanel */
076: public LibraryStartVisualPanel(final NewModuleProjectData data) {
077: super (data);
078: initComponents();
079: initAccessibility();
080: libraryDL = new UIUtil.DocumentAdapter() {
081: public void insertUpdate(DocumentEvent e) {
082: checkLibraryAndLicense();
083: }
084: };
085: licenseDL = new UIUtil.DocumentAdapter() {
086: public void insertUpdate(DocumentEvent e) {
087: checkLibraryAndLicense();
088: }
089: };
090: }
091:
092: private void initAccessibility() {
093: this .getAccessibleContext().setAccessibleDescription(
094: getMessage("ACS_LibraryStartVisualPanel"));
095: browseLibraryButton.getAccessibleContext()
096: .setAccessibleDescription(
097: getMessage("ACS_CTL_BrowseLibraries"));
098: browseLicenceButton.getAccessibleContext()
099: .setAccessibleDescription(
100: getMessage("ACS_CTL_BrowseLicense"));
101: txtLibrary.getAccessibleContext().setAccessibleDescription(
102: getMessage("ACS_CTL_Library"));
103: txtLicense.getAccessibleContext().setAccessibleDescription(
104: getMessage("ACS_CTL_License"));
105: }
106:
107: private void checkLibraryAndLicense() {
108: String text = txtLibrary.getText().trim();
109: if (text.length() > 0) {
110: StringTokenizer tokens = new StringTokenizer(text,
111: File.pathSeparator);
112: while (tokens.hasMoreTokens()) {
113: String one = tokens.nextToken();
114: File fil = new File(one);
115: if (!fil.exists()) {
116: setError(getMessage("MSG_Invalid_Library_Path"));
117: return;
118: }
119: try {
120: new JarFile(fil); // just checking whether the jar is valid
121: } catch (IOException exc) {
122: setError(getMessage("MSG_Invalid_Library_Path"));
123: return;
124: }
125: String badOnes = populateProjectData(getData(), text,
126: false);
127: if (badOnes != null) {
128: setWarning(NbBundle.getMessage(
129: LibraryStartVisualPanel.class,
130: "MSG_ClassInDefaultPackage", badOnes));
131: return;
132: }
133: }
134: } else {
135: setError(getMessage("MSG_Library_Path_Not_Defined"));
136: return;
137: }
138: text = txtLicense.getText().trim();
139: if (text.length() > 0) {
140: File fil = new File(text);
141: if (!fil.exists()) {
142: setError(getMessage("MSG_Invalid_License_Path"));
143: return;
144: }
145: }
146: markValid();
147: }
148:
149: void refreshData() {
150: // XXX should be cleaned out if it is not needed
151: // String license = (String)getSettings().getProperty(PROP_LICENSE_PATH);
152: // String jars = (String)getSettings().getProperty(PROP_LIBRARY_PATH);
153:
154: // String cnb = data.getCodeNameBase();
155: // codeNameBaseValue.setText(cnb);
156: // if (cnb.startsWith(EXAMPLE_BASE_NAME)) {
157: // codeNameBaseValue.select(0, EXAMPLE_BASE_NAME.length() - 1);
158: // }
159: // String dn = data.getProjectDisplayName();
160: // displayNameValue.setText(dn);
161: // checkCodeNameBase();
162: }
163:
164: /** Stores collected data into model. */
165: void storeData() {
166: String jars = txtLibrary.getText().trim();
167: getSettings().putProperty(PROP_LIBRARY_PATH, jars);
168: getSettings().putProperty(PROP_LICENSE_PATH,
169: txtLicense.getText().trim());
170: populateProjectData(getData(), jars, true);
171: // // change will be fired -> update data
172: // data.setCodeNameBase(getCodeNameBaseValue());
173: // data.setProjectDisplayName(displayNameValue.getText());
174: // data.setBundle(getBundleValue());
175: // if (!libraryModule) {
176: // data.setLayer(getLayerValue());
177: // }
178: }
179:
180: static String populateProjectData(NewModuleProjectData data,
181: String paths, boolean assignValues) {
182: if (data.getProjectName() != null
183: && data.getCodeNameBase() != null && assignValues) {
184: return null;
185: }
186: String wrongOnes = null;
187: StringTokenizer tokens = new StringTokenizer(paths,
188: File.pathSeparator);
189: boolean cutShortestPath = false;
190: boolean fileAlreadyMarked = false;
191: if (tokens.hasMoreTokens()) {
192: fileAlreadyMarked = false;
193: File fil = new File(tokens.nextToken());
194: if (!fil.exists()) {
195: // #63438 hmm. happens when cancelling the panel? why?
196: return wrongOnes;
197: }
198: String name = fil.getName();
199: int inddd = name.lastIndexOf('.');
200: if (inddd > -1) {
201: name = name.substring(0, inddd);
202: }
203: name = name.replaceAll("[0-9._-]+$", ""); // NOI18N
204: if (assignValues) {
205: data.setProjectName(name);
206: }
207: JarFile jf = null;
208: String shortestPath = null;
209: try {
210: jf = new JarFile(fil);
211: Enumeration en = jf.entries();
212: while (en.hasMoreElements()) {
213: JarEntry entry = (JarEntry) en.nextElement();
214: if (!entry.isDirectory()
215: && entry.getName().endsWith(".class")) { // NOI18N
216: String nm = entry.getName();
217: if (!Util.isValidJavaFQN(nm.substring(0,
218: nm.length() - 6).replace('/', '.'))) {
219: continue; // #72669
220: }
221: int index = nm.lastIndexOf('/');
222: if (index > -1) {
223: String path = nm.substring(0, index);
224: if (shortestPath != null
225: && path.length() == shortestPath
226: .length()
227: && !path.equals(shortestPath)) {
228: cutShortestPath = true;
229: }
230: if (shortestPath == null
231: || path.length() < shortestPath
232: .length()) {
233: shortestPath = path;
234: cutShortestPath = false;
235: }
236: } else {
237: // a bad, bad jar having class files in default package.
238: if (!fileAlreadyMarked) {
239: wrongOnes = wrongOnes == null ? fil
240: .getName() : wrongOnes + ","
241: + fil.getName(); // NOI18N
242: fileAlreadyMarked = true;
243: }
244: }
245: }
246: }
247: } catch (IOException e) {
248: ErrorManager.getDefault().notify(ErrorManager.WARNING,
249: e);
250: } finally {
251: if (jf != null) {
252: try {
253: jf.close();
254: } catch (IOException e) {
255: Util.err.notify(ErrorManager.INFORMATIONAL, e);
256: }
257: }
258: }
259: if (shortestPath != null && assignValues) {
260: shortestPath = shortestPath.replace('/', '.');
261: if (cutShortestPath
262: && shortestPath.indexOf('.') != shortestPath
263: .lastIndexOf('.')) {
264: // if there's more than one dot (meanign we don't want to cut too much to present just
265: // org or com. org.apache is probably already good enough
266: int ind = shortestPath.lastIndexOf('.');
267: shortestPath = shortestPath.substring(0, ind);
268: }
269: data.setCodeNameBase(shortestPath);
270: }
271: }
272: return wrongOnes;
273: }
274:
275: public @Override
276: void addNotify() {
277: super .addNotify();
278: attachDocumentListeners();
279: }
280:
281: public @Override
282: void removeNotify() {
283: // prevent checking when the panel is not "active"
284: removeDocumentListeners();
285: super .removeNotify();
286: }
287:
288: private void attachDocumentListeners() {
289: if (!listenersAttached) {
290: txtLibrary.getDocument().addDocumentListener(libraryDL);
291: txtLicense.getDocument().addDocumentListener(licenseDL);
292: listenersAttached = true;
293: }
294: }
295:
296: private void removeDocumentListeners() {
297: if (listenersAttached) {
298: txtLibrary.getDocument().removeDocumentListener(libraryDL);
299: txtLicense.getDocument().removeDocumentListener(licenseDL);
300: listenersAttached = false;
301: }
302: }
303:
304: private static String getMessage(String key) {
305: return NbBundle.getMessage(LibraryStartVisualPanel.class, key);
306: }
307:
308: /** This method is called from within the constructor to
309: * initialize the form.
310: * WARNING: Do NOT modify this code. The content of this method is
311: * always regenerated by the Form Editor.
312: */
313: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
314: private void initComponents() {
315: java.awt.GridBagConstraints gridBagConstraints;
316:
317: confPanel = new javax.swing.JPanel();
318: lblLibrary = new javax.swing.JLabel();
319: txtLibrary = new javax.swing.JTextField();
320: lblLicense = new javax.swing.JLabel();
321: txtLicense = new javax.swing.JTextField();
322: browseLibraryButton = new javax.swing.JButton();
323: browseLicenceButton = new javax.swing.JButton();
324: filler = new javax.swing.JPanel();
325:
326: setLayout(new java.awt.GridBagLayout());
327:
328: confPanel.setLayout(new java.awt.GridBagLayout());
329:
330: lblLibrary.setLabelFor(txtLibrary);
331: org.openide.awt.Mnemonics.setLocalizedText(lblLibrary,
332: org.openide.util.NbBundle.getMessage(
333: LibraryStartVisualPanel.class,
334: "LBL_Library_path"));
335: gridBagConstraints = new java.awt.GridBagConstraints();
336: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
337: gridBagConstraints.insets = new java.awt.Insets(1, 0, 6, 12);
338: confPanel.add(lblLibrary, gridBagConstraints);
339:
340: gridBagConstraints = new java.awt.GridBagConstraints();
341: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
342: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
343: gridBagConstraints.insets = new java.awt.Insets(1, 0, 6, 0);
344: confPanel.add(txtLibrary, gridBagConstraints);
345:
346: lblLicense.setLabelFor(txtLicense);
347: org.openide.awt.Mnemonics.setLocalizedText(lblLicense,
348: org.openide.util.NbBundle.getMessage(
349: LibraryStartVisualPanel.class,
350: "LBL_License_Path"));
351: gridBagConstraints = new java.awt.GridBagConstraints();
352: gridBagConstraints.gridx = 0;
353: gridBagConstraints.gridy = 1;
354: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
355: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
356: confPanel.add(lblLicense, gridBagConstraints);
357:
358: gridBagConstraints = new java.awt.GridBagConstraints();
359: gridBagConstraints.gridx = 1;
360: gridBagConstraints.gridy = 1;
361: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
362: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
363: gridBagConstraints.weightx = 1.0;
364: confPanel.add(txtLicense, gridBagConstraints);
365:
366: org.openide.awt.Mnemonics.setLocalizedText(browseLibraryButton,
367: org.openide.util.NbBundle.getMessage(
368: LibraryStartVisualPanel.class,
369: "CTL_BrowseButton_o"));
370: browseLibraryButton
371: .addActionListener(new java.awt.event.ActionListener() {
372: public void actionPerformed(
373: java.awt.event.ActionEvent evt) {
374: browseLibraryButtonActionPerformed(evt);
375: }
376: });
377:
378: gridBagConstraints = new java.awt.GridBagConstraints();
379: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
380: gridBagConstraints.insets = new java.awt.Insets(0, 12, 6, 0);
381: confPanel.add(browseLibraryButton, gridBagConstraints);
382:
383: org.openide.awt.Mnemonics.setLocalizedText(browseLicenceButton,
384: org.openide.util.NbBundle.getMessage(
385: LibraryStartVisualPanel.class,
386: "CTL_BrowseButton_w"));
387: browseLicenceButton
388: .addActionListener(new java.awt.event.ActionListener() {
389: public void actionPerformed(
390: java.awt.event.ActionEvent evt) {
391: browseLicenceButtonActionPerformed(evt);
392: }
393: });
394:
395: gridBagConstraints = new java.awt.GridBagConstraints();
396: gridBagConstraints.gridx = 2;
397: gridBagConstraints.gridy = 1;
398: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
399: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
400: confPanel.add(browseLicenceButton, gridBagConstraints);
401:
402: gridBagConstraints = new java.awt.GridBagConstraints();
403: gridBagConstraints.gridx = 0;
404: gridBagConstraints.gridy = 2;
405: gridBagConstraints.gridwidth = 3;
406: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
407: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
408: gridBagConstraints.weightx = 1.0;
409: gridBagConstraints.weighty = 1.0;
410: confPanel.add(filler, gridBagConstraints);
411:
412: gridBagConstraints = new java.awt.GridBagConstraints();
413: gridBagConstraints.gridx = 0;
414: gridBagConstraints.gridy = 0;
415: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
416: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
417: gridBagConstraints.weightx = 1.0;
418: gridBagConstraints.weighty = 1.0;
419: gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 0);
420: add(confPanel, gridBagConstraints);
421:
422: }// </editor-fold>//GEN-END:initComponents
423:
424: private void browseLicenceButtonActionPerformed(
425: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLicenceButtonActionPerformed
426: JFileChooser chooser = new JFileChooser(ModuleUISettings
427: .getDefault().getLastChosenLibraryLocation());
428: chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
429: chooser.setMultiSelectionEnabled(false);
430: if (txtLicense.getText().trim().length() > 0) {
431: chooser.setSelectedFile(new File(txtLicense.getText()
432: .trim()));
433: }
434: int ret = chooser.showDialog(this , getMessage("LBL_Select"));
435: if (ret == JFileChooser.APPROVE_OPTION) {
436: txtLicense.setText(chooser.getSelectedFile()
437: .getAbsolutePath());
438: ModuleUISettings.getDefault().setLastChosenLibraryLocation(
439: txtLicense.getText());
440: }
441: }//GEN-LAST:event_browseLicenceButtonActionPerformed
442:
443: private void browseLibraryButtonActionPerformed(
444: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLibraryButtonActionPerformed
445: JFileChooser chooser = new JFileChooser(ModuleUISettings
446: .getDefault().getLastChosenLibraryLocation());
447: File[] olds = convertStringToFiles(txtLibrary.getText().trim());
448: chooser.setSelectedFiles(olds);
449: chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
450: chooser.setMultiSelectionEnabled(true);
451: chooser.addChoosableFileFilter(new JarZipFilter());
452: int ret = chooser.showDialog(this , getMessage("LBL_Select"));
453: if (ret == JFileChooser.APPROVE_OPTION) {
454: File[] files = chooser.getSelectedFiles();
455: String path = "";
456: for (int i = 0; i < files.length; i++) {
457: path = path
458: + files[i]
459: + (i == files.length - 1 ? ""
460: : File.pathSeparator);
461: }
462: txtLibrary.setText(path);
463: ModuleUISettings.getDefault().setLastChosenLibraryLocation(
464: files[0].getParentFile().getAbsolutePath());
465: }
466: }//GEN-LAST:event_browseLibraryButtonActionPerformed
467:
468: static File[] convertStringToFiles(String path) {
469: StringTokenizer tok = new StringTokenizer(path,
470: File.pathSeparator);
471: File[] olds = new File[tok.countTokens()];
472: for (int i = 0; i < olds.length; i++) {
473: olds[i] = new File(tok.nextToken());
474: }
475: return olds;
476: }
477:
478: // Variables declaration - do not modify//GEN-BEGIN:variables
479: private javax.swing.JButton browseLibraryButton;
480: private javax.swing.JButton browseLicenceButton;
481: private javax.swing.JPanel confPanel;
482: private javax.swing.JPanel filler;
483: private javax.swing.JLabel lblLibrary;
484: private javax.swing.JLabel lblLicense;
485: private javax.swing.JTextField txtLibrary;
486: private javax.swing.JTextField txtLicense;
487:
488: // End of variables declaration//GEN-END:variables
489:
490: private static final class JarZipFilter extends FileFilter {
491: public boolean accept(File pathname) {
492: return pathname.isDirectory()
493: || pathname.getName().endsWith("zip")
494: || pathname.getName().endsWith("jar"); // NOI18N
495: }
496:
497: public String getDescription() {
498: return getMessage("LibraryStartVisualPanel_jar_zip_filter");
499: }
500: }
501:
502: }
|