001: /*
002: * Sun Public License Notice
003: *
004: * The contents of this file are subject to the Sun Public License
005: * Version 1.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://www.sun.com/
008: *
009: * The Original Code is NetBeans. The Initial Developer of the Original
010: * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
011: * Microsystems, Inc. All Rights Reserved.
012: If you wish your version of this file to be governed by only the CDDL
013: or only the GPL Version 2, indicate your decision by adding
014: "[Contributor] elects to include this software in this distribution
015: under the [CDDL or GPL Version 2] license." If you do not indicate a
016: single choice of license, a recipient has the option to distribute
017: your version of this file under either the CDDL, the GPL Version 2 or
018: to extend the choice of license to its licensees as provided above.
019: However, if you add GPL Version 2 code and therefore, elected the GPL
020: Version 2 license, then the option applies only if the new code is
021: made subject to such option by the copyright holder.
022: If you wish your version of this file to be governed by only the CDDL
023: or only the GPL Version 2, indicate your decision by adding
024: "[Contributor] elects to include this software in this distribution
025: under the [CDDL or GPL Version 2] license." If you do not indicate a
026: single choice of license, a recipient has the option to distribute
027: your version of this file under either the CDDL, the GPL Version 2 or
028: to extend the choice of license to its licensees as provided above.
029: However, if you add GPL Version 2 code and therefore, elected the GPL
030: Version 2 license, then the option applies only if the new code is
031: made subject to such option by the copyright holder.
032: */
033:
034: /*
035: * Created on May 19, 2005
036: *
037: * To change the template for this generated file go to
038: * Window - Preferences - Java - Code Generation - Code and Comments
039: */
040: package org.netbeans.modules.etl.ui;
041:
042: import java.awt.BorderLayout;
043: import java.awt.Color;
044: import java.awt.dnd.DropTarget;
045: import java.awt.dnd.DropTargetDragEvent;
046: import java.awt.dnd.DropTargetDropEvent;
047: import java.awt.dnd.DropTargetEvent;
048: import java.awt.dnd.DropTargetListener;
049: import java.beans.PropertyChangeEvent;
050: import java.beans.PropertyChangeListener;
051: import java.io.Externalizable;
052: import java.io.IOException;
053: import java.io.ObjectInput;
054: import java.io.ObjectOutput;
055: import java.util.ArrayList;
056: import java.util.Arrays;
057:
058: import javax.swing.Action;
059: import javax.swing.JSeparator;
060: import javax.swing.UIManager;
061: import javax.swing.event.ChangeListener;
062: import javax.swing.text.Document;
063: import javax.swing.undo.CannotRedoException;
064: import javax.swing.undo.CannotUndoException;
065:
066: import net.java.hulp.i18n.Logger;
067: import org.netbeans.core.spi.multiview.CloseOperationState;
068: import org.netbeans.core.spi.multiview.MultiViewElement;
069: import org.netbeans.core.spi.multiview.MultiViewElementCallback;
070: import org.netbeans.core.spi.multiview.MultiViewFactory;
071: import org.netbeans.modules.etl.logger.Localizer;
072: import org.netbeans.modules.etl.logger.LogUtil;
073: import org.netbeans.modules.etl.model.ETLDefinition;
074: import org.netbeans.modules.etl.ui.palette.PaletteSupport;
075: import org.netbeans.modules.sql.framework.model.utils.SQLObjectUtil;
076: import org.netbeans.modules.etl.ui.view.ETLCollaborationTopPanel;
077: import org.netbeans.modules.sql.framework.ui.graph.impl.GraphView;
078: import org.netbeans.spi.palette.PaletteController;
079: import org.openide.DialogDisplayer;
080: import org.openide.ErrorManager;
081: import org.openide.NotifyDescriptor;
082: import org.openide.awt.StatusDisplayer;
083: import org.openide.awt.UndoRedo;
084: import org.openide.cookies.SaveCookie;
085: import org.openide.nodes.Node;
086: import org.openide.text.ActiveEditorDrop;
087: import org.openide.util.Lookup;
088: import org.openide.util.lookup.AbstractLookup;
089: import org.openide.util.lookup.InstanceContent;
090: import org.openide.util.lookup.Lookups;
091: import org.openide.util.lookup.ProxyLookup;
092: import org.openide.windows.CloneableTopComponent;
093:
094: /**
095: * @author radval
096: *
097: * To change the template for this generated type comment go to
098: * Window - Preferences - Java - Code Generation - Code and Comments
099: */
100: public class ETLEditorViewMultiViewElement extends
101: CloneableTopComponent implements MultiViewElement,
102: Lookup.Provider, Externalizable {
103:
104: private static final long serialVersionUID = -655912409997381426L;
105: private ETLDataObject dataObject = null;
106: private ETLCollaborationTopPanel topPanel;
107: private ETLEditorSupport mEditorSupport = null;
108: private transient InstanceContent nodesHack;
109: private transient javax.swing.JLabel errorLabel = new javax.swing.JLabel();
110: private static transient final Logger mLogger = LogUtil
111: .getLogger(ETLEditorViewMultiViewElement.class.getName());
112: private static transient final Localizer mLoc = Localizer.get();
113:
114: public ETLEditorViewMultiViewElement() {
115: super ();
116: }
117:
118: public ETLEditorViewMultiViewElement(ETLDataObject dObj) {
119: super ();
120: this .dataObject = dObj;
121: try {
122: initialize();
123: } catch (Exception ex) {
124: String nbBundle1 = mLoc
125: .t("PRSR001: Error in creating eTL Editor view");
126: ErrorManager.getDefault().log(ErrorManager.ERROR,
127: Localizer.parse(nbBundle1) + ex.getMessage());
128: }
129: }
130:
131: private void initialize() throws Exception {
132: try {
133: mEditorSupport = dataObject.getETLEditorSupport();
134: setLayout(new BorderLayout());
135: topPanel = dataObject.getETLEditorTopPanel();
136: add(BorderLayout.CENTER, topPanel);
137: initializeLookup();
138: } catch (Exception ex) {
139: throw ex;
140: }
141: }
142:
143: private void initializeLookup() throws IOException {
144: associateLookup(createAssociateLookup());
145: addPropertyChangeListener(new PropertyChangeListener() {
146:
147: /**
148: * TODO: may not be needed at some point when parenting
149: * MultiViewTopComponent delegates properly to its peer's
150: * activatedNodes.
151: *
152: * see http://www.netbeans.org/issues/show_bug.cgi?id=67257
153: *
154: * note: TopComponent.setActivatedNodes is final
155: */
156: public void propertyChange(PropertyChangeEvent event) {
157: if (event.getPropertyName().equals("activatedNodes")) {
158: nodesHack.set(Arrays.asList(getActivatedNodes()),
159: null);
160: }
161: }
162: });
163: setActivatedNodes(new Node[] { getETLDataObject()
164: .getNodeDelegate() });
165: }
166:
167: private Lookup createAssociateLookup() throws IOException {
168: //
169: // see http://www.netbeans.org/issues/show_bug.cgi?id=67257
170: //
171: final PaletteController controller = createPalette();
172: nodesHack = new InstanceContent();
173: nodesHack.add(controller);
174: /*controller.addPropertyChangeListener( new PropertyChangeListener() {
175: public void propertyChange(PropertyChangeEvent evt) {
176: if( PaletteController.PROP_SELECTED_ITEM.equals( evt.getPropertyName() ) ) {
177: Lookup selItem = controller.getSelectedItem();
178: if( null != selItem ) {
179: ActiveEditorDrop selNode = (ActiveEditorDrop)selItem.lookup( ActiveEditorDrop.class );
180: if(null != selNode){
181: StatusDisplayer.getDefault().setStatusText("Selected "+selNode);
182: }
183: }
184: }
185: }
186:
187: });
188: setDropTarget(new DropTarget(this,new DropTargetListener() {
189: public void dragEnter(DropTargetDragEvent dtde) {
190: }
191:
192: public void dragOver(DropTargetDragEvent dtde) {
193: }
194:
195: public void dropActionChanged(DropTargetDragEvent dtde) {
196: }
197:
198: public void dragExit(DropTargetEvent dte) {
199: }
200:
201: public void drop(DropTargetDropEvent dtde) {
202: NotifyDescriptor d =new NotifyDescriptor.Message("Drop",NotifyDescriptor.INFORMATION_MESSAGE);
203: DialogDisplayer.getDefault().notify(d);
204: }
205: }));*/
206: return new ProxyLookup(new Lookup[] {
207: //
208: // other than nodesHack what else do we need in the associated
209: // lookup? I think that XmlNavigator needs DataObject
210: //
211: getETLDataObject().getLookup(), // this lookup contain objects that are used in OM clients
212: Lookups.singleton(this ), new AbstractLookup(nodesHack),
213: Lookups.fixed(new Object[] { controller }), });
214: }
215:
216: private PaletteController createPalette() throws IOException {
217: PaletteController controller = PaletteSupport
218: .createPalette(topPanel);
219: return controller;
220: }
221:
222: private ETLDataObject getETLDataObject() {
223: return dataObject;
224: }
225:
226: /**
227: * Overwrite when you want to change default persistence type. Default
228: * persistence type is PERSISTENCE_ALWAYS.
229: * Return value should be constant over a given TC's lifetime.
230: * @return one of P_X constants
231: * @since 4.20
232: */
233: @Override
234: public int getPersistenceType() {
235: return PERSISTENCE_ONLY_OPENED;//was PERSISTENCE_NEVER
236: }
237:
238: public void setMultiViewCallback(
239: final MultiViewElementCallback callback) {
240: ETLEditorSupport editor = dataObject.getETLEditorSupport();
241: editor.setTopComponent(callback.getTopComponent());
242: }
243:
244: public CloseOperationState canCloseElement() {
245: if ((dataObject != null) && (dataObject.isModified())) {
246: return MultiViewFactory.createUnsafeCloseState(
247: "Data object modified", null, null);
248: }
249: return CloseOperationState.STATE_OK;
250: }
251:
252: @Override
253: public void componentHidden() {
254: super .componentHidden();
255: }
256:
257: @Override
258: public void componentClosed() {
259: super .componentClosed();
260: }
261:
262: @Override
263: public void componentOpened() {
264: super .componentOpened();
265: DataObjectProvider.activeDataObject = dataObject;
266: }
267:
268: @Override
269: public void componentActivated() {
270: super .componentActivated();
271: if (getETLDataObject().getETLEditorSupport().isFirstTime) {
272: try {
273: getETLDataObject().getETLEditorSupport().syncModel();
274: SQLObjectUtil
275: .createMissingModelTablesInDB(getETLDataObject());
276: } catch (Exception ex) {
277: ex.printStackTrace();
278: StatusDisplayer.getDefault().setStatusText(
279: ex.getMessage());
280: }
281: }
282: getETLDataObject().createNodeDelegate();
283: DataObjectProvider.activeDataObject = dataObject;
284: GraphView graphView = (GraphView) this .topPanel.getGraphView();
285: if (null != graphView) {
286: graphView.setObserved(graphView);
287: }
288: }
289:
290: @Override
291: public void componentDeactivated() {
292: SaveCookie cookie = dataObject.getCookie(SaveCookie.class);
293: if (cookie != null) {
294: getETLDataObject().getETLEditorSupport().synchDocument();
295: }
296: super .componentDeactivated();
297: }
298:
299: @Override
300: public void componentShowing() {
301:
302: super .componentShowing();
303: ETLEditorSupport editor = dataObject.getETLEditorSupport();
304: UndoRedo.Manager undoRedo = editor.getUndoManager();
305: Document document = editor.getDocument();
306: if (document != null) {
307: document.removeUndoableEditListener(undoRedo);
308: }
309: checkModelState();
310: DataObjectProvider.activeDataObject = dataObject;
311: }
312:
313: private void checkModelState() {
314: ETLEditorSupport editor = getETLDataObject()
315: .getETLEditorSupport();
316: ETLDataObject dObj = (ETLDataObject) editor.getDataObject();
317: ETLDefinition model = null;
318: String errorMessage = null;
319:
320: try {
321: model = dObj.getETLDefinition();
322: if (model != null) {
323: recreateUI(model);
324: return;
325: }
326: } catch (Exception ex) {
327: errorMessage = ex.getMessage();
328: ex.printStackTrace();
329: }
330:
331: //if it comes here, either the schema is not well-formed or invalid
332: if (model == null) {
333: if (errorMessage == null) {
334: String nbBundle2 = mLoc
335: .t("PRSR001: The etl is not well-formed");
336: errorMessage = Localizer.parse(nbBundle2);
337: }
338: }
339:
340: emptyUI(errorMessage);
341: }
342:
343: private void emptyUI(String errorMessage) {
344: this .removeAll();
345: errorLabel.setText("<" + errorMessage + ">");
346: errorLabel
347: .setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
348: errorLabel
349: .setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
350: errorLabel.setEnabled(false);
351: Color usualWindowBkg = UIManager.getColor("window"); //NOI18N
352: errorLabel
353: .setBackground(usualWindowBkg != null ? usualWindowBkg
354: : Color.white);
355: errorLabel.setOpaque(true);
356: add(errorLabel, BorderLayout.CENTER);
357: }
358:
359: private void recreateUI(ETLDefinition model) {
360: this .removeAll();
361: // Add the schema category pane as our primary interface.
362: add(topPanel, BorderLayout.CENTER);
363: }
364:
365: public javax.swing.JComponent getToolbarRepresentation() {
366: return topPanel.createToolbar();
367: }
368:
369: public javax.swing.JComponent getVisualRepresentation() {
370: return this ;
371: }
372:
373: public CloneableTopComponent getComponent() {
374: return this ;
375: }
376:
377: /** Get the undo/redo support for this component.
378: * The default implementation returns a dummy support that cannot
379: * undo anything.
380: *
381: * @return undoable edit for this component
382: */
383: @Override
384: public UndoRedo getUndoRedo() {
385: return new TreeEditorUndoRedo();
386: }
387:
388: public void cleanUp() {
389: }
390:
391: public class TreeEditorUndoRedo implements UndoRedo {
392:
393: public void addChangeListener(ChangeListener l) {
394: }
395:
396: public boolean canRedo() {
397: return mEditorSupport.getUndoManager().canRedo();
398: }
399:
400: public boolean canUndo() {
401: return mEditorSupport.getUndoManager().canUndo();
402: }
403:
404: public String getRedoPresentationName() {
405: if (mEditorSupport != null) {
406: return mEditorSupport.getUndoManager()
407: .getRedoPresentationName();
408: }
409: return "Redo_ETLTreeEditor";
410: }
411:
412: public String getUndoPresentationName() {
413: if (mEditorSupport != null) {
414: return mEditorSupport.getUndoManager()
415: .getUndoPresentationName();
416: }
417: return "Undo_ETLTreeEditor";
418: }
419:
420: public void redo() throws CannotRedoException {
421: mEditorSupport.getUndoManager().redo();
422: }
423:
424: public void removeChangeListener(ChangeListener l) {
425: }
426:
427: public void undo() throws CannotUndoException {
428: mEditorSupport.getUndoManager().undo();
429: }
430: }
431:
432: @Override
433: public void writeExternal(ObjectOutput out) throws IOException {
434: super .writeExternal(out);
435: out.writeObject(dataObject);
436: }
437:
438: @Override
439: public void readExternal(ObjectInput in) throws IOException,
440: ClassNotFoundException {
441: super .readExternal(in);
442: Object firstObject = in.readObject();
443: if (firstObject instanceof ETLDataObject) {
444: dataObject = (ETLDataObject) in.readObject();
445: }
446: }
447:
448: @Override
449: public Action[] getActions() {
450: ArrayList<Action> actionsList = new ArrayList<Action>();
451: for (Action action : super .getActions()) {
452: actionsList.add(action);
453: }
454: actionsList.add(addFromLayers());
455: Action[] actions = new Action[actionsList.size()];
456: actionsList.toArray(actions);
457: return actions;
458: }
459:
460: private Action addFromLayers() {
461: Action action = null;
462: Lookup look = Lookups.forPath("Projects/Actions");
463: for (Object next : look.lookupAll(Object.class)) {
464: if (next instanceof Action) {
465: action = (Action) next;
466: } else if (next instanceof JSeparator) {
467: action = null;
468: }
469: }
470: return action;
471: }
472: }
|