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: package org.netbeans.modules.ruby.rubyproject.ui.wizards;
043:
044: import java.awt.Component;
045: import java.io.File;
046: import java.io.IOException;
047: import java.text.MessageFormat;
048: import java.util.HashSet;
049: import java.util.NoSuchElementException;
050: import java.util.Set;
051: import javax.swing.JComponent;
052: import javax.swing.event.ChangeListener;
053: import org.netbeans.api.progress.ProgressHandle;
054: import org.netbeans.api.ruby.platform.RubyPlatform;
055: import org.netbeans.modules.ruby.rubyproject.RubyProjectGenerator;
056: import org.netbeans.modules.ruby.rubyproject.ui.FoldersListSettings;
057: import org.netbeans.modules.ruby.spi.project.support.rake.RakeProjectHelper;
058: import org.netbeans.spi.project.ui.support.ProjectChooser;
059: import org.openide.ErrorManager;
060: import org.openide.WizardDescriptor;
061: import org.openide.filesystems.FileObject;
062: import org.openide.filesystems.FileUtil;
063: import org.openide.util.NbBundle;
064:
065: /**
066: * Wizard to create a new Ruby project.
067: */
068: public class NewRubyProjectWizardIterator implements
069: WizardDescriptor.ProgressInstantiatingIterator {
070:
071: static final int TYPE_APP = 0;
072: //static final int TYPE_LIB = 1;
073: static final int TYPE_EXT = 2;
074:
075: static final String PROP_NAME_INDEX = "nameIndex"; //NOI18N
076:
077: private static final long serialVersionUID = 1L;
078:
079: private int type;
080:
081: /** Create a new wizard iterator. */
082: public NewRubyProjectWizardIterator() {
083: this (TYPE_APP);
084: }
085:
086: public NewRubyProjectWizardIterator(int type) {
087: this .type = type;
088: }
089:
090: // public static NewRubyProjectWizardIterator library() {
091: // return new NewRubyProjectWizardIterator( TYPE_LIB );
092: // }
093:
094: public static NewRubyProjectWizardIterator existing() {
095: return new NewRubyProjectWizardIterator(TYPE_EXT);
096: }
097:
098: private WizardDescriptor.Panel[] createPanels() {
099: return this .type == TYPE_EXT ? new WizardDescriptor.Panel[] {
100: new PanelConfigureProject(this .type),
101: new PanelSourceFolders.Panel() }
102: : new WizardDescriptor.Panel[] { new PanelConfigureProject(
103: this .type) };
104: }
105:
106: private String[] createSteps() {
107: return this .type == TYPE_EXT ? new String[] {
108: NbBundle.getMessage(NewRubyProjectWizardIterator.class,
109: "LAB_ConfigureProject"),
110: NbBundle.getMessage(NewRubyProjectWizardIterator.class,
111: "LAB_ConfigureSourceRoots"), }
112: : new String[] { NbBundle.getMessage(
113: NewRubyProjectWizardIterator.class,
114: "LAB_ConfigureProject"), };
115: }
116:
117: public Set/*<FileObject>*/instantiate() throws IOException {
118: assert false : "Cannot call this method if implements WizardDescriptor.ProgressInstantiatingIterator.";
119: return null;
120: }
121:
122: public Set/*<FileObject>*/instantiate(ProgressHandle handle)
123: throws IOException {
124: handle.start(4);
125: //handle.progress (NbBundle.getMessage (NewRubyProjectWizardIterator.class, "LBL_NewRubyProjectWizardIterator_WizardProgress_ReadingProperties"));
126: Set<FileObject> resultSet = new HashSet<FileObject>();
127: File dirF = (File) wiz.getProperty("projdir"); //NOI18N
128: if (dirF != null) {
129: dirF = FileUtil.normalizeFile(dirF);
130: }
131: String name = (String) wiz.getProperty("name"); //NOI18N
132: handle
133: .progress(
134: NbBundle
135: .getMessage(
136: NewRubyProjectWizardIterator.class,
137: "LBL_NewRubyProjectWizardIterator_WizardProgress_CreatingProject"),
138: 1);
139: RubyPlatform platform = (RubyPlatform) wiz
140: .getProperty("platform"); // NOI18N
141: if (this .type == TYPE_EXT) {
142: File[] sourceFolders = (File[]) wiz
143: .getProperty("sourceRoot"); //NOI18N
144: File[] testFolders = (File[]) wiz.getProperty("testRoot"); //NOI18N
145: RubyProjectGenerator.createProject(dirF, name,
146: sourceFolders, testFolders, platform);
147: handle.progress(2);
148: for (int i = 0; i < sourceFolders.length; i++) {
149: FileObject srcFo = FileUtil
150: .toFileObject(sourceFolders[i]);
151: if (srcFo != null) {
152: resultSet.add(srcFo);
153: }
154: }
155: } else {
156: String mainClass = (String) wiz.getProperty("mainClass"); // NOI18N
157: RakeProjectHelper h = RubyProjectGenerator.createProject(
158: dirF, name, mainClass, platform);
159: handle.progress(2);
160: // BEGIN SEMPLICE MODIFICATIONS
161: // Update since format is customized
162: //mainClass = (String)wiz.getProperty("mainClass");
163: // END SEMPLICE MODIFICATIONS
164:
165: if (mainClass != null && mainClass.length() > 0) {
166: try {
167: //String sourceRoot = "lib"; //(String)j2seProperties.get (RubyProjectProperties.SRC_DIR);
168: FileObject sourcesRoot = h.getProjectDirectory()
169: .getFileObject("lib"); //NOI18N
170: FileObject mainClassFo = getMainClassFO(
171: sourcesRoot, mainClass);
172: assert mainClassFo != null : "sourcesRoot: "
173: + sourcesRoot + ", mainClass: " + mainClass; //NOI18N
174: // Returning FileObject of main class, will be called its preferred action
175: resultSet.add(mainClassFo);
176: } catch (Exception x) {
177: ErrorManager.getDefault().notify(x);
178: }
179: }
180: // if ( type == TYPE_LIB ) {
181: // resultSet.add( h.getProjectDirectory ().getFileObject ("lib") ); //NOI18N
182: // resultSet.add( h.getProjectDirectory() ); // Only expand the project directory
183: // }
184: }
185: FileObject dir = FileUtil.toFileObject(dirF);
186: handle.progress(3);
187:
188: // Returning FileObject of project diretory.
189: // Project will be open and set as main
190: Integer index = (Integer) wiz.getProperty(PROP_NAME_INDEX);
191: switch (this .type) {
192: case TYPE_APP:
193: FoldersListSettings.getDefault().setNewApplicationCount(
194: index.intValue());
195: break;
196: // case TYPE_LIB:
197: // FoldersListSettings.getDefault().setNewLibraryCount(index.intValue());
198: // break;
199: case TYPE_EXT:
200: FoldersListSettings.getDefault().setNewProjectCount(
201: index.intValue());
202: break;
203: }
204: resultSet.add(dir);
205: handle
206: .progress(
207: NbBundle
208: .getMessage(
209: NewRubyProjectWizardIterator.class,
210: "LBL_NewRubyProjectWizardIterator_WizardProgress_PreparingToOpen"),
211: 4);
212: dirF = (dirF != null) ? dirF.getParentFile() : null;
213: if (dirF != null && dirF.exists()) {
214: ProjectChooser.setProjectsFolder(dirF);
215: }
216:
217: return resultSet;
218: }
219:
220: private transient int index;
221: private transient WizardDescriptor.Panel[] panels;
222: private transient WizardDescriptor wiz;
223:
224: public void initialize(WizardDescriptor wiz) {
225: this .wiz = wiz;
226: index = 0;
227: panels = createPanels();
228: // Make sure list of steps is accurate.
229: String[] steps = createSteps();
230: for (int i = 0; i < panels.length; i++) {
231: Component c = panels[i].getComponent();
232: if (steps[i] == null) {
233: // Default step name to component name of panel.
234: // Mainly useful for getting the name of the target
235: // chooser to appear in the list of steps.
236: steps[i] = c.getName();
237: }
238: if (c instanceof JComponent) { // assume Swing components
239: JComponent jc = (JComponent) c;
240: // Step #.
241: jc.putClientProperty(
242: "WizardPanel_contentSelectedIndex",
243: new Integer(i)); // NOI18N
244: // Step name (actually the whole list for reference).
245: jc.putClientProperty("WizardPanel_contentData", steps); // NOI18N
246: }
247: }
248: //set the default values of the sourceRoot and the testRoot properties
249: this .wiz.putProperty("sourceRoot", new File[0]); //NOI18N
250: this .wiz.putProperty("testRoot", new File[0]); //NOI18N
251: }
252:
253: public void uninitialize(WizardDescriptor wiz) {
254: if (this .wiz != null) {
255: this .wiz.putProperty("projdir", null); //NOI18N
256: this .wiz.putProperty("name", null); //NOI18N
257: this .wiz.putProperty("mainClass", null); //NOI18N
258: this .wiz.putProperty("platform", null); //NOI18N
259: if (this .type == TYPE_EXT) {
260: this .wiz.putProperty("sourceRoot", null); //NOI18N
261: this .wiz.putProperty("testRoot", null); //NOI18N
262: }
263: this .wiz = null;
264: panels = null;
265: }
266: }
267:
268: public String name() {
269: return MessageFormat.format(
270: NbBundle.getMessage(NewRubyProjectWizardIterator.class,
271: "LAB_IteratorName"), new Object[] {
272: new Integer(index + 1),
273: new Integer(panels.length) });
274: }
275:
276: public boolean hasNext() {
277: return index < panels.length - 1;
278: }
279:
280: public boolean hasPrevious() {
281: return index > 0;
282: }
283:
284: public void nextPanel() {
285: if (!hasNext())
286: throw new NoSuchElementException();
287: index++;
288: }
289:
290: public void previousPanel() {
291: if (!hasPrevious())
292: throw new NoSuchElementException();
293: index--;
294: }
295:
296: public WizardDescriptor.Panel current() {
297: return panels[index];
298: }
299:
300: // If nothing unusual changes in the middle of the wizard, simply:
301: public final void addChangeListener(ChangeListener l) {
302: }
303:
304: public final void removeChangeListener(ChangeListener l) {
305: }
306:
307: // helper methods, finds mainclass's FileObject
308: private FileObject getMainClassFO(FileObject sourcesRoot,
309: String mainClass) {
310: // replace '.' with '/'
311: // mainClass = mainClass.replace ('.', '/'); // NOI18N
312: //
313: // // ignore unvalid mainClass ???
314: //
315: // return sourcesRoot.getFileObject (mainClass+ ".java"); // NOI18N
316: return sourcesRoot.getFileObject(mainClass);
317: }
318:
319: static String getPackageName(String displayName) {
320: StringBuffer builder = new StringBuffer();
321: boolean firstLetter = true;
322: for (int i = 0; i < displayName.length(); i++) {
323: char c = displayName.charAt(i);
324: if ((!firstLetter && Character.isJavaIdentifierPart(c))
325: || (firstLetter && Character
326: .isJavaIdentifierStart(c))) {
327: firstLetter = false;
328: if (Character.isUpperCase(c)) {
329: c = Character.toLowerCase(c);
330: }
331: builder.append(c);
332: }
333: }
334: return builder.length() == 0 ? NbBundle.getMessage(
335: NewRubyProjectWizardIterator.class,
336: "TXT_DefaultPackageName") : builder.toString();
337: }
338:
339: }
|