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.java.project;
043:
044: import java.awt.Component;
045: import java.io.IOException;
046: import java.util.Collections;
047: import java.util.HashSet;
048: import java.util.NoSuchElementException;
049: import java.util.Set;
050: import javax.swing.JComponent;
051: import javax.swing.event.ChangeEvent;
052: import javax.swing.event.ChangeListener;
053: import org.netbeans.api.java.project.JavaProjectConstants;
054: import org.netbeans.api.project.Project;
055: import org.netbeans.api.project.ProjectUtils;
056: import org.netbeans.api.project.SourceGroup;
057: import org.netbeans.api.project.Sources;
058: import org.netbeans.spi.java.project.support.ui.templates.JavaTemplates;
059: import org.netbeans.spi.project.ui.templates.support.Templates;
060: import org.openide.WizardDescriptor;
061: import org.openide.filesystems.FileObject;
062: import org.openide.filesystems.FileUtil;
063: import org.openide.loaders.DataFolder;
064: import org.openide.loaders.DataObject;
065:
066: /**
067: * Wizard to create a new Java file.
068: */
069: public class NewJavaFileWizardIterator implements
070: WizardDescriptor.InstantiatingIterator {
071:
072: private static final long serialVersionUID = 1L;
073:
074: public static final int TYPE_FILE = 0;
075: public static final int TYPE_PACKAGE = 1;
076: public static final int TYPE_PKG_INFO = 2;
077:
078: private int type = TYPE_FILE;
079:
080: /** Create a new wizard iterator. */
081: public NewJavaFileWizardIterator() {
082: }
083:
084: private NewJavaFileWizardIterator(int type) {
085: this .type = type;
086: }
087:
088: public static NewJavaFileWizardIterator packageWizard() {
089: return new NewJavaFileWizardIterator(TYPE_PACKAGE);
090: }
091:
092: public static NewJavaFileWizardIterator packageInfoWizard() {
093: return new NewJavaFileWizardIterator(TYPE_PKG_INFO);
094: }
095:
096: private WizardDescriptor.Panel[] createPanels(
097: WizardDescriptor wizardDescriptor) {
098:
099: // Ask for Java folders
100: Project project = Templates.getProject(wizardDescriptor);
101: Sources sources = ProjectUtils.getSources(project);
102: SourceGroup[] groups = sources
103: .getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
104: assert groups != null : "Cannot return null from Sources.getSourceGroups: "
105: + sources;
106: if (groups.length == 0) {
107: groups = sources.getSourceGroups(Sources.TYPE_GENERIC);
108: return new WizardDescriptor.Panel[] { Templates
109: .createSimpleTargetChooser(project, groups), };
110: } else {
111:
112: if (this .type == TYPE_FILE) {
113: return new WizardDescriptor.Panel[] { JavaTemplates
114: .createPackageChooser(project, groups), };
115: } else {
116: return new WizardDescriptor.Panel[] { new JavaTargetChooserPanel(
117: project, groups, null, this .type,
118: this .type == TYPE_PKG_INFO), };
119: }
120: }
121:
122: }
123:
124: private String[] createSteps(String[] before,
125: WizardDescriptor.Panel[] panels) {
126: assert panels != null;
127: // hack to use the steps set before this panel processed
128: int diff = 0;
129: if (before == null) {
130: before = new String[0];
131: } else if (before.length > 0) {
132: diff = ("...".equals(before[before.length - 1])) ? 1 : 0; // NOI18N
133: }
134: String[] res = new String[(before.length - diff)
135: + panels.length];
136: for (int i = 0; i < res.length; i++) {
137: if (i < (before.length - diff)) {
138: res[i] = before[i];
139: } else {
140: res[i] = panels[i - before.length + diff]
141: .getComponent().getName();
142: }
143: }
144: return res;
145: }
146:
147: public Set/*<FileObject>*/instantiate() throws IOException {
148: FileObject dir = Templates.getTargetFolder(wiz);
149: String targetName = Templates.getTargetName(wiz);
150:
151: DataFolder df = DataFolder.findFolder(dir);
152: FileObject template = Templates.getTemplate(wiz);
153:
154: FileObject createdFile = null;
155: if (this .type == TYPE_PACKAGE) {
156: targetName = targetName.replace('.', '/'); // NOI18N
157: createdFile = FileUtil.createFolder(dir, targetName);
158: } else {
159: DataObject dTemplate = DataObject.find(template);
160: DataObject dobj = dTemplate.createFromTemplate(df,
161: targetName);
162: createdFile = dobj.getPrimaryFile();
163: }
164:
165: return Collections.singleton(createdFile);
166: }
167:
168: private transient int index;
169: private transient WizardDescriptor.Panel[] panels;
170: private transient WizardDescriptor wiz;
171:
172: public void initialize(WizardDescriptor wiz) {
173: this .wiz = wiz;
174: index = 0;
175: panels = createPanels(wiz);
176: // Make sure list of steps is accurate.
177: String[] beforeSteps = null;
178: Object prop = wiz.getProperty("WizardPanel_contentData"); // NOI18N
179: if (prop != null && prop instanceof String[]) {
180: beforeSteps = (String[]) prop;
181: }
182: String[] steps = createSteps(beforeSteps, panels);
183: for (int i = 0; i < panels.length; i++) {
184: Component c = panels[i].getComponent();
185: if (steps[i] == null) {
186: // Default step name to component name of panel.
187: // Mainly useful for getting the name of the target
188: // chooser to appear in the list of steps.
189: steps[i] = c.getName();
190: }
191: if (c instanceof JComponent) { // assume Swing components
192: JComponent jc = (JComponent) c;
193: // Step #.
194: jc.putClientProperty(
195: "WizardPanel_contentSelectedIndex",
196: new Integer(i)); // NOI18N
197: // Step name (actually the whole list for reference).
198: jc.putClientProperty("WizardPanel_contentData", steps); // NOI18N
199: }
200: }
201: }
202:
203: public void uninitialize(WizardDescriptor wiz) {
204: this .wiz = null;
205: panels = null;
206: }
207:
208: public String name() {
209: //return "" + (index + 1) + " of " + panels.length;
210: return ""; // NOI18N
211: }
212:
213: public boolean hasNext() {
214: return index < panels.length - 1;
215: }
216:
217: public boolean hasPrevious() {
218: return index > 0;
219: }
220:
221: public void nextPanel() {
222: if (!hasNext())
223: throw new NoSuchElementException();
224: index++;
225: }
226:
227: public void previousPanel() {
228: if (!hasPrevious())
229: throw new NoSuchElementException();
230: index--;
231: }
232:
233: public WizardDescriptor.Panel current() {
234: return panels[index];
235: }
236:
237: private transient Set<ChangeListener> listeners = new HashSet<ChangeListener>(
238: 1);
239:
240: public final void addChangeListener(ChangeListener l) {
241: synchronized (listeners) {
242: listeners.add(l);
243: }
244: }
245:
246: public final void removeChangeListener(ChangeListener l) {
247: synchronized (listeners) {
248: listeners.remove(l);
249: }
250: }
251:
252: protected final void fireChangeEvent() {
253: ChangeListener[] ls;
254: synchronized (listeners) {
255: ls = listeners
256: .toArray(new ChangeListener[listeners.size()]);
257: }
258: ChangeEvent ev = new ChangeEvent(this );
259: for (ChangeListener l : ls) {
260: l.stateChanged(ev);
261: }
262: }
263:
264: }
|