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:
042: package org.netbeans.modules.visualweb.designer.jsf;
043:
044: import com.sun.rave.designtime.DesignBean;
045: import com.sun.rave.designtime.DisplayItem;
046: import com.sun.rave.designtime.Position;
047: import com.sun.rave.designtime.markup.MarkupDesignBean;
048: import com.sun.rave.designtime.markup.MarkupPosition;
049: import java.awt.Dimension;
050: import java.awt.Point;
051: import java.awt.datatransfer.DataFlavor;
052: import java.awt.datatransfer.Transferable;
053: import java.awt.datatransfer.UnsupportedFlavorException;
054: import java.beans.PropertyChangeEvent;
055: import java.beans.PropertyChangeListener;
056: import java.io.File;
057: import java.io.IOException;
058: import java.util.ArrayList;
059: import java.util.List;
060: import java.util.logging.Level;
061: import java.util.logging.Logger;
062: import javax.swing.JComponent;
063: import org.netbeans.api.project.FileOwnerQuery;
064: import org.netbeans.api.project.Project;
065: import org.netbeans.modules.visualweb.api.designer.Designer;
066: import org.netbeans.modules.visualweb.api.designer.DomProvider;
067: import org.netbeans.modules.visualweb.api.designerapi.DesignTimeTransferDataCreator;
068: import org.netbeans.modules.visualweb.insync.Util;
069: import org.netbeans.modules.visualweb.insync.live.LiveUnit;
070: import org.netbeans.modules.visualweb.insync.models.FacesModel;
071: import org.openide.ErrorManager;
072: import org.openide.filesystems.FileObject;
073: import org.openide.loaders.DataObject;
074: import org.openide.util.Exceptions;
075: import org.openide.util.Lookup;
076: import org.openide.util.WeakListeners;
077: import org.w3c.dom.Element;
078: import static org.netbeans.modules.visualweb.api.designer.DomProvider.*;
079: import org.w3c.dom.Node;
080:
081: /**
082: * Place for JSF specific DnD support.
083: * Factored out the complicated stuff from the designer/DnDHandler.
084: *
085: * XXX TODO Merge with FacesDndSupport.
086: * XXX TODO Separate FacesModel.JsfSupport impl.
087: *
088: * @author Peter Zavadsky
089: * @author Tor Norbye (the original moved code)
090: */
091: class DndSupport implements /*XXX*/FacesModel.JsfSupport {
092:
093: private final JsfForm jsfForm;
094: /** XXX TEMP solution. Listener on DnD changes. */
095: private PropertyChangeListener dndListener;
096:
097: // private MarkupDesignBean recentDropTarget;
098:
099: private final FacesDndSupport facesDndSupport;
100:
101: /** Creates a new instance of DndSupport */
102: public DndSupport(JsfForm jsfForm) {
103: this .jsfForm = jsfForm;
104: this .facesDndSupport = new FacesDndSupport(jsfForm);
105: }
106:
107: // private FacesModel getFacesModel() {
108: // return jsfForm.getFacesModel();
109: // }
110:
111: DataFlavor getImportFlavor(DataFlavor[] flavors) {
112: return FacesDndSupport.getImportFlavor(flavors);
113: }
114:
115: // MarkupPosition getDefaultMarkupPositionUnderParent(DesignBean parent) {
116: // return FacesDndSupport.getDefaultMarkupPositionUnderParent(parent, getFacesModel());
117: // }
118:
119: String[] getClassNames(DisplayItem[] displayItems) {
120: // return getFacesModel().getDnDSupport().getClasses(displayItems);
121: return facesDndSupport.getClasses(displayItems);
122: }
123:
124: // boolean importBean(DisplayItem[] items, DesignBean origParent, int nodePos,
125: // String facet, List createdBeans, DomProvider.Location location,
126: // DomProvider.CoordinateTranslator coordinateTranslator) throws IOException {
127: // return getFacesModel().getDnDSupport().importBean(items, origParent, nodePos, facet, createdBeans,
128: // new LocationImpl(location), new CoordinateTranslatorImpl(coordinateTranslator), jsfForm.getUpdateSuspender());
129: // }
130:
131: // void importData(JComponent comp, Transferable t, Object transferData, Dimension dimension,
132: // DomProvider.Location location, DomProvider.CoordinateTranslator coordinateTranslator, int dropAction) {
133: // getFacesModel().getDnDSupport().importData(comp, t, transferData, dimension, new LocationImpl(location),
134: // new CoordinateTranslatorImpl(coordinateTranslator), jsfForm.getUpdateSuspender(), dropAction);
135: // }
136:
137: // void importString(String string, DomProvider.Location location, DomProvider.CoordinateTranslator coordinateTranslator) {
138: // getFacesModel().getDnDSupport().importString(string, new LocationImpl(location), new CoordinateTranslatorImpl(coordinateTranslator), jsfForm.getUpdateSuspender());
139: // }
140:
141: DesignBean[] pasteBeans(Transferable t, DesignBean parent,
142: MarkupPosition pos, Point location,
143: FacesDndSupport.UpdateSuspender updateSuspender) {
144: // return getFacesModel().getDnDSupport().pasteBeans(t, parent, pos, location, jsfForm.getUpdateSuspender());
145: return facesDndSupport.pasteBeans(t, parent, pos, location,
146: jsfForm.getUpdateSuspender());
147: }
148:
149: int computeActions(DesignBean droppee, Transferable transferable) {
150: // return getFacesModel().getDnDSupport().computeActions(droppee, transferable);
151: return facesDndSupport.computeActions(droppee, transferable);
152: }
153:
154: int processLinks(Element origElement, List<DesignBean> beans) {
155: return processLinks(origElement, null, beans, true, true, false);
156: }
157:
158: private int processLinks(Element origElement, Class[] classes,
159: List<DesignBean> beans, boolean selectFirst,
160: boolean handleLinks, boolean showLinkTarget) {
161: // return getFacesModel().getDnDSupport().processLinks(origElement, classes, beans, selectFirst, handleLinks, showLinkTarget, jsfForm.getUpdateSuspender());
162: return facesDndSupport.processLinks(origElement, classes,
163: beans, selectFirst, handleLinks, showLinkTarget,
164: jsfForm.getUpdateSuspender());
165: }
166:
167: void updateDndListening() {
168: dndListener = new DnDListener(jsfForm);
169: // XXX Listening on dnd support, it should be on model.
170: // getFacesModel().getDnDSupport().addPropertyChangeListener(WeakListeners.propertyChange(dndListener, getFacesModel().getDnDSupport()));
171: facesDndSupport.addPropertyChangeListener(WeakListeners
172: .propertyChange(dndListener, facesDndSupport));
173: }
174:
175: int getDropType(DesignBean origDroppee, Element droppeeElement,
176: Transferable t, boolean linkOnly) {
177: DataFlavor importFlavor = getImportFlavor(t
178: .getTransferDataFlavors());
179:
180: if (importFlavor == null) {
181: DataFlavor[] flavors = t.getTransferDataFlavors();
182: ErrorManager
183: .getDefault()
184: .log(
185: "Unusable transfer, data flavors="
186: + (flavors == null ? null
187: : java.util.Arrays
188: .asList(t
189: .getTransferDataFlavors()))); // NOI18N
190:
191: return DROP_DENIED;
192: }
193:
194: Class rc = importFlavor.getRepresentationClass();
195:
196: if (rc == DisplayItem.class) {
197: // Create a new type
198: try {
199: Object transferData = t.getTransferData(importFlavor);
200:
201: if (!(transferData instanceof DisplayItem)) {
202: ErrorManager.getDefault().notify(
203: ErrorManager.INFORMATIONAL,
204: new IllegalStateException(
205: "Invalid transferData="
206: + transferData // NOI18N
207: + ", from transferable="
208: + t)); // NOI18N
209: return DROP_DENIED;
210: }
211:
212: DisplayItem item = (DisplayItem) transferData;
213:
214: return getDropTypeForDisplayItem(origDroppee,
215: droppeeElement, item, linkOnly);
216: } catch (UnsupportedFlavorException ex) {
217: ErrorManager.getDefault().notify(ex);
218:
219: return DROP_DENIED;
220: } catch (java.io.IOException ex) {
221: ErrorManager.getDefault().notify(ex);
222:
223: return DROP_DENIED;
224: }
225: } else if (rc == DesignBean.class) {
226: try {
227: Object transferData = t.getTransferData(importFlavor);
228:
229: if (!(transferData instanceof DesignBean[])) {
230: ErrorManager.getDefault().log(
231: "Invalid DesignBean[] transfer data: "
232: + transferData);
233:
234: return DROP_DENIED;
235: }
236:
237: DesignBean[] beans = (DesignBean[]) transferData;
238:
239: String[] classNames = new String[beans.length];
240:
241: for (int i = 0, n = beans.length; i < n; i++) {
242: classNames[i] = beans[i].getInstance().getClass()
243: .getName();
244: }
245:
246: return getDropTypeForClassNames(origDroppee,
247: droppeeElement, classNames, null, linkOnly);
248: } catch (UnsupportedFlavorException ex) {
249: ErrorManager.getDefault().notify(
250: ErrorManager.INFORMATIONAL, ex);
251: return DROP_DENIED;
252: } catch (java.io.IOException ex) {
253: ErrorManager.getDefault().notify(
254: ErrorManager.INFORMATIONAL, ex);
255: return DROP_DENIED;
256: }
257: }
258:
259: // XXX TEMP First give the chance to the provider.
260: // FIXME This shouldn't be here at all, the original transferable
261: // should contain all the needed flavors.
262: DesignTimeTransferDataCreator dataCreator = (DesignTimeTransferDataCreator) Lookup
263: .getDefault().lookup(
264: DesignTimeTransferDataCreator.class);
265: if (dataCreator != null) {
266: DisplayItem displayItem = dataCreator.getDisplayItem(t);
267: if (displayItem != null) {
268: return getDropTypeForDisplayItem(origDroppee,
269: droppeeElement, displayItem, linkOnly);
270: }
271: }
272:
273: // XXX The other hacked transferables.
274: if (rc == String.class/*Linux*/|| rc == List.class/*Windows/Solaris*/) {
275: if (rc == List.class) {
276: // XXX #99457 There needs to be more fine grained decision.
277: try {
278: java.util.List list = (java.util.List) t
279: .getTransferData(importFlavor);
280: for (Object element : list) {
281: if (element instanceof File) {
282: File file = (File) element;
283: // XXX Copy also in FacesDndSupport.
284: if (file.exists()) {
285: String name = file.getName();
286: String extension = name.substring(name
287: .lastIndexOf(".") + 1); // NOI18N
288: // Project project = facesModel.getProject();
289: Project project = jsfForm.getProject();
290:
291: // XXX #95601 Skip the file if it is already inside the project.
292: if (FileOwnerQuery.getOwner(file
293: .toURI()) == project) {
294: // return panel;
295: return DROP_DENIED;
296: }
297:
298: //String mime = FileUtil.getMIMEType(extension);
299: // They've only registered gif and jpg so not a big deal
300: if (FacesDndSupport.isImage(extension)) {
301: // Location location =
302: // computePositions(null, DROP_CENTER, null, getDropPoint(), insertPos, true);
303: // return panel;
304: return DROP_PARENTED;
305: } else if (FacesDndSupport
306: .isStylesheet(extension)) {
307: // return panel;
308: return DROP_PARENTED;
309: }
310:
311: // XXX TODO Also missing how to check whether Importable.PageImportable can do the import.
312: }
313: }
314: }
315: } catch (UnsupportedFlavorException ex) {
316: log(ex);
317: return DROP_DENIED;
318: } catch (IOException ex) {
319: log(ex);
320: return DROP_DENIED;
321: }
322: } else if (rc == String.class) {
323: // TODO Also more fine grained decision.
324: return DROP_PARENTED;
325: }
326: return DROP_DENIED;
327: } else if (rc == org.openide.nodes.Node.class) {
328: // XXX #6482097 Reflecting the impl in FacesDnDSupport.
329: // FIXME Later the impl has to be improved and moved over there.
330: Object transferData;
331: try {
332: transferData = t.getTransferData(importFlavor);
333: if (transferData instanceof org.openide.nodes.Node) {
334: org.openide.nodes.Node node = (org.openide.nodes.Node) transferData;
335: DataObject dobj = (DataObject) node
336: .getCookie(DataObject.class);
337:
338: if (dobj != null) {
339: FileObject fo = dobj.getPrimaryFile();
340: // if (isImage(fo.getExt())) {
341: if (FacesDndSupport.isImage(fo.getExt())) {
342: // String className;
343: // // XXX This should be decided by the parent bean.
344: // // I.e. appropriate api is missing.
345: // // XXX This shouldn't be here resolved, but in the parent bean.
346: // if (webform.isBraveheartPage()) {
347: // className = com.sun.rave.web.ui.component.ImageComponent.class.getName(); // NOI18N
348: // } else if (webform.isWoodstockPage()) {
349: // // Use woodstock ImageComponent component
350: // className = com.sun.webui.jsf.component.ImageComponent.class.getName(); // NOI18N
351: // } else {
352: // className = javax.faces.component.html.HtmlGraphicImage.class.getName(); // NOI18N
353: // }
354:
355: // String className = webform.getImageComponentClassName();
356: String className = getImageComponentClassName();
357:
358: String[] classNames = new String[] { className };
359:
360: return getDropTypeForClassNames(
361: origDroppee, droppeeElement,
362: classNames, null, linkOnly);
363: // } else if (isStylesheet(fo.getExt())) {
364: } else if (FacesDndSupport.isStylesheet(fo
365: .getExt())) {
366: return DROP_PARENTED;
367: }
368: }
369: }
370: } catch (IOException ex) {
371: ErrorManager.getDefault().notify(
372: ErrorManager.INFORMATIONAL, ex);
373: } catch (UnsupportedFlavorException ex) {
374: ErrorManager.getDefault().notify(
375: ErrorManager.INFORMATIONAL, ex);
376: }
377: return DROP_DENIED;
378: }
379:
380: return DROP_DENIED;
381: }
382:
383: private String getImageComponentClassName() {
384: // XXX This should be decided by the parent bean.
385: // I.e. appropriate api is missing.
386: // XXX This shouldn't be here resolved, but in the parent bean.
387: // if (jsfForm.getDomProvider().isBraveheartPage()) {
388: if (jsfForm.isBraveheartPage()) {
389: return com.sun.rave.web.ui.component.ImageComponent.class
390: .getName(); // NOI18N
391: // } else if (jsfForm.getDomProvider().isWoodstockPage()) {
392: } else if (jsfForm.isWoodstockPage()) {
393: // Use woodstock ImageComponent component
394: return com.sun.webui.jsf.component.ImageComponent.class
395: .getName(); // NOI18N
396: } else {
397: return javax.faces.component.html.HtmlGraphicImage.class
398: .getName(); // NOI18N
399: }
400: }
401:
402: /**
403: * Decide whether or not we can drop the given palette item
404: * at the given position.
405: * XXX TODO get rid of this method from the designer, it is JSF specific..
406: */
407: // private int getDropTypeForDisplayItem(Point p, DisplayItem item, boolean linkOnly) {
408: private int getDropTypeForDisplayItem(DesignBean origDroppee,
409: Element droppeeElement, DisplayItem item, boolean linkOnly) {
410: if (item == null) {
411: ErrorManager.getDefault().notify(
412: ErrorManager.INFORMATIONAL,
413: new NullPointerException("Item is null")); // NOI18N
414: return DROP_DENIED;
415: }
416:
417: // String[] classNames = getClasses(new DisplayItem[] { item });
418: // String[] classNames = webform.getClassNames(new DisplayItem[] {item});
419: String[] classNames = getClassNames(new DisplayItem[] { item });
420:
421: return getDropTypeForClassNames(origDroppee, droppeeElement,
422: classNames, null, linkOnly);
423: }
424:
425: /**
426: * Decide whether or not we can drop the given palette item at the given position.
427: * @todo implement using computeActions and computePosition instead of custom solution here... e.g.
428: <pre>
429: public int getDropType(Point p, String[] classNames, boolean linkOnly) {
430: int allowed = computeActions(dropNode, t, false, nodePos);
431: if (allowed == DnDConstants.ACTION_NONE) {
432: return;
433: }
434: if (dropAction == DnDConstants.ACTION_COPY) {
435: ... XXX call computeActions
436: }
437: </pre>
438: * XXX TODO get rid of this method from the designer, it is JSF specific.
439: */
440: int getDropTypeForClassNames(DesignBean origDroppee,
441: Element droppeeElement, String[] classNames,
442: DesignBean[] beans, boolean linkOnly) {
443: // if(DesignerUtils.DEBUG) {
444: // DesignerUtils.debugLog(getClass().getName() + ".getDropType(Point, PaletteItem, boolean)");
445: // }
446: // if(p == null) {
447: // throw(new IllegalArgumentException("Null drop point."));
448: // }
449: if (classNames == null) {
450: throw (new IllegalArgumentException(
451: "Null class names array."));
452: }
453:
454: // recentDropTarget = null;
455:
456: // // No... call computePositions and use location.coordinates instead... see @todo above
457: //// CssBox box = webform.getMapper().findBox(p.x, p.y);
458: // CssBox box = ModelViewMapper.findBox(webform.getPane().getPageBox(), p.x, p.y);
459: // DesignBean origDroppee = getDroppee(box);
460:
461: if (origDroppee == null) {
462: if (linkOnly) {
463: return DROP_DENIED;
464: }
465:
466: // if (origDroppee instanceof MarkupDesignBean) {
467: // recentDropTarget = (MarkupDesignBean)origDroppee;
468: // }
469:
470: // LiveUnit unit = webform.getModel().getLiveUnit();
471:
472: // if (unit != null) {
473: for (int i = 0; i < classNames.length; i++) {
474: // Do anything smart about facets here? E.g. what if you
475: // point over a facet table header? A drop in the app outline
476: // would offer to replace it. Should the interactive link feedback
477: // allow this too?
478: // if (unit.canCreateBean(classNames[i], null, null)) {
479: // if (webform.canCreateBean(classNames[i], null, null)) {
480: if (canCreateBean(classNames[i], null, null)) {
481: showDropMatch(null, DROP_PARENTED);
482:
483: return DROP_PARENTED;
484: }
485: }
486: // }
487:
488: clearDropMatch();
489:
490: return DROP_DENIED;
491: }
492:
493: // None of the droppee ancestors accepted the drop items
494: // as a potential child - but perhaps they will accept
495: // a link?
496: // Class[] classes = new Class[classNames.length];
497: // ArrayList beanList = null;
498: //
499: // if (beans != null) {
500: // beanList = new ArrayList(beans.length);
501: // }
502: //
503: // for (int i = 0; i < classNames.length; i++) {
504: // try {
505: // Class clz = webform.getModel().getFacesUnit().getBeanClass(classNames[i]);
506: //
507: // if (clz != null) {
508: // classes[i] = clz;
509: // }
510: //
511: // if (beans != null) {
512: // beanList.add(beans[i]);
513: // }
514: // } catch (Exception e) {
515: // ErrorManager.getDefault().notify(e);
516: // }
517: // }
518: //
519: // if (beans == null) {
520: // beanList = null;
521: // }
522: List<Class> classList = new ArrayList<Class>();
523: List<DesignBean> beanList = beans == null ? null
524: : new ArrayList<DesignBean>();
525: for (int i = 0; i < classNames.length; i++) {
526: try {
527: // Class clazz = webform.getModel().getFacesUnit().getBeanClass(classNames[i]);
528: // Class clazz = webform.getBeanClass(classNames[i]);
529: Class clazz = getBeanClass(classNames[i]);
530: if (clazz != null) {
531: classList.add(clazz);
532: }
533: if (beans != null) {
534: beanList.add(beans[i]);
535: }
536: } catch (ClassNotFoundException ex) {
537: // XXX #6492649 It means the class can't be found so no drop should happen.
538: // FIXME The API should be improved and not controlled via exceptions.
539: continue;
540: } catch (Exception ex) {
541: ErrorManager.getDefault().notify(
542: ErrorManager.INFORMATIONAL, ex);
543: continue;
544: }
545: }
546: Class[] classes = classList
547: .toArray(new Class[classList.size()]);
548:
549: // RaveElement droppeeElement = (RaveElement)box.getElement();
550: // Element droppeeElement = box.getElement();
551:
552: int dropType = processLinks(droppeeElement, classes, beanList,
553: true, false, true);
554:
555: if (dropType != DROP_DENIED) {
556: return dropType;
557: }
558:
559: if (linkOnly) {
560: clearDropMatch();
561:
562: return DROP_DENIED;
563: }
564:
565: // See if any of the droppee parents accept the new item as a
566: // child
567: for (int i = 0; i < classNames.length; i++) {
568: Node parentNode = null; // XXX todo figure out better parent node
569: // DesignBean parent = findParent(classNames[i], origDroppee, parentNode, true);
570: // DesignBean parent = webform.findParent(classNames[i], origDroppee, parentNode, true);
571: DesignBean parent = findParent(classNames[i], origDroppee,
572: parentNode, true);
573:
574: if (parent != null) {
575: if (parent instanceof MarkupDesignBean) {
576: // recentDropTarget = (MarkupDesignBean)parent;
577: // showDropMatch(recentDropTarget, null, DROP_PARENTED);
578: showDropMatch(
579: DomProviderImpl
580: .getComponentRootElementForMarkupDesignBean((MarkupDesignBean) parent),
581: DROP_PARENTED);
582: } else {
583: clearDropMatch();
584: }
585:
586: return DROP_PARENTED;
587: }
588: }
589:
590: showDropMatch(null, DROP_DENIED);
591:
592: return DROP_DENIED;
593: }
594:
595: private boolean canCreateBean(String className, DesignBean parent,
596: Position pos) {
597: // LiveUnit liveUnit = getFacesModel().getLiveUnit();
598: LiveUnit liveUnit = jsfForm.getLiveUnit();
599: if (liveUnit == null) {
600: return false;
601: }
602: return liveUnit.canCreateBean(className, parent, pos);
603: }
604:
605: private DesignBean findParent(String className, DesignBean droppee,
606: Node parentNode, boolean searchUp) {
607: // return Util.findParent(className, droppee, parentNode, searchUp, getFacesModel());
608: return jsfForm.findParent(className, droppee, parentNode,
609: searchUp);
610: }
611:
612: private Class getBeanClass(String className)
613: throws ClassNotFoundException {
614: // return getFacesModel().getFacesUnit().getBeanClass(className);
615: return jsfForm.getFacesPageUnit().getBeanClass(className);
616: }
617:
618: private void showDropMatch(Element componentRootElement,
619: int dropType) {
620: // jsfForm.fireShowDropMatch(componentRootElement, null, dropType);
621: jsfForm.showDropMatch(componentRootElement, null, dropType);
622: }
623:
624: private void clearDropMatch() {
625: // jsfForm.fireClearDropMatch();
626: jsfForm.clearDropMatch();
627: }
628:
629: void importString(Designer designer, String string,
630: Point canvasPos, Node documentPosNode,
631: int documentPosOffset, Dimension dimension, boolean isGrid,
632: Element droppeeElement, DesignBean droppeeBean,
633: DesignBean defaultParent/*, DomProvider.CoordinateTranslator coordinateTranslator*/) {
634: // getFacesModel().getDnDSupport().importString(string, canvasPos, documentPosNode, documentPosOffset, dimension, isGrid,
635: // droppeeElement, droppeeBean, defaultParent, new CoordinateTranslatorImpl(coordinateTranslator), jsfForm.getUpdateSuspender());
636: facesDndSupport.importString(designer, string, canvasPos,
637: documentPosNode, documentPosOffset, dimension, isGrid,
638: droppeeElement, droppeeBean, defaultParent, /*new CoordinateTranslatorImpl(coordinateTranslator),*/
639: jsfForm.getUpdateSuspender());
640: }
641:
642: boolean importData(
643: Designer designer,
644: JComponent comp,
645: Transferable t, /*Object transferData,*/
646: Point canvasPos,
647: Node documentPosNode,
648: int documentPosOffset,
649: Dimension dimension,
650: boolean isGrid,
651: Element droppeeElement,
652: DesignBean droppeeBean,
653: DesignBean defaultParent/*, DomProvider.CoordinateTranslator coordinateTranslator*/,
654: int dropAction) {
655: // getFacesModel().getDnDSupport().importData(comp, t, transferData, canvasPos, documentPosNode, documentPosOffset, dimension, isGrid,
656: // droppeeElement, droppeeBean, defaultParent, new CoordinateTranslatorImpl(coordinateTranslator), jsfForm.getUpdateSuspender(), dropAction);
657: return facesDndSupport.importData(designer, comp, t, /*transferData,*/
658: canvasPos, documentPosNode, documentPosOffset,
659: dimension, isGrid, droppeeElement, droppeeBean,
660: defaultParent, /*new CoordinateTranslatorImpl(coordinateTranslator),*/
661: jsfForm.getUpdateSuspender(), dropAction);
662:
663: }
664:
665: boolean canImport(JComponent comp, DataFlavor[] transferFlavors,
666: Transferable transferable) {
667: return facesDndSupport.canImport(comp, transferFlavors,
668: transferable);
669: }
670:
671: // XXX >>> JsfSupport
672: public void moveBeans(DesignBean[] designBeans, DesignBean liveBean) {
673: facesDndSupport.moveBeans(designBeans, liveBean,
674: new MarkupPosition(-1), null);
675: }
676:
677: public void selectAndInlineEdit(DesignBean[] beans, DesignBean bean) {
678: facesDndSupport.notifyBeansDesigner(beans, bean);
679: }
680:
681: public void refresh(boolean deep) {
682: facesDndSupport.fireRefreshNeeded(deep);
683: }
684:
685: // XXX <<< JsfSupport
686:
687: // // XXX
688: // private static class CoordinateTranslatorImpl implements FacesDndSupport.CoordinateTranslator {
689: // private final DomProvider.CoordinateTranslator coordinateTranslator;
690: //
691: // public CoordinateTranslatorImpl(DomProvider.CoordinateTranslator coordinateTranslator) {
692: // this.coordinateTranslator = coordinateTranslator;
693: // }
694: //
695: // public Point translateCoordinates(Element parent, int x, int y) {
696: // return coordinateTranslator.translateCoordinates(parent, x, y);
697: // }
698: //
699: // public int snapX(int x) {
700: // return coordinateTranslator.snapX(x);
701: // }
702: //
703: // public int snapY(int y) {
704: // return coordinateTranslator.snapY(y);
705: // }
706: // } // End of CoordinateTranslatorImpl.
707:
708: // // XXX
709: // private static class LocationImpl implements FacesDndSupport.Location {
710: // private final DomProvider.Location location;
711: //
712: //
713: // public LocationImpl(DomProvider.Location location) {
714: // this.location = location;
715: // }
716: //
717: //
718: // public DesignBean getDroppee() {
719: // return location.droppee;
720: // }
721: //
722: // public String getFacet() {
723: // return location.facet;
724: // }
725: //
726: // public Element getDroppeeElement() {
727: // return location.droppeeElement;
728: // }
729: //
730: // public MarkupPosition getPos() {
731: // return location.pos;
732: // }
733: //
734: // public Point getCoordinates() {
735: // return location.coordinates;
736: // }
737: //
738: // public Dimension getSize() {
739: // return location.size;
740: // }
741: // } // End of LocationImpl.
742:
743: // XXX Make FacesModel fire appropriate event changes and then this might be not needed.
744: private static class DnDListener implements PropertyChangeListener {
745: private final JsfForm jsfForm;
746:
747: public DnDListener(JsfForm jsfForm) {
748: this .jsfForm = jsfForm;
749: }
750:
751: public void propertyChange(PropertyChangeEvent evt) {
752: if (FacesDndSupport.PROPERTY_DROP_TARGET.equals(evt
753: .getPropertyName())) {
754: FacesDndSupport.DropInfo dropInfo = (FacesDndSupport.DropInfo) evt
755: .getNewValue();
756: // jsfForm.designer.showDropMatch(dropInfo.getMarkupDesignBean(), dropInfo.getMarkupMouseRegion(), dropInfo.getDropType());
757: // jsfForm.fireShowDropMatch(dropInfo.getMarkupDesignBean(), dropInfo.getMarkupMouseRegion(), dropInfo.getDropType());
758: Element componentRootElement = DomProviderImpl
759: .getComponentRootElementForMarkupDesignBean(dropInfo
760: .getMarkupDesignBean());
761: // jsfForm.fireShowDropMatch(componentRootElement, dropInfo.getRegionElement(), dropInfo.getDropType());
762: jsfForm.showDropMatch(componentRootElement, dropInfo
763: .getRegionElement(), dropInfo.getDropType());
764: } else if (FacesDndSupport.PROPERTY_SELECTED_DESIGN_BEAN
765: .equals(evt.getPropertyName())) {
766: Element componentRootElement = JsfSupportUtilities
767: .getComponentRootElementForDesignBean((DesignBean) evt
768: .getNewValue());
769: // jsfForm.designer.select((DesignBean)evt.getNewValue());
770: // jsfForm.fireSelect((DesignBean)evt.getNewValue());
771: jsfForm.selectComponent(componentRootElement);
772: } else if (FacesDndSupport.PROPERTY_REFRESH.equals(evt
773: .getPropertyName())) {
774: // jsfForm.designer.refreshForm(((Boolean)evt.getNewValue()).booleanValue());
775: // jsfForm.fireRefreshForm(((Boolean)evt.getNewValue()).booleanValue());
776: jsfForm.refreshModel(((Boolean) evt.getNewValue())
777: .booleanValue());
778: } else if (FacesDndSupport.PROPERTY_INLINE_EDIT.equals(evt
779: .getPropertyName())) {
780: DesignBean[] designBeans = (DesignBean[]) evt
781: .getNewValue();
782: List<Element> componentRootElements = new ArrayList<Element>();
783: for (DesignBean designBean : designBeans) {
784: Element componentRootElement = JsfSupportUtilities
785: .getComponentRootElementForDesignBean(designBean);
786: if (componentRootElement != null) {
787: componentRootElements.add(componentRootElement);
788: }
789: }
790: // jsfForm.designer.inlineEdit((DesignBean[])evt.getNewValue());
791: // jsfForm.fireInlineEdit((DesignBean[])evt.getNewValue());
792: jsfForm.inlineEditComponents(componentRootElements
793: .toArray(new Element[componentRootElements
794: .size()]));
795: }
796: }
797: } // End of DnDListener.
798:
799: private static void log(Exception ex) {
800: Logger logger = Logger.getLogger(DndSupport.class.getName());
801: logger.log(Level.INFO, null, ex);
802: }
803: }
|