KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > web > jsf > navigation > vwmodel > NavigationModel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.web.jsf.navigation.vwmodel;
20
21 import org.netbeans.modules.web.jsf.navigation.vwmodel.NavigationModel;
22 import org.netbeans.modules.web.jsf.navigation.*;
23 import org.netbeans.modules.web.jsf.navigation.vwmodel.NavigableComponent;
24 import org.netbeans.modules.web.jsf.navigation.vwmodel.Page;
25 import org.netbeans.modules.visualweb.api.insync.InSyncService;
26 import com.sun.rave.designtime.DesignEvent;
27 import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
28 import java.awt.Image JavaDoc;
29 import java.beans.BeanInfo JavaDoc;
30 import java.net.MalformedURLException JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Collections JavaDoc;
34 import java.util.Comparator JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Map JavaDoc;
39 import javax.faces.component.ActionSource;
40 import javax.faces.component.ActionSource2;
41 import javax.swing.SwingUtilities JavaDoc;
42 import org.openide.ErrorManager;
43 import org.openide.filesystems.FileObject;
44 import org.openide.filesystems.URLMapper;
45 import org.openide.util.NbBundle;
46 //import org.netbeans.modules.visualweb.extension.openide.util.Trace;
47
import org.netbeans.api.project.Project;
48 import org.netbeans.modules.visualweb.project.jsf.api.JsfPortletSupport;
49 import org.netbeans.modules.visualweb.project.jsf.api.JsfPortletSupportException;
50 import org.netbeans.modules.visualweb.api.portlet.dd.PortletModeType;
51 import com.sun.rave.designtime.DesignBean;
52 import com.sun.rave.designtime.DesignProperty;
53 import org.netbeans.modules.visualweb.insync.Model;
54 import org.netbeans.modules.visualweb.insync.ModelSet;
55 import org.netbeans.modules.visualweb.insync.UndoEvent;
56 import org.netbeans.modules.visualweb.insync.faces.HtmlBean;
57 import org.netbeans.modules.visualweb.insync.faces.config.NavigationCase;
58 import org.netbeans.modules.visualweb.insync.faces.config.NavigationRule;
59 import org.netbeans.modules.visualweb.insync.live.MethodBindDesignEvent;
60 import org.netbeans.modules.visualweb.insync.live.MethodBindDesignProperty;
61 import org.netbeans.modules.visualweb.insync.models.ConfigModel;
62 import org.netbeans.modules.visualweb.insync.models.FacesModel;
63 import org.netbeans.modules.visualweb.insync.models.FacesModelSet;
64 import org.netbeans.modules.visualweb.xhtml.FormNamePanel;
65 import java.beans.PropertyChangeListener JavaDoc;
66 import java.beans.PropertyChangeSupport JavaDoc;
67 import java.io.IOException JavaDoc;
68 import javax.swing.JDialog JavaDoc;
69 import org.openide.DialogDescriptor;
70 import org.openide.DialogDisplayer;
71 import org.openide.filesystems.FileSystem;
72 import org.openide.filesystems.Repository;
73 import org.openide.loaders.DataFolder;
74 import org.openide.loaders.DataObject;
75 import org.openide.loaders.DataObjectNotFoundException;
76
77
78 /**
79  * Wrapper object for the navigation document information
80  *
81  * @todo Add locking around insync buffers (reads in getLinks, writes around mutations)
82  */

