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.xhtml;
042:
043: import org.netbeans.modules.visualweb.api.insync.InSyncService;
044: import java.awt.event.ActionListener;
045: import java.awt.event.ItemListener;
046: import java.io.IOException;
047: import java.util.ArrayList;
048: import java.util.Collections;
049: import java.util.List;
050:
051: import javax.swing.DefaultComboBoxModel;
052: import org.netbeans.api.project.Project;
053:
054: import org.openide.DialogDescriptor;
055: import org.openide.DialogDisplayer;
056: import org.openide.ErrorManager;
057: import org.openide.filesystems.FileObject;
058: import org.openide.filesystems.FileSystem;
059: import org.openide.filesystems.Repository;
060: import org.openide.loaders.DataFolder;
061: import org.openide.loaders.DataObject;
062: import org.openide.loaders.DataObjectNotFoundException;
063: import org.openide.util.NbBundle;
064:
065: import com.sun.rave.designtime.DesignContext;
066: import com.sun.rave.designtime.DesignProject;
067: import com.sun.rave.designtime.DesignProperty;
068: import javax.swing.JDialog;
069: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
070:
071: /**
072: * Panel for selecting a page fragment
073: *
074: * @author Tor Norbye
075: */
076: public class FragmentPanel extends javax.swing.JPanel implements
077: ActionListener, ItemListener {
078: private DesignProperty prop;
079:
080: /** Creates new form FragmentPanel */
081: public FragmentPanel(DesignProperty prop) {
082: this .prop = prop;
083: initComponents();
084: createButton.addActionListener(this );
085: comboBox.addItemListener(this );
086: addComboFragments();
087: }
088:
089: /** Sync gui to property */
090: private void update() {
091: }
092:
093: private Project getProject() {
094: DesignContext context = prop.getDesignBean().getDesignContext();
095: DesignProject lp = context.getProject();
096: // FacesModelSet set = (FacesModelSet)lp;
097: // return set.getProject();
098: return InSyncService.getProvider().getProjectForDesignProject(
099: lp);
100: }
101:
102: private void addComboFragments() {
103: comboBox.setEditable(false);
104: // RequestProcessor.postRequest(new Runnable() {
105: // public void run() {
106: DesignContext context = prop.getDesignBean().getDesignContext();
107: DataObject curr = null;
108: if (context != null) {
109: // LiveUnit lu = (LiveUnit)context;
110: // FacesPageUnit fu = (FacesPageUnit)lu.getBeansUnit();
111: // MarkupUnit mu = fu.getPageUnit();
112: // FileObject fo = mu.getFileObject();
113: FileObject fo = InSyncService.getProvider()
114: .getMarkupFileObjectForDesignContext(context);
115: try {
116: curr = DataObject.find(fo);
117: } catch (DataObjectNotFoundException ce) {
118: }
119: }
120: // final ArrayList formList = new ArrayList();
121: Project project = getProject();
122: if (project == null) {
123: return;
124: }
125: FileObject webforms = JsfProjectUtils.getDocumentRoot(project);
126: if (webforms == null)
127: return;
128: // FacesModelSet modelset = FacesModelSet.getInstance(project);
129: DataObject folderObj = null;
130: try {
131: folderObj = DataObject.find(webforms);
132: } catch (DataObjectNotFoundException e) {
133: return;
134: }
135: final ArrayList formList = new ArrayList();
136: if (folderObj instanceof DataFolder) {
137: addSubFolderFragments((DataFolder) folderObj, formList, /*modelset,*/
138: curr);
139: }
140: // SwingUtilities.invokeLater(new Runnable() {
141: // public void run() {
142: String[] comboValues = (String[]) formList
143: .toArray(new String[formList.size()]);
144: comboBox.setModel(new DefaultComboBoxModel(comboValues));
145: comboBox.setEditable(true);
146: // int index = formList.indexOf(prop.getValue().toString());
147: if (prop.getValue() != null) {
148: comboBox.setSelectedItem(prop.getValue().toString());
149: } else if (comboValues.length > 0) {
150: prop.setValue(comboValues[0]);
151: }
152: // }
153: // }
154: // );
155:
156: // }
157: // }
158: // );
159: }
160:
161: private void addSubFolderFragments(DataFolder folder,
162: List formList,
163: /*FacesModelSet modelset,*/DataObject current) {
164: DataObject[] children = folder.getChildren();
165: if (children == null) {
166: return;
167: }
168: for (int i = 0; i < children.length; i++) {
169: if (children[i] instanceof DataFolder) {
170: addSubFolderFragments((DataFolder) children[i],
171: formList, /*modelset,*/current);
172: } else {
173: DataObject d = children[i];
174:
175: if (d == current) {
176: continue;
177: }
178: // See if it's a fragment
179:
180: if (d.getPrimaryFile().getNameExt().endsWith(".jspf")) {
181: String path = computePathFromTo(current, d);
182: formList.add(path);
183: }
184: }
185: }
186: }
187:
188: public static String computePathFromTo(DataObject from,
189: DataObject to) {
190: FileObject fromFile = from.getPrimaryFile();
191: FileObject toFile = to.getPrimaryFile();
192: ArrayList fromPathList = getPathList(fromFile);
193: ArrayList toPathList = getPathList(toFile);
194: int index = 0;
195: // find the first non matching sub dir
196: for (; index < fromPathList.size() && index < toPathList.size(); index++) {
197: if (!fromPathList.get(index).equals(toPathList.get(index))) {
198: break;
199: }
200: }
201: StringBuffer stringBuffer = new StringBuffer();
202: // create a file that goes up to match found
203: for (int i = index; i < fromPathList.size(); i++) {
204: stringBuffer.append("../"); // NOI18N
205: }
206: // create a file that goes down from match found
207: for (int i = index; i < toPathList.size(); i++) {
208: stringBuffer.append(toPathList.get(i));
209: stringBuffer.append("/"); // NOI18N
210: }
211: if (toFile.isData()) {
212: stringBuffer.append(toFile.getNameExt());
213: }
214: return stringBuffer.toString();
215: }
216:
217: public static ArrayList getPathList(FileObject file) {
218: if (!file.isFolder()) {
219: file = file.getParent();
220: }
221: ArrayList result = new ArrayList(4);
222: while (file != null) {
223: result.add(file.getName());
224: file = file.getParent();
225: }
226: Collections.reverse(result);
227: return result;
228: }
229:
230: /** This method is called from within the constructor to
231: * initialize the form.
232: * WARNING: Do NOT modify this code. The content of this method is
233: * always regenerated by the Form Editor.
234: */
235: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
236: private void initComponents() {
237: java.awt.GridBagConstraints gridBagConstraints;
238:
239: jLabel1 = new javax.swing.JLabel();
240: jLabel2 = new javax.swing.JLabel();
241: comboBox = new javax.swing.JComboBox();
242: createButton = new javax.swing.JButton();
243: jPanel1 = new javax.swing.JPanel();
244:
245: setLayout(new java.awt.GridBagLayout());
246:
247: jLabel1.setText(NbBundle.getMessage(FragmentPanel.class,
248: "JspPageDesc")); // NOI18N
249: gridBagConstraints = new java.awt.GridBagConstraints();
250: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
251: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
252: gridBagConstraints.insets = new java.awt.Insets(12, 12, 11, 11);
253: add(jLabel1, gridBagConstraints);
254: java.util.ResourceBundle bundle = java.util.ResourceBundle
255: .getBundle("org/netbeans/modules/visualweb/xhtml/Bundle"); // NOI18N
256: jLabel1.getAccessibleContext().setAccessibleDescription(
257: bundle.getString("PF_LBL_ACCESS_DESC")); // NOI18N
258:
259: jLabel2.setDisplayedMnemonic(java.util.ResourceBundle
260: .getBundle(
261: "org/netbeans/modules/visualweb/xhtml/Bundle")
262: .getString("JspPageMnemonic").charAt(0));
263: jLabel2.setLabelFor(comboBox);
264: jLabel2.setText(NbBundle.getMessage(FragmentPanel.class,
265: "JspPage")); // NOI18N
266: gridBagConstraints = new java.awt.GridBagConstraints();
267: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
268: gridBagConstraints.insets = new java.awt.Insets(0, 12, 11, 6);
269: add(jLabel2, gridBagConstraints);
270:
271: comboBox.setEditable(true);
272: gridBagConstraints = new java.awt.GridBagConstraints();
273: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
274: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
275: gridBagConstraints.insets = new java.awt.Insets(0, 0, 11, 11);
276: add(comboBox, gridBagConstraints);
277: comboBox.getAccessibleContext()
278: .setAccessibleName(
279: org.openide.util.NbBundle.getMessage(
280: FragmentPanel.class,
281: "PF_COMBOBOX_ACCESS_NAME")); // NOI18N
282: comboBox.getAccessibleContext()
283: .setAccessibleDescription(
284: org.openide.util.NbBundle.getMessage(
285: FragmentPanel.class,
286: "PF_COMBOBOX_ACCESS_DESC")); // NOI18N
287:
288: createButton.setMnemonic(org.openide.util.NbBundle.getMessage(
289: FragmentPanel.class, "CREATE_NEW_PF_BUTTON_MNEMONIC")
290: .charAt(0));
291: createButton.setText(NbBundle.getMessage(FragmentPanel.class,
292: "CreateNew")); // NOI18N
293: gridBagConstraints = new java.awt.GridBagConstraints();
294: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
295: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
296: gridBagConstraints.insets = new java.awt.Insets(12, 12, 6, 11);
297: add(createButton, gridBagConstraints);
298: createButton.getAccessibleContext().setAccessibleDescription(
299: org.openide.util.NbBundle.getMessage(
300: FragmentPanel.class,
301: "CREATE_NEW_PF_BUTTON_ACCESS_DESC")); // NOI18N
302:
303: gridBagConstraints = new java.awt.GridBagConstraints();
304: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
305: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
306: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
307: gridBagConstraints.weightx = 1.0;
308: gridBagConstraints.weighty = 1.0;
309: add(jPanel1, gridBagConstraints);
310: }// </editor-fold>//GEN-END:initComponents
311:
312: // Implements ActionListener
313: public void actionPerformed(java.awt.event.ActionEvent e) {
314: if (e.getSource() == createButton) {
315: String name = createPageFragment();
316: if (name != null) {
317: //addComboFragments();
318: comboBox.setSelectedItem(name);
319: prop.setValue(name);
320: // TODO - add to the combo list too?
321: }
322: }
323: }
324:
325: // Implements ItemListener
326: public void itemStateChanged(java.awt.event.ItemEvent e) {
327: prop.setValue(comboBox.getSelectedItem().toString());
328: }
329:
330: /** Create a pagefragment and return its URL string - or null
331: * if creating the webform didn't succeed.
332: */
333: private String createPageFragment() {
334: DataFolder folderObj = null;
335: Project project = getProject();
336: if (project != null) {
337: FileObject webforms = JsfProjectUtils
338: .getDocumentRoot(project);
339: try {
340: folderObj = (DataFolder) DataObject.find(webforms);
341: } catch (DataObjectNotFoundException e) {
342: }
343: }
344: if (prop != null) {
345: // LiveUnit unit = (LiveUnit)prop.getDesignBean().getDesignContext();
346: // if (unit.getBeansUnit() instanceof FacesPageUnit) {
347: // FacesPageUnit fpu = (FacesPageUnit)unit.getBeansUnit();
348: // DataObject dobj = fpu.getPageUnit().getDataObject();
349: FileObject fo = InSyncService.getProvider()
350: .getMarkupFileObjectForDesignContext(
351: prop.getDesignBean().getDesignContext());
352: if (fo != null) {
353: DataObject dobj;
354: try {
355: dobj = DataObject.find(fo);
356: } catch (DataObjectNotFoundException ex) {
357: ErrorManager.getDefault().notify(
358: ErrorManager.INFORMATIONAL, ex);
359: dobj = null;
360: }
361: if (dobj != null) {
362: DataFolder df = dobj.getFolder();
363: if (df != null) {
364: folderObj = df;
365: }
366: }
367: }
368: }
369: String error = null;
370: String name = null;
371: //!CQ This is bad to have this base name buried in the source here... should talk to project some how..
372: FormNamePanel panel = new FormNamePanel(project, "Fragment");
373:
374: String title = NbBundle.getMessage(FragmentPanel.class,
375: "CreateFragment"); // NOI18N
376: DialogDescriptor dlg = new DialogDescriptor(panel, title, true,
377: DialogDescriptor.OK_CANCEL_OPTION,
378: DialogDescriptor.OK_OPTION,
379: DialogDescriptor.DEFAULT_ALIGN, // DialogDescriptor.BOTTOM_ALIGN,
380: null, //new HelpCtx("new_page_fragment"), // NOI18N
381: null);
382:
383: JDialog dialog = (JDialog) DialogDisplayer.getDefault()
384: .createDialog(dlg);
385: dialog.getAccessibleContext().setAccessibleDescription(
386: NbBundle.getMessage(FragmentPanel.class,
387: "CreateFragmentAccessibleDesc")); // NOI18N
388: panel.setDescriptor(dlg);
389: dialog.show();
390: String answer = dlg.getValue().toString();
391: if (!dlg.getValue().equals(DialogDescriptor.OK_OPTION)) {
392: // Cancel, or Esc: do nothing
393: return null;
394: }
395: name = panel.getFragmentName();
396:
397: // Check name - shouldn't be necessary, form should enforce it.
398: boolean validName;
399: validName = JsfProjectUtils.isValidJavaFileName(name);
400: if (!validName) {
401: return null;
402: }
403:
404: // Create files
405: try {
406: FileSystem fs = Repository.getDefault()
407: .getDefaultFileSystem();
408: String tmpl = "Templates/JSF/PageFragment.jspf"; // NOI18N
409: FileObject fo = fs.findResource(tmpl);
410: if (fo == null)
411: throw new IOException(
412: "Can't find template FileObject for " + tmpl); // NOI18N
413: DataObject webformTemplate = DataObject.find(fo);
414: DataObject webform = webformTemplate.createFromTemplate(
415: folderObj, name);
416:
417: // Next, try to access the insync units! This is important for
418: // bug 4960018; the backing file template is empty so we've gotta
419: // force insync to "create" it
420: if (webform != null) {
421: // FacesModelSet modelset = FacesModelSet.getInstance(project);
422: // FacesModel model = modelset.getFacesModel(webform.getPrimaryFile());
423: // if (model == null) {
424: // ErrorManager.getDefault().log(webform + " has no insync Model!");
425: // }
426: InSyncService.getProvider().initModelsForWebformFile(
427: project, webform.getPrimaryFile());
428: }
429:
430: return webform.getPrimaryFile().getNameExt();
431:
432: } catch (Exception ex) {
433: ErrorManager.getDefault().notify(ex);
434: }
435: return null;
436: }
437:
438: // Variables declaration - do not modify//GEN-BEGIN:variables
439: private javax.swing.JComboBox comboBox;
440: private javax.swing.JButton createButton;
441: private javax.swing.JLabel jLabel1;
442: private javax.swing.JLabel jLabel2;
443: private javax.swing.JPanel jPanel1;
444: // End of variables declaration//GEN-END:variables
445: }
|