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: package org.netbeans.modules.visualweb.project.jsf.ui;
042:
043: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectConstants;
044: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
045: import org.netbeans.modules.visualweb.project.jsf.framework.JSFFrameworkProvider;
046: import org.netbeans.modules.web.api.webmodule.ExtenderController;
047:
048: import org.netbeans.modules.web.api.webmodule.WebModule;
049: import org.netbeans.modules.web.api.webmodule.WebFrameworks;
050: import org.netbeans.modules.web.spi.webmodule.WebFrameworkProvider;
051: import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
052:
053: import java.awt.Component;
054: import java.io.IOException;
055: import java.util.Collections;
056: import java.util.Map;
057: import java.util.NoSuchElementException;
058: import java.util.Set;
059: import java.util.List;
060: import java.util.HashMap;
061: import javax.swing.JComponent;
062: import javax.swing.event.ChangeListener;
063:
064: import org.netbeans.api.java.project.JavaProjectConstants;
065: import org.netbeans.modules.web.spi.webmodule.WebModuleExtender;
066: import org.netbeans.spi.project.ui.templates.support.Templates;
067: import org.netbeans.api.project.FileOwnerQuery;
068: import org.netbeans.api.project.Project;
069: import org.netbeans.api.project.ProjectUtils;
070: import org.netbeans.api.project.SourceGroup;
071: import org.netbeans.api.project.Sources;
072: import org.openide.DialogDisplayer;
073: import org.openide.NotifyDescriptor;
074: import org.openide.NotifyDescriptor.Message;
075:
076: import org.openide.WizardDescriptor;
077: import org.openide.cookies.OpenCookie;
078: import org.openide.filesystems.FileObject;
079: import org.openide.filesystems.FileSystem;
080: import org.openide.filesystems.FileUtil;
081: import org.openide.filesystems.Repository;
082: import org.openide.loaders.*;
083: import org.openide.util.Lookup;
084: import org.openide.util.NbBundle;
085:
086: /** A template wizard iterator for new JSF page action
087: *
088: * @author Po-Ting Wu
089: */
090: public class PageIterator implements TemplateWizard.Iterator {
091:
092: private static final long serialVersionUID = 1L;
093: public static final String FILETYPE_WEBFORM = "WebForm";
094: public static final String FILETYPE_BEAN = "Bean";
095: private String fileType;
096: private int index;
097: private boolean usePageLayout = false;
098: PageLayoutChooserPanel pageLayoutChooserPanel = new PageLayoutChooserPanel();
099: private transient WizardDescriptor.Panel[] panels;
100:
101: public static PageIterator createWebFormIterator() {
102: return new PageIterator(FILETYPE_WEBFORM);
103: }
104:
105: public static PageIterator createBeanIterator() {
106: return new PageIterator(FILETYPE_BEAN);
107: }
108:
109: private PageIterator(String fileType) {
110: this .fileType = fileType;
111: }
112:
113: public void initialize(TemplateWizard wizard) {
114: index = 0;
115: // obtaining target folder
116: Project project = Templates.getProject(wizard);
117: SourceGroup[] sourceGroups = ProjectUtils
118: .getSources(project)
119: .getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
120:
121: WizardDescriptor.Panel packagePanel = new PagebeanPackagePanel(
122: project);
123: WizardDescriptor.Panel javaPanel = new SimpleTargetChooserPanel(
124: project, sourceGroups, packagePanel, false, fileType);
125: String templateType = Templates.getTemplate(wizard).getExt();
126:
127: boolean templatesAvailable = pageLayoutChooserPanel
128: .isPageLayoutsAvailable();
129: if (fileType.equals(FILETYPE_WEBFORM)
130: && (!"jspf".equals(templateType))
131: && (J2eeModule.JAVA_EE_5.equals(JsfProjectUtils
132: .getJ2eePlatformVersion(project)))
133: && templatesAvailable) {
134: usePageLayout = true;
135: }
136:
137: if (usePageLayout) {
138: panels = new WizardDescriptor.Panel[] { javaPanel,
139: pageLayoutChooserPanel };
140: } else {
141: panels = new WizardDescriptor.Panel[] { javaPanel };
142: }
143:
144: // Creating steps.
145: Object prop = wizard.getProperty("WizardPanel_contentData"); // NOI18N
146: String[] beforeSteps = null;
147: if (prop != null && prop instanceof String[]) {
148: beforeSteps = (String[]) prop;
149: }
150: String[] steps = createSteps(beforeSteps, panels);
151:
152: for (int i = 0; i < panels.length; i++) {
153: JComponent jc = (JComponent) panels[i].getComponent();
154: if (steps[i] == null) {
155: steps[i] = jc.getName();
156: }
157: jc.putClientProperty("WizardPanel_contentSelectedIndex",
158: new Integer(i)); // NOI18N
159: jc.putClientProperty("WizardPanel_contentData", steps); // NOI18N
160: }
161:
162: // no support for non-web project
163: if (!JsfProjectUtils.isWebProject(project)) {
164: return;
165: }
166:
167: if (fileType.equals(FILETYPE_WEBFORM)) {
168: // Always start with the document root or under
169: FileObject docRoot = JsfProjectUtils
170: .getDocumentRoot(project);
171: FileObject javaDir = JsfProjectUtils
172: .getPageBeanRoot(project);
173: FileObject jspDir = Templates.getTargetFolder(wizard);
174: String relativePath = (jspDir == null) ? null : FileUtil
175: .getRelativePath(docRoot, jspDir);
176: if ((relativePath == null)
177: || (relativePath.indexOf("WEB-INF") != -1)) {
178: Templates.setTargetFolder(wizard, docRoot);
179: jspDir = docRoot;
180: } else if (relativePath.length() > 0) {
181: javaDir = javaDir.getFileObject(relativePath);
182: }
183:
184: // Find a free page name
185: String ext = Templates.getTemplate(wizard).getExt();
186: String prefix = "jsp".equals(ext) ? "Page" : "Fragment"; // NOI18N
187: for (int pageIndex = 1;; pageIndex++) {
188: String name = prefix + pageIndex;
189: if ((jspDir.getFileObject(name + "." + ext) == null)
190: && ((javaDir == null) || (javaDir
191: .getFileObject(name + ".java") == null))) { // NOI18N
192: wizard.setTargetName(name);
193: return;
194: }
195: }
196: } else if (fileType.equals(FILETYPE_BEAN)) {
197: // Always start with the bean package root or under
198: FileObject javaDir = JsfProjectUtils
199: .getPageBeanRoot(project);
200: if (javaDir == null) {
201: return;
202: }
203:
204: FileObject beanDir = Templates.getTargetFolder(wizard);
205: String relativePath = (beanDir == null) ? null : FileUtil
206: .getRelativePath(javaDir, beanDir);
207: if (relativePath == null) {
208: Templates.setTargetFolder(wizard, javaDir);
209: beanDir = javaDir;
210: }
211:
212: // Find a free bean name
213: String header = Templates.getTemplate(wizard).getName();
214: for (int beanIndex = 1;; beanIndex++) {
215: String name = header + beanIndex;
216: if (beanDir.getFileObject(name + ".java") == null) { // NOI18N
217: wizard.setTargetName(name);
218: return;
219: }
220: }
221: }
222: }
223:
224: public void uninitialize(TemplateWizard wizard) {
225: panels = null;
226: }
227:
228: public Set instantiate(TemplateWizard wizard) throws IOException/*, IllegalStateException*/{
229: // Here is the default plain behavior. Simply takes the selected
230: // template (you need to have included the standard second panel
231: // in createPanels(), or at least set the properties targetName and
232: // targetFolder correctly), instantiates it in the provided
233: // position, and returns the result.
234: // More advanced wizards can create multiple objects from template
235: // (return them all in the result of this method), populate file
236: // contents on the fly, etc.
237: FileObject dir = Templates.getTargetFolder(wizard);
238: DataFolder df = DataFolder.findFolder(dir);
239: FileObject template = Templates.getTemplate(wizard);
240: Project project = Templates.getProject(wizard);
241:
242: if (J2eeModule.JAVA_EE_5.equals(JsfProjectUtils
243: .getJ2eePlatformVersion(project))
244: && usePageLayout) {
245: PageLayoutData selectedTemplate = pageLayoutChooserPanel
246: .getSelectedPageLayout();
247: selectedTemplate.copyResources(JsfProjectUtils
248: .getResourcesDirectory(project));
249: template = selectedTemplate.getFileObject();
250: }
251:
252: DataObject dTemplate = DataObject.find(template);
253: String targetName = Templates.getTargetName(wizard);
254: Set result = Collections.EMPTY_SET;
255:
256: // Visual Web framework is not initialized
257: if (!JsfProjectUtils.isJsfProject(project)) {
258: List<WebFrameworkProvider> frameworks = WebFrameworks
259: .getFrameworks();
260: for (WebFrameworkProvider framework : frameworks) {
261: if (framework instanceof JSFFrameworkProvider) {
262: WebModule webModule = JsfProjectUtils
263: .getWebModule(project);
264:
265: String beanPackage = (String) wizard
266: .getProperty(JsfProjectConstants.PROP_JSF_PAGEBEAN_PACKAGE);
267: if (beanPackage == null) {
268: beanPackage = JsfProjectUtils
269: .deriveSafeName(project
270: .getProjectDirectory()
271: .getName());
272: }
273: JsfProjectUtils
274: .createProjectProperty(
275: project,
276: JsfProjectConstants.PROP_JSF_PAGEBEAN_PACKAGE,
277: beanPackage);
278:
279: if ("jsp".equals(template.getExt())) { // NOI18N
280: setStartPage(project, webModule, dir,
281: targetName);
282: } else if ("jspf".equals(template.getExt())
283: && "Page1".equals(targetName)) { // NOI18N
284: setStartPage(project, webModule, dir, "Page2"); // NOI18N
285: }
286:
287: WebModuleExtender extender = framework
288: .createWebModuleExtender(webModule,
289: ExtenderController.create());
290: result = extender.extend(webModule);
291:
292: if (dir.getFileObject(targetName + "."
293: + template.getExt()) != null) { // NOI18N
294: return result;
295: }
296: }
297: }
298: }
299:
300: DataObject obj;
301: try {
302: if (targetName == null) {
303: // Default name.
304: obj = dTemplate.createFromTemplate(df);
305: } else {
306: Map<String, String> templateParameters = new HashMap<String, String>();
307: templateParameters
308: .put("j2eePlatformVersion", JsfProjectUtils
309: .getJ2eePlatformVersion(project)); //NOI18N
310: templateParameters.put("sourceLevel", JsfProjectUtils
311: .getSourceLevel(project)); //NOI18N
312:
313: if ("jsp".equals(template.getExt())) { // NOI18N
314: FileObject webDocbase = JsfProjectUtils
315: .getDocumentRoot(project);
316: String folder;
317: if (dir == webDocbase) {
318: folder = "";
319: } else {
320: folder = FileUtil.getRelativePath(webDocbase,
321: dir);
322: if (folder == null) {
323: folder = "";
324: } else {
325: folder = folder.replace('/', '$') + "$";
326: }
327: }
328: templateParameters.put("folder", folder); //NOI18N
329:
330: }
331:
332: obj = dTemplate.createFromTemplate(df, targetName,
333: templateParameters);
334: }
335: } catch (org.netbeans.modules.visualweb.project.jsf.api.JsfDataObjectException jsfe) {
336: DialogDisplayer.getDefault().notify(
337: new NotifyDescriptor.Message(NbBundle.getMessage(
338: PageIterator.class, "TXT_CantCreatePage",
339: df.getName())));
340: return result;
341: }
342:
343: if (result == Collections.EMPTY_SET) {
344: result = Collections.singleton(obj);
345: } else {
346: result.add(obj);
347: }
348:
349: // Open the new document
350: OpenCookie open = (OpenCookie) obj.getCookie(OpenCookie.class);
351: if (open != null) {
352: open.open();
353: }
354: return result;
355: }
356:
357: private void setStartPage(Project project, WebModule webModule,
358: FileObject targetFolder, String targetName) {
359: String startPage = targetName + ".jsp";
360: FileObject webFolder = webModule.getDocumentBase();
361: if (webFolder != null) {
362: // Allow the first start page been created under subdir of the web root.
363: String startPath = FileUtil.getRelativePath(webFolder,
364: targetFolder);
365: if (startPath != null && startPath.length() > 0) {
366: startPage = startPath + "/" + startPage;
367: }
368: }
369: JsfProjectUtils.createProjectProperty(project,
370: JsfProjectConstants.PROP_START_PAGE, startPage);
371: }
372:
373: public void previousPanel() {
374: if (!hasPrevious())
375: throw new NoSuchElementException();
376: index--;
377: }
378:
379: public void nextPanel() {
380: if (!hasNext())
381: throw new NoSuchElementException();
382: index++;
383: }
384:
385: public boolean hasPrevious() {
386: return index > 0;
387: }
388:
389: public boolean hasNext() {
390: return index < panels.length - 1;
391: }
392:
393: public String name() {
394: return NbBundle.getMessage(PageIterator.class, "TITLE_x_of_y",
395: new Integer(index + 1), new Integer(panels.length));
396: }
397:
398: public WizardDescriptor.Panel current() {
399: return panels[index];
400: }
401:
402: // If nothing unusual changes in the middle of the wizard, simply:
403:
404: public final void addChangeListener(ChangeListener l) {
405: }
406:
407: public final void removeChangeListener(ChangeListener l) {
408: }
409:
410: private String[] createSteps(String[] before,
411: WizardDescriptor.Panel[] panels) {
412: int diff = 0;
413: if (before == null) {
414: before = new String[0];
415: } else if (before.length > 0) {
416: diff = ("...".equals(before[before.length - 1])) ? 1 : 0; // NOI18N
417: }
418: String[] res = new String[(before.length - diff)
419: + panels.length];
420: for (int i = 0; i < res.length; i++) {
421: if (i < (before.length - diff)) {
422: res[i] = before[i];
423: } else {
424: res[i] = panels[i - before.length + diff]
425: .getComponent().getName();
426: }
427: }
428: return res;
429: }
430: }
|