83 public class NavigationModel extends ConfigModel {
84     
85     //-------------------------------------------------------------------------------------- Statics
86

87     public static class Factory implements Model.Factory {
88         public Model newInstance(ModelSet set, FileObject file) {
89             String JavaDoc nameext = file.getNameExt();
90             return nameext.equals("navigation.xml") ? new NavigationModel(set, file) : null;
91         }
92     }
93     
94     //------------------------------------------------------------------------------------- Instance
95

96     private List JavaDoc<Page> pages;
97     private Map JavaDoc<String JavaDoc,Page> pageMap; // page objects indexed by name
98
private List JavaDoc<Link> links;
99     
100     public Page ERROR_PAGE = new Page(NbBundle.getMessage(NavigationModel.class, "ErrorPage"), (FileObject) null, this);
101     
102     Page currentPage = null;
103     
104     public static final String JavaDoc PAGE = "page";
105     public static final String JavaDoc LINK = "link";
106     
107     private PropertyChangeSupport JavaDoc propertyChangeSupport;
108     
109     public void addPropertyChangeListener(PropertyChangeListener JavaDoc propChangeListener){
110         propertyChangeSupport.addPropertyChangeListener(propChangeListener);
111     }
112     
113     public void removePropertyChangeListener(PropertyChangeListener JavaDoc propChangeListener){
114         propertyChangeSupport.removePropertyChangeListener(propChangeListener);
115     }
116     
117     public NavigationModel(ModelSet owner, FileObject file) {
118         super(owner, file);
119         propertyChangeSupport = new PropertyChangeSupport JavaDoc(this);
120     }
121     
122     public boolean isCurrentPage(Page page){
123         return page == getCurrentPage();
124     }
125     
126     public Page getCurrentPage(){
127         if (currentPage == null){
128             List JavaDoc<Page> pages = getPages();
129             if (!pages.isEmpty()){
130                 return pages.get(0);
131             }
132         }
133         return currentPage;
134     }
135     
136     public void setCurrentPage(Page page){
137         currentPage = page;
138     }
139     
140     public void moveCurrentPage(){
141         List JavaDoc<Page> pages = getPages();
142         int currIndex = pages.indexOf(getCurrentPage());
143         currIndex++;
144         if(currIndex >= pages.size()){
145             currIndex = 0;
146         }
147         currentPage = pages.get(currIndex);
148     }
149     
150     boolean isPortletProject() {
151         Project project = getProject();
152         if (project != null && JsfProjectUtils.getPortletSupport(project) != null) {
153             return true;
154         }
155         return false;
156     }
157     
158     
159     /**
160      * Computes the page name
161      */

162     String JavaDoc getPageName(Project project, FileObject jspFile) {
163         if (jspFile == null || project == null)
164             return null;
165         FileObject webRoot = JsfProjectUtils.getDocumentRoot(project);
166         String JavaDoc jspPath = jspFile.getParent().getPath();
167         jspPath = jspPath.substring(webRoot.getPath().length());
168         if(jspPath.startsWith("/")) //NOI18N
169
jspPath = jspPath.substring(1);
170         if (jspPath.length() > 0)
171             jspPath += "/"; // NOI18N
172
jspPath += jspFile.getNameExt();
173         return jspPath;
174     }
175     
176     
177     /**
178      * Never returns null
179      */

180     
181     public List JavaDoc<Page> getPages() {
182         if (pages != null)
183             return pages;
184         
185         pages = new ArrayList JavaDoc<Page>();
186         pageMap = new HashMap JavaDoc<String JavaDoc,Page>();
187         
188 // List list = DesignerService.getDefault().getWebPages(getProject(), true, false);
189
List JavaDoc list = InSyncService.getProvider().getWebPages(getProject(), true, false);
190         Iterator JavaDoc it = list.iterator();
191         while (it.hasNext()) {
192             FileObject fo = (FileObject)it.next();
193             String JavaDoc name = getPageName(getProject(), fo);
194             Page page = new Page(name, fo, this);
195             pages.add(page);
196             pageMap.put(name, page);
197         }
198         
199         // This should put pages in alpha order to be shown in navigation editor in that order
200
Collections.sort(pages, new Comparator JavaDoc() {
201             public int compare(Object JavaDoc object1, Object JavaDoc object2) {
202                 return ((Page) object1).getName().compareTo(((Page) object2).getName());
203             }
204         });
205         
206         // Ensure that links are initialized too
207
getLinks();
208         
209         return pages;
210     }
211     
212     /**
213      * Never returns null
214      */

215     public List JavaDoc<Link> getLinks() {
216         // XXX TODO: grab insync readlock!
217
if (links != null) {
218             return links;
219         }
220         if (pages == null) {
221             // initialize page list
222
getPages();
223         }
224         links = new ArrayList JavaDoc<Link>();
225         
226         // Clear out incident lists
227
for( Page page : pages) {
228 // Page p = (Page)pages.get(i);
229
page.pointedTo = null;
230             page.pointsTo = null;
231         }
232         
233         if(ERROR_PAGE != null) {
234             ERROR_PAGE.pointedTo = null;
235             ERROR_PAGE.pointsTo = null;
236         }
237         
238         NavigationRule[] navRules = unit.getRules();
239         for( NavigationRule navRule : navRules) {
240             
241             String JavaDoc from = navRule.getFromView();
242             // Strip out leading /
243
if ((from != null) && from.startsWith("/")) { // NOI18N
244
from = from.substring(1);
245             }
246             
247             NavigationCase[] navCases = navRule.getCases();
248             for( NavigationCase navCase : navCases ) {
249                 String JavaDoc to = navCase.getToView();
250                 String JavaDoc outcome = navCase.getFromOutcome();
251                 
252 // assert Trace.trace("nav.events", "Found new rule: ");
253
// assert Trace.trace("nav.events", " from=" + from);
254
// assert Trace.trace("nav.events", " outcome=" + outcome);
255
// assert Trace.trace("nav.events", " to=" + to);
256

257                 // Strip out leading /
258
if (to.startsWith("/")) { // NOI18N
259
to = to.substring(1);
260                 }
261                 
262                 if (from == null && to == null) {
263                     ErrorManager.getDefault().log("Skipping navigation rule " + navRule+ " case " + navCase + " because both from and to are null");
264                     continue;
265                 }
266                 
267                 // Add to links
268
Page fromPage = null;
269                 if (from != null) {
270                     fromPage = pageMap.get(from);
271                 }
272                 Page toPage = null;
273                 if (to != null) {
274                     toPage = pageMap.get(to);
275                 }
276                 
277                 if (fromPage == null && toPage == null) {
278                     ErrorManager.getDefault().log("Skipping navigation rule " + navRule + " case " + navCase + " because both from and to are null");
279                     continue;
280                 }
281                 if (fromPage == null) {
282                     fromPage = ERROR_PAGE;
283                 } else if (toPage == null) {
284                     toPage = ERROR_PAGE;
285                 }
286                 
287                 Link link = new Link(outcome, fromPage, toPage, navCase);
288                 links.add(link);
289                 
290                 // Compute incidents
291
if (fromPage.pointsTo == null) {
292                     fromPage.pointsTo = new ArrayList JavaDoc(3);
293                 }
294                 fromPage.pointsTo.add(toPage);
295                 
296                 if (toPage.pointedTo == null) {
297                     toPage.pointedTo = new ArrayList JavaDoc(3);
298                 }
299                 toPage.pointedTo.add(fromPage);
300                 
301                 //assert Trace.trace("nav.events", "Computing link [" + from +","+to+","+outcome+": fromPAge="+ fromPage + ", toPage=" + toPage);
302
}
303         }
304         
305         return links;
306     }
307     
308     protected void handleDomChanged() {
309         if (!SwingUtilities.isEventDispatchThread()) {
310             SwingUtilities.invokeLater(new Runnable JavaDoc() {
311                 public void run() {
312                     handleDomChanged(); // " recurse"
313
}
314             }
315             );
316             return;
317         }
318         
319         // force layout
320
links = null;
321         //pages = null; NO! Pages are tied to project manager, not DOM!
322
//pageMap = null;
323

324         // XXX Hack
325
update();
326     }
327     
328     protected void handleModelChanged(final Model m) {
329         if (!SwingUtilities.isEventDispatchThread()) {
330             SwingUtilities.invokeLater(new Runnable JavaDoc() {
331                 public void run() {
332                     handleModelChanged(m); // " recurse"
333
}
334             }
335             );
336             return;
337         }
338         
339         update();
340         
341     }
342     
343     protected void handleProjectChanged() {
344         // XXX look for many events?
345

346         // Ensure that we do this on the dispatch thread so we
347
// don't cause problems for the painting thread which is
348
// reading out of the pages data structure
349
if (!SwingUtilities.isEventDispatchThread()) {
350             SwingUtilities.invokeLater(new Runnable JavaDoc() {
351                 public void run() {
352                     handleProjectChanged(); // " recurse"
353
}
354             }
355             );
356             return;
357         }
358         pages = null;
359         pageMap = null;
360         // Should redo links too
361
flush();
362         handleDomChanged();
363     }
364     
365     public void update(){
366         if ((propertyChangeSupport != null) && (propertyChangeSupport.getPropertyChangeListeners().length > 0)){
367             List JavaDoc<Page> pages = getPages();
368             for( Page page: pages ) {
369                 updateBeans(page);
370             }
371             List JavaDoc links = getLinks();
372             propertyChangeSupport.firePropertyChange(PAGE, null, pages);
373             propertyChangeSupport.firePropertyChange(LINK, null, links);
374         }
375     }
376     
377     
378 // /**
379
// * Called when a set of items in the project have been renamed.
380
// */
381
// protected void handleProjectItemsRenamed(GenericItem[] items, String[] oldNames) {
382
// // subclasses can do something more clever, just don't call
383
// // super too!
384
// assert items != null && oldNames != null && items.length == oldNames.length;
385
//
386
// for (int f = 0; f < items.length; f++) {
387
// // Replace all references in the config dom
388
//
389
// DataObject d = items[f].getDataObject();
390
// if (!WebAppProject.isWebPage(d)) {
391
// continue;
392
// }
393
// String newName = d.getPrimaryFile().getNameExt();
394
// String oldName = oldNames[f];
395
//
396
// NavigationRule[] rules = unit.getRules();
397
// for (int i = 0; i < rules.length; i++) {
398
//
399
// String from = rules[i].getFromView();
400
// // Strip out leading /
401
// if (from.startsWith("/")) { // NOI18N
402
// from = from.substring(1);
403
// }
404
// if (from != null && from.equals(oldName)) {
405
// rules[i].setFromView(newName);
406
// }
407
//
408
// NavigationCase[] cases = rules[i].getCases();
409
// for (int j = 0; j < cases.length; j++) {
410
// String to = cases[j].getToView();
411
// // Strip out leading /
412
// if (to.startsWith("/")) { // NOI18N
413
// to = to.substring(1);
414
// }
415
// if (to != null && to.equals(oldName)) {
416
// cases[j].setToView(newName);
417
// }
418
// }
419
// }
420
// }
421
// handleProjectChanged();
422
// }
423

424     
425     public boolean updateBeans(Page p) {
426         return updateBeans(p, true);
427     }
428     
429     public boolean removeNavigableComponent( NavigableComponent navComp) {
430         DesignBean bean = navComp.getBean();
431 // assert Trace.trace("nave.events", "Command beans=" + bean);
432
List JavaDoc<DesignBean> zoomedBeans = new ArrayList JavaDoc<DesignBean>();
433         if( bean != null ){
434             return bean.getDesignContext().deleteBean(bean);
435         }
436         return false;
437     }
438     
439     /** Some reason it looks like updateBeans is called twice when a component is added. Is this good?
440      * Initialize the given page by looking up its insync information, and update the page beans
441      * list. Perform initial layout of positions on that page.
442      *
443      * @return true if succeeded, false if there's an error
444      */

445     public boolean updateBeans(Page p, boolean redraw) {
446         // Wrapper which handles errors
447
FacesModel model = p.getModel();
448 // assert Trace.trace("nav.events", "model=" + model);
449
//model.sync();
450
if (model != null && !model.isBusted()) {
451             DesignBean container = model.getRootBean();
452 // assert Trace.trace("nav.events", "Container = " + container);
453
List JavaDoc<DesignBean> zoomedBeans = new ArrayList JavaDoc<DesignBean>();
454             if (container != null) {
455                 findCommandBeans(model, container, zoomedBeans, true);
456 // assert Trace.trace("nav.events", "Command beans=" + zoomedBeans);
457
} else {
458 // assert Trace.trace("nav.events", "No container!");
459
}
460             p.setBeans(new ArrayList JavaDoc());
461             // Create page beans structure
462
for( DesignBean bean : zoomedBeans ) {
463                 String JavaDoc name = bean.getInstanceName();
464                 
465                 /* designContextName may reveal a sub-page or fragement*/
466                 String JavaDoc designContextName = bean.getDesignContext().getDisplayName();
467                 
468                 /* If the page name does not match the designContext page name, then prepend it to the NavigableComponent name. */
469                 String JavaDoc pageName = p.getName();
470                 int lastIndex = pageName.lastIndexOf('.');
471                 if( !pageName.substring(0,lastIndex).equals(designContextName)) {
472                     name = designContextName + ":" + name;
473                 }
474                 
475                 BeanInfo JavaDoc bi = bean.getBeanInfo();
476                 // XXX Find a way to cache the image icon (repaint of icon slow)
477
Image JavaDoc icon = bi != null ? bi.getIcon(BeanInfo.ICON_COLOR_16x16) : null;
478                 if (icon == null) {
479                     // use backup image
480
icon = GraphUtilities.getCommandIcon();
481                 }
482                 String JavaDoc javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
483                 DesignProperty pr;
484                 if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
485                     pr = bean.getProperty("actionExpression"); // NOI18N
486
}else{
487                     pr = bean.getProperty("action"); // NOI18N
488
}
489                 
490                 String JavaDoc action = pr != null ? pr.getValueSource() : "Unknown"; // NOI18N
491
Object JavaDoc actionO = pr != null ? pr.getValue() : null;
492                 
493                 /* TODO: support actionRefs !CQ MethodBinding
494                 if (action == null || action.length() == 0) {
495                     // See if we have an action ref, and if so visually
496                     // indicate that this component binds to a page
497                     // that is decided on the fly / dynamically
498                     //!CQ this will need to be integrated with the above since all actions are now refs
499                 }
500                  */

501                 
502                 NavigableComponent b = new NavigableComponent(bean, action, p, name, icon);
503                 if (action != null && action.startsWith("#{")) { // Looks like value binding: dynamic navigation.
504
b.dynamic = true;
505                     if (pr instanceof MethodBindDesignProperty) {
506                         MethodBindDesignProperty mpr = (MethodBindDesignProperty)pr;
507                         MethodBindDesignEvent mev = mpr.getEventReference();
508                         if (mev != null) {
509                             Object JavaDoc ret = mev.getHandlerMethodReturn();
510                             if (ret instanceof String JavaDoc) {
511                                 b.setAction((String JavaDoc)ret);
512                                 //b.dynamic = false; //!CQ TODO: show both icon & link
513
}
514                         }
515                     }
516                 }
517                 p.getBeans().add(b);
518             }
519             return true;
520         } else {
521             return false;
522             // TODO: add some kind of error badge to the GUI
523
}
524     }
525     
526     private static FacesModel getFragmentModel(FacesModel model, DesignBean fragment) {
527         
528         DesignProperty prop = fragment.getProperty("file"); // NOI18N
529
if( prop == null ){
530             return null;
531         }
532         Object JavaDoc fileO = prop.getValue();
533         if (!(fileO instanceof String JavaDoc)) {
534             return null;
535         }
536         String JavaDoc file = (String JavaDoc)fileO;
537         if ((file == null) || (file.length() == 0)) {
538             return null;
539         }
540         URL JavaDoc reference = model.getMarkupUnit().getBase();
541         URL JavaDoc url = null;
542         try {
543             url = new URL JavaDoc(reference, file); // XXX what if it's absolute?
544
if (url == null) {
545                 return null;
546             }
547         } catch (MalformedURLException JavaDoc e) {
548             ErrorManager.getDefault().notify(e);
549             return null;
550         }
551         
552         Project project = model.getProject();
553         FacesModelSet models = FacesModelSet.getInstance(project);
554         if (models == null) {
555             return null;
556         }
557         FileObject fo = URLMapper.findFileObject(url);
558         if (fo != null) {
559             FacesModel fragmentModel = models.getFacesModel(fo);
560             if (fragmentModel != null) {
561                 return fragmentModel;
562             }
563         }
564         return null;
565     }
566     
567     /**
568      * Recursively locate all UICommand beans and add them to the given list
569      */

570     private static void findCommandBeans(FacesModel model, DesignBean container, List JavaDoc<DesignBean> beans,
571             boolean includeFragments) {
572         if(container == null)
573             return;
574         
575         
576         for ( DesignBean designBean : container.getChildBeans()) {
577             
578             // To be more general, check if instance of ActionSource and ActionSource2 instead of UICommand.
579
// Check if it extends actionsSource and/or is hidden. Don't add otherwise.
580
if( designBean.getInstance() instanceof ActionSource || designBean.getInstance() instanceof ActionSource2 ) {
581                 /**** HACK, HACK, HACK *****
582                  * DropDown is an instance of ActionSource but does not completely define the ActionSource interface.
583                  * Unfortunatley there is not enough time to redo this component, so we are having to put a hack into
584                  * navigator. I hate doing this. -Joelle
585                  */

586                 if (designBean.getInstance().getClass().getName().equals("com.sun.rave.web.ui.component.DropDown")
587                 || (designBean.getInstance().getClass().getName().equals("com.sun.webui.jsf.component.DropDown"))){
588                     continue;
589                 }
590                 beans.add(designBean);
591             }
592             String JavaDoc className = designBean.getInstance() != null ?
593                 designBean.getInstance().getClass().getName() : "";
594             if (includeFragments && className.equals(HtmlBean.PACKAGE+"Jsp_Directive_Include")) { // NOI18N
595
// directive include -- look for referenced beans too in the fragment
596
FacesModel fragmentModel = getFragmentModel(model, designBean);
597                 if (fragmentModel != null) {
598                     findCommandBeans(fragmentModel, fragmentModel.getRootBean(), beans, true);
599                 }
600             } else if (designBean.isContainer()) {
601                 findCommandBeans(model, designBean, beans, includeFragments);
602             }
603         }
604     }
605     
606     /**
607      * Add a navigation link from page "from" to page "to"
608      */

609     public boolean setOutcomeNoLayout(Link link, String JavaDoc outcome, DesignProperty addLinkTo, boolean rename) {
610         String JavaDoc oldOutcome = link.getOutcome();
611         assert oldOutcome.equals(link.getNavcase().getFromOutcome());
612         String JavaDoc javaeePlatform = null;
613         
614         if (outcome.length() > 0) {
615             link.getNavcase().setFromOutcome(outcome);
616             link.setOutcome(outcome);
617             unit.flush();
618             
619             // Are there any beans on the page referring to that
620
// action? If so, update their action handlers too!
621
if (link.getFrom().getBeans() == null && link.getFrom() != ERROR_PAGE) {
622                 boolean r = updateBeans(link.getFrom());
623             }
624             if (link.getFrom().getBeans() != null && link.getFrom() != ERROR_PAGE) {
625                 UndoEvent undo = null;
626                 try {
627                     undo = link.getFrom().model.writeLock(null); //!CQ TODO: nice description
628
for( NavigableComponent bean : link.getFrom().getBeans() ) {
629                         if (bean.getBean() != null) {
630                             DesignProperty pr = getActionProperty(link, bean);
631                             if (pr != null) {
632                                 // dom't check equals if oldOutcome is null.
633
boolean setValueSource = (oldOutcome != null && oldOutcome.equals(pr.getValueSource()));
634                                 if (pr instanceof MethodBindDesignProperty) {
635                                     MethodBindDesignProperty mpr = (MethodBindDesignProperty) pr;
636                                     MethodBindDesignEvent mev = mpr.getEventReference();
637                                     if (mev != null) {
638                                         boolean modify = false;
639                                         // If rename, set the value of all the beans action property to new outcome,
640
// if the action property has current value equal to outcome
641
if(rename){
642                                             if((oldOutcome != null) && oldOutcome.equals(mev.getHandlerMethodReturn())){
643                                                 modify = true;
644                                             }
645                                         }else{ // Modify only the current bean
646
if (addLinkTo == pr) {
647                                                 modify = true;
648                                             }
649                                         }
650                                         if (modify){
651                                             if (mev.getHandlerName() == null) {
652                                                 setValueSource = true;
653                                             } else {
654 // System.out.println("((StringLiteral)mev.getHandlerMethodReturn();
655
//When link is created for the first time,
656
//oldOutcome and outcome are same
657
//But what if a link was never there and there is already an assigned return case
658
if(oldOutcome.equals(outcome)) {
659                                                     if (mev.getHandlerMethodReturn() != null ){
660                                                         oldOutcome = mev.getHandlerMethodReturn().toString();
661                                                     } else {
662                                                         oldOutcome = null;
663                                                     }
664                                                 }
665                                                 mev.updateReturnStrings(oldOutcome, outcome);
666                                                 setValueSource = false;
667                                             }
668                                         }
669                                     }
670                                 }
671                                 if (setValueSource) {
672                                     pr.setValueSource(outcome);
673                                 }
674                             }
675                         }
676                     }
677                 }finally {
678                     // XXX - some time returns null not sure why!!
679
if(link.getFrom().model != null){
680                         link.getFrom().model.writeUnlock(undo);
681                     }else{
682                         System.out.println("Insync model of the from page retunred null - Needs fix");
683                     }
684                     addLinkTo = null;
685                 }
686             }
687             return true;
688         }
689         return false;
690     }
691     
692     private DesignProperty getActionProperty(Link link, NavigableComponent bean) {
693         String JavaDoc javaeePlatform;
694         javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
695         DesignProperty pr;
696         if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
697             pr = bean.getBean().getProperty("actionExpression"); // NOI18N
698
if(pr!= null ){
699                 DesignEvent event = link.getFrom().model.getDefaultEvent(pr.getDesignBean());
700                 if (event != null) {
701                     link.getFrom().model.createEventHandler(event);
702                 }
703             }
704         }else{
705             pr = bean.getBean().getProperty("action"); // NOI18N
706
}
707         return pr;
708     }
709     
710     /**
711      * Add a navigation link from page "from" to page "to"
712      */

713     public void setOutcome(Link link, String JavaDoc outcome, boolean rename) {
714         DesignProperty addLinkTo = null;
715         NavigableComponent pb = link.getFrom().getCurrentBean();
716         if(pb != null && pb.getBean() != null) {
717             String JavaDoc javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
718             if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
719                 addLinkTo = pb.getBean().getProperty("actionExpression"); // NOI18N
720
}else{
721                 addLinkTo = pb.getBean().getProperty("action"); // NOI18N
722
}
723         }
724         if (setOutcomeNoLayout(link, outcome, addLinkTo, rename)) {
725             update();
726         }
727     }
728     
729     public void fileRenamed(String JavaDoc oldName, String JavaDoc newName, String JavaDoc ext, FileObject fo, boolean remove) {
730 // Page pageMatch = null;
731
// List<Link> links = this.getLinks();
732
// for(Link link : links){
733
// if (file != null ){
734
// Page page = link.getToPage();
735
// DataObject dOPage = page.getDataObject();
736
// try {
737
// if( DataObject.find(file).equals(dOPage)) {
738
// link.setToPage(page);
739
// pageMatch = page;
740
// }
741
// } catch (DataObjectNotFoundException ex) {
742
// ex.printStackTrace();
743
// }
744
// }
745
// }
746
// if( pageMatch != null ){
747
// pageMatch.setName(newName);
748
// }
749
//
750
//
751
//If the file is marked non sharable, delete the model
752
if(remove && file == fo){
753             getOwner().removeModel(this);
754         } else {
755             handleProjectChanged();
756         }
757     }
758     
759     /**
760      * Find a rule originating from this page, if any. If non is found, create a new one.
761      */

762     private NavigationRule findRule(Page from) {
763 // NavigationRule[] rules = unit.getRules();
764
for( NavigationRule rule : unit.getRules() ) {
765             if ((rule != null) && (rule.getFromView() != null) && rule.getFromView().equals(from.getName()))
766                 return rule;
767         }
768         NavigationRule rule = unit.addRule();
769         rule.setFromView(from.getName());
770         return rule;
771     }
772     
773     /**
774      * Pick a default "outcome" name
775      */

776     String JavaDoc getDefaultName(Page from) {
777         String JavaDoc basename = "case";
778         int num = 1;
779         while (true) {
780             String JavaDoc name = basename + Integer.toString(num);
781             boolean used = false;
782             // The user can add multiple nav rules for the same
783
// page so we can't just check a single NavigationRule for
784
// a NavigationCase matching this name, we have to check all nav rules
785
NavigationRule[] navRules = unit.getRules();
786             for ( NavigationRule navRule: navRules ) {
787                 if (!from.getName().equals(navRule.getFromView())) {
788                     // Only care about rules for the same origin page
789
continue;
790                 }
791                 NavigationCase[] navCases = navRule.getCases();
792                 for( NavigationCase navCase : navCases ) {
793                     if (navCase.getFromOutcome() != null && navCase.getFromOutcome().equals(name)) {
794                         used = true;
795                         break;
796                     }
797                 }
798                 if (used)
799                     break;
800             }
801             
802             // See if that name is already used
803
if (!used) {
804                 return name;
805             }
806             num++;
807         }
808     }
809     
810     /**
811      * Add a navigation link from page "from" to page "to". If a NavigableComponent is passed in, the link is
812      * from the bean itself on the page to the link.
813      */

814     public Link addLink(Page from, Page to, NavigableComponent pbean) {
815         Link link = null;
816         try {
817             ignoreEvents = true;
818             
819             String JavaDoc outcome = getDefaultName(from);
820             NavigationRule rule = findRule(from);
821             NavigationCase navcase = rule.addCase();
822             navcase.setToView(to.getName());
823             navcase.setFromOutcome(outcome);
824             
825             link = new Link(outcome, from, to, navcase);
826             links.add(link);
827             
828             // Compute incidents
829
if (from.pointsTo == null) {
830                 from.pointsTo = new ArrayList JavaDoc(3);
831             }
832             from.pointsTo.add(to);
833             
834             if (to.pointedTo == null) {
835                 to.pointedTo = new ArrayList JavaDoc(3);
836             }
837             to.pointedTo.add(from);
838             
839             // Bind the bean to the port too, if applicable
840
if (pbean != null) {
841                 assignLink(pbean, link);
842             }else{
843                 update();
844             }
845         } finally {
846             ignoreEvents = false;
847             
848             
849             unit.flush();
850         }
851         return link;
852     }
853     
854     public void assignLink(NavigableComponent pageBean, Link port) {
855         // assert: check that pbean lives within port.from
856
// EAT: delay the adding of the link until the edit on the case is done
857
// Can't add link yet, it introduces some focus issues
858
// Link completion occurs in setOutcome
859
if(pageBean != null){
860             DesignProperty addLinkTo;
861             String JavaDoc javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
862             if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
863                 addLinkTo = pageBean.getBean().getProperty("actionExpression");
864             }else{
865                 addLinkTo = pageBean.getBean().getProperty("action");
866             }
867             setOutcomeNoLayout(port, port.getOutcome(), addLinkTo, false);
868         }
869         update();
870     }
871     
872     /**
873      * Remove the given link.
874      */

875     public Link removeLink(Link link) {
876         try {
877             ignoreEvents = true;
878             
879             NavigationRule rule = link.getNavcase().getRule();
880             rule.removeCase(link.getNavcase());
881             
882             // Get rid of empty rules too
883
NavigationCase[] cases = rule.getCases();
884             if (cases.length == 0)
885                 unit.removeRule(rule);
886             
887             links = null;
888             
889             link.getTo().pointedTo.remove(link.getFrom());
890             link.getFrom().pointsTo.remove(link.getTo());
891             
892             // Gotta do this even though we're clearing out the link list,
893
// since the PAGES aren't recreated and via the bean list,
894
// there might be link references.
895
link.getFrom().setBeanLinks(null);
896             // XXX make it smarter? Might not get recreated now, gotta
897
// clean up the relayout logic
898

899             // Clear out any references to this case on the page
900
// It might still be referenced from a method (hooked up via
901
// actionRef) but we can't really do anything about that.
902

903             if (link.getFrom() != ERROR_PAGE && link.getFrom().model == null) {
904                 // Wrapper which handles errors
905
FacesModel model = ((FacesModelSet)owner).getFacesModel(link.getFrom().getDobj().getPrimaryFile());
906                 if (model == null) {
907                     ErrorManager.getDefault().log("Data object " + link.getFrom().getDobj() + " ain't got no insync Model!");
908                     return link;
909                 }
910                 link.getFrom().model = model;
911                 link.getFrom().wasModelBusted = model.isBusted();
912             }
913             
914             //!CQ: link.from.model.sync();
915
if ((link != null) && (link.getFrom() != null) && (link.getFrom().model != null) && !link.getFrom().model.isBusted()) {
916                 DesignBean container = link.getFrom().model.getRootBean();
917                 List JavaDoc<DesignBean> beans = new ArrayList JavaDoc<DesignBean>();
918                 // Don't delete actions in fragments -- other pages may still have a valid link
919
// TODO -- should we check that?? We have the other models around.... probably
920
// would help the user........
921
findCommandBeans(link.getFrom().model, container, beans, false);
922                 UndoEvent undo = null;
923                 try {
924                     undo = link.getFrom().model.writeLock(null); //!CQ TODO: nice description
925
for( DesignBean designBean : beans ) {
926                         DesignProperty pr = null;
927                         String JavaDoc javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
928                         if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
929                             pr = designBean.getProperty("actionExpression");
930                         }else{
931                             pr = designBean.getProperty("action");
932                         }
933 // DesignProperty pr = designBean.getProperty("action"); // NOI18N
934
if (pr != null && link.getOutcome().equals(pr.getValueSource())) {
935                             // Yes, this action bound to this port
936
pr.unset(); // means "reset" despite the name
937
}
938                         //update the java source
939
if (pr instanceof MethodBindDesignProperty) {
940                             MethodBindDesignProperty mpr = (MethodBindDesignProperty) pr;
941                             MethodBindDesignEvent mev = mpr.getEventReference();
942                             if (mev != null && mev.getHandlerName() != null) {
943                                 mev.updateReturnStrings(link.getOutcome(), null);
944                             }
945                         }
946                     }
947                 } finally {
948                     link.getFrom().model.writeUnlock(undo);
949                 }
950             }
951         } finally {
952             ignoreEvents = false;
953             
954             update();
955             
956             unit.flush(); // flush this nav model
957
}
958         return link;
959     }
960     
961     public void removePage(Page page) {
962         // Find and delete backing file too!
963
Project project = getProject();
964         if (project != null) {
965             FileObject backingFile = FacesModel.getJavaForJsp(page.getDobj().getPrimaryFile());
966             if (backingFile != null) {
967                 /**
968                  * Defect Fix: CR 6341053
969                  * If the project is a portlet project, we need to adjust the initial page info in the
970                  * portlet.xml if the page being deleted is an initial page.
971                  * -David Botterill 10/31/2005
972                  */

973                 FileObject jspPage = page.getDobj().getPrimaryFile();
974                 if(null != jspPage) {
975                     JsfPortletSupport portletSupport = JsfProjectUtils.getPortletSupport(project);
976                     if(null != portletSupport) {
977                         try {
978                             PortletModeType mode = portletSupport.getPortletMode(jspPage);
979                             if(null != mode) {
980                                 portletSupport.unsetInitialPage(jspPage);
981                             }
982                         }catch(JsfPortletSupportException jspse) {
983                             ErrorManager.getDefault().notify(jspse);
984                         }
985                     }
986                 }
987                 try {
988                     DataObject backingObj = DataObject.find(backingFile);
989                     if (backingObj != null && backingObj.isValid()) {
990                         try {
991                             backingObj.delete();
992                         } catch (IOException JavaDoc ex) {
993                             ErrorManager.getDefault().notify(ex);
994                         }
995                     }
996                 } catch(DataObjectNotFoundException dnfe) {
997                     ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, dnfe);
998                 }
999             }
1000        }
1001        
1002        if (page.getDobj().isValid()) {
1003            try {
1004                page.getDobj().delete();
1005            } catch (IOException JavaDoc ex) {
1006                ErrorManager.getDefault().notify(ex);
1007            }
1008        }
1009        update();
1010        
1011    }
1012    
1013    /* Creates a webpage by prompting the user for a page name
1014     * @return <code>Page</code> that was created or <code>null</code> if no page was created
1015     */

1016    public Page createWebPage() {
1017        Project project = getProject();
1018        if (project == null) {
1019            return null;
1020        }
1021        
1022        FileObject folder = getWebFolder();
1023        DataFolder folderObj = null;
1024        try {
1025            folderObj = (DataFolder)DataObject.find(folder);
1026        } catch (DataObjectNotFoundException e) {
1027        }
1028        
1029        String JavaDoc error = null;
1030        
1031        String JavaDoc name = null;
1032        //!CQ This is bad to have this base name buried in the source here... should talk to project some how..
1033
FormNamePanel panel = new FormNamePanel(project, isPortletProject() ? "PortletPage" : "Page");
1034        
1035        String JavaDoc title = NbBundle.getMessage(GraphUtilities.class, "NewFormTitle"); // NOI18N
1036
DialogDescriptor dlg = new DialogDescriptor(
1037                panel,
1038                title,
1039                true,
1040                DialogDescriptor.OK_CANCEL_OPTION,
1041                DialogDescriptor.OK_OPTION,
1042                DialogDescriptor.DEFAULT_ALIGN, // DialogDescriptor.BOTTOM_ALIGN,
1043
null, //new HelpCtx("new_web_form"), // NOI18N
1044
null);
1045        
1046        JDialog JavaDoc dialog = (JDialog JavaDoc) DialogDisplayer.getDefault().createDialog(dlg);
1047        dialog.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GraphUtilities.class, "NewFormTitleAcessDesc"));
1048        panel.setDescriptor(dlg);
1049        dialog.show();
1050        String JavaDoc answer = dlg.getValue().toString();
1051        if (!dlg.getValue().equals(DialogDescriptor.OK_OPTION)) {
1052            // Cancel, or Esc: do nothing
1053
return null;
1054        }
1055        
1056        name = panel.getName();
1057        
1058        // Create files
1059
try {
1060            
1061            String JavaDoc javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
1062            FileSystem fs = Repository.getDefault().getDefaultFileSystem();
1063            String JavaDoc tmpl;
1064            if (isPortletProject()) {
1065                tmpl = "Templates/JsfPortlet/PortletPage.jsp";
1066            } else {
1067                if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
1068                    tmpl = "Templates/JsfApps/Page12.jsp"; // NOI18N
1069
}else{
1070                    tmpl = "Templates/JsfApps/Page.jsp"; // NOI18N
1071
}
1072            }
1073            FileObject fo = fs.findResource(tmpl);
1074            if (fo == null)
1075                throw new IOException JavaDoc("Can't find template FileObject for " + tmpl); // NOI18N
1076
DataObject webformTemplate = DataObject.find(fo);
1077            DataObject webform = webformTemplate.createFromTemplate(folderObj, name);
1078            
1079            // Next, try to access the insync units! This is important for
1080
// bug 4960018; the backing file template is empty so we've gotta
1081
// force insync to "create" it
1082
if (webform != null) {
1083// // XXX FIXME, why project itself doesn't recognize new file was created, and create the item, so
1084
// // it is shown in the project view, etc.
1085
// // Without this next line the files are there, but ignored by project.
1086
// com.sun.rave.project.model.GenericItem.findItem(webform);
1087

1088                FacesModel model = ((FacesModelSet)getOwner()).getFacesModel(webform.getPrimaryFile());
1089                if (model == null)
1090                    ErrorManager.getDefault().log(webform + " has no insync Model!");
1091            }
1092            Page page = new Page(name, webform.getPrimaryFile(), this);
1093            return page;
1094            
1095        } catch (Exception JavaDoc ex) {
1096            ErrorManager.getDefault().notify(ex);
1097        }
1098        return null;
1099    }
1100    
1101    public NavigableComponent addPageBean(Page page, int type) {
1102        DesignBean designBean = addComponent("createComponent", page, page.getBeanClassName(type));
1103        
1104        NavigableComponent navComp = solveNavComponent(page, designBean);
1105        
1106        //Is this still needed?
1107
update();
1108        
1109        return navComp;
1110    }
1111    
1112    private NavigableComponent solveNavComponent(Page page, DesignBean designBean){
1113        if( designBean == null || page == null ) {
1114            return null;
1115        }
1116        
1117        //To figure out navigable component.
1118
String JavaDoc name = designBean.getInstanceName();
1119        
1120        /* designContextName may reveal a sub-page or fragement*/
1121        String JavaDoc designContextName = designBean.getDesignContext().getDisplayName();
1122        
1123        /* If the page name does not match the designContext page name, then prepend it to the NavigableComponent name. */
1124        String JavaDoc pageName = page.getName();
1125        int lastIndex = pageName.lastIndexOf('.');
1126        if( !pageName.substring(0,lastIndex).equals(designContextName)) {
1127            name = designContextName + ":" + name;
1128        }
1129        
1130        BeanInfo JavaDoc bi = designBean.getBeanInfo();
1131        // XXX Find a way to cache the image icon (repaint of icon slow)
1132
Image JavaDoc icon = bi != null ? bi.getIcon(BeanInfo.ICON_COLOR_16x16) : null;
1133        if (icon == null) {
1134            // use backup image
1135
icon = GraphUtilities.getCommandIcon();
1136        }
1137        String JavaDoc javaeePlatform = JsfProjectUtils.getJ2eePlatformVersion(getProject());
1138        DesignProperty pr;
1139        if ((javaeePlatform != null) && JsfProjectUtils.JAVA_EE_5.equals(javaeePlatform)){
1140            pr = designBean.getProperty("actionExpression"); // NOI18N
1141
}else{
1142            pr = designBean.getProperty("action"); // NOI18N
1143
}
1144        
1145        String JavaDoc action = pr != null ? pr.getValueSource() : "Unknown"; // NOI18N
1146

1147        NavigableComponent navComp = new NavigableComponent(designBean, action, page, name, icon);
1148        return navComp;
1149        
1150    }
1151    
1152    
1153    
1154    private DesignBean addComponent(String JavaDoc lockDesc, Page page, String JavaDoc className) {
1155        //page.model.sync();
1156
UndoEvent undo = null;
1157        DesignBean bean = null;
1158        try {
1159            undo = page.model.writeLock(lockDesc);
1160            bean = page.model.getLiveUnit().createBean(className, null, null);
1161            if (bean == null) {
1162                return bean;
1163            }
1164            page.model.beanCreated(bean);
1165        } catch (Exception JavaDoc e) {
1166            ErrorManager.getDefault().notify(e);
1167        } finally {
1168            page.model.writeUnlock(undo);
1169        }
1170        page.model.flush();
1171        return bean;
1172        
1173    }
1174}
1175
Popular Tags