001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.etl.ui.view;
042:
043: import java.awt.BorderLayout;
044: import java.awt.CardLayout;
045: import java.awt.Component;
046: import java.awt.Dialog;
047: import java.awt.Dimension;
048: import java.awt.Font;
049: import java.io.IOException;
050: import java.io.ObjectInput;
051: import java.io.ObjectOutput;
052: import java.util.List;
053: import javax.swing.BorderFactory;
054: import javax.swing.JLabel;
055: import javax.swing.JPanel;
056: import java.awt.event.KeyEvent;
057: import javax.swing.ActionMap;
058: import javax.swing.InputMap;
059: import javax.swing.KeyStroke;
060: import javax.swing.SwingConstants;
061: import javax.swing.SwingUtilities;
062: import org.netbeans.modules.etl.model.impl.ETLDefinitionImpl;
063: import org.netbeans.modules.etl.ui.DataObjectProvider;
064: import org.netbeans.modules.etl.ui.ETLDataObject;
065: import org.netbeans.modules.etl.ui.model.impl.ETLCollaborationModel;
066: import org.netbeans.modules.etl.ui.view.cookies.ExecuteTestCookie;
067: import org.netbeans.modules.etl.ui.view.cookies.SelectTablesCookie;
068: import org.netbeans.modules.sql.framework.model.SQLDefinition;
069: import org.netbeans.modules.sql.framework.ui.SwingWorker;
070: import org.netbeans.modules.sql.framework.ui.editor.property.IPropertySheet;
071: import org.netbeans.modules.sql.framework.ui.graph.IGraphNode;
072: import org.netbeans.modules.sql.framework.ui.graph.IGraphView;
073: import org.netbeans.modules.sql.framework.ui.graph.actions.PrintAction;
074: import org.netbeans.modules.sql.framework.ui.graph.actions.RedoAction;
075: import org.netbeans.modules.sql.framework.ui.graph.actions.RunAction;
076: import org.netbeans.modules.sql.framework.ui.graph.actions.UndoAction;
077: import org.netbeans.modules.sql.framework.ui.output.SQLLogView;
078: import org.netbeans.modules.sql.framework.ui.view.validation.SQLValidationView;
079: import org.netbeans.modules.sql.framework.ui.zoom.ZoomSupport;
080: import org.openide.DialogDescriptor;
081: import org.openide.DialogDisplayer;
082: import org.openide.NotifyDescriptor;
083: import org.openide.actions.SaveAction;
084: import org.openide.nodes.Node;
085: import org.openide.util.actions.CallableSystemAction;
086: import org.openide.util.actions.SystemAction;
087: import com.sun.sql.framework.exception.BaseException;
088: import net.java.hulp.i18n.Logger;
089: import java.io.Externalizable;
090: import javax.swing.JComponent;
091: import javax.swing.JToolBar;
092: import org.netbeans.modules.etl.logger.Localizer;
093: import org.netbeans.modules.etl.logger.LogUtil;
094: import org.netbeans.modules.sql.framework.ui.graph.impl.BirdsEyeView;
095: import org.netbeans.modules.sql.framework.ui.graph.impl.GraphView;
096: import org.netbeans.modules.sql.framework.ui.graph.view.impl.SQLToolBar;
097: import org.netbeans.modules.sql.framework.ui.view.graph.SQLCollaborationView;
098: import org.openide.awt.StatusDisplayer;
099:
100: /**
101: * An openable window available to the IDE's window manager.
102: *
103: * @author Ritesh Adval
104: * @version $Revision$
105: */
106: public class ETLCollaborationTopPanel extends JPanel implements
107: ZoomSupport, Externalizable {
108:
109: private static transient final Logger mLogger = LogUtil
110: .getLogger(ETLCollaborationTopPanel.class.getName());
111: private static transient final Localizer mLoc = Localizer.get();
112:
113: class ValidationThread extends SwingWorker {
114:
115: private SQLDefinition execModel;
116: private List list;
117:
118: public ValidationThread(SQLDefinition execModel) {
119: this .execModel = execModel;
120: }
121:
122: /**
123: * Compute the value to be returned by the <code>get</code> method.
124: *
125: * @return object
126: */
127: public Object construct() {
128: list = execModel.validate();
129:
130: return "";
131: }
132:
133: //Runs on the event-dispatching thread.
134: @Override
135: public void finished() {
136: if (execModel.getAllObjects().size() == 0) {
137: String nbBundle1 = mLoc
138: .t("PRSR001: \nNo items to validate in this collaboration.");
139: String msg = Localizer.parse(nbBundle1);
140: StatusDisplayer.getDefault().setStatusText("\n" + msg);
141: } else if (execModel.getTargetTables().size() == 0) {
142: String nbBundle2 = mLoc
143: .t("PRSR001: \nNo target table defined.");
144: String msg = Localizer.parse(nbBundle2);
145: StatusDisplayer.getDefault().setStatusText("\n" + msg);
146: } else if (list.size() == 0) {
147: StatusDisplayer.getDefault().setStatusText(
148: "\nCollaboration is valid.");
149: }
150:
151: if (list.size() > 0) {
152: validationView.setValidationInfos(list);
153: showSplitPaneView(validationView);
154: }
155: }
156: }
157:
158: /**
159: * Constant representing default name of operator folder from which operator
160: * definitions are retrieved.
161: */
162: public static final String DEFAULT_OPERATOR_FOLDER = "ETLOperators";
163: private static final String GRAPHPANEL_NAME = "Graph Panel";
164: private CardLayout cLayout;
165: private EditDBModelPanel editPanel;
166: private static ETLDataObject dObj;
167: private ETLEditorTopView etlTopView;
168: private SQLLogView logView;
169: private SQLValidationView validationView;
170: private JToolBar toolBar;
171:
172: // REMEMBER: You should have a public default constructor!
173: // This is for externalization. If you have a non-default
174: // constructor for normal creation of the component, leave
175: // in a default constructor that will put the component into
176: // a consistent but unconfigured state, and make sure readExternal
177: // initializes it properly. Or, be creative with writeReplace().
178: /**
179: * Constructs a new default instance of ETLCollaborationTopPanel.
180: */
181: public ETLCollaborationTopPanel() {
182: initComponents();
183:
184: //do not show tab view if there is only one tab
185: putClientProperty("TabPolicy", "HideWhenAlone"); //NOI18N
186: putClientProperty("PersistenceType", "Never"); //NOI18N
187: this .setFont(new Font("Dialog", Font.PLAIN, 12)); //NOI18N
188: registerActions();
189: // Use the Component Inspector to set tool-tip text. This will be saved
190: // automatically. Other JComponent properties you may need to save yuorself.
191: // At any time you can affect the node selection:
192: // setActivatedNodes(new Node[] { ... } );
193: }
194:
195: /**
196: * Constructs new instance of ETLCollaborationTopPanel, using the given
197: * data object to populate its contents.
198: *
199: * @param eTL data object to be rendered
200: * @throws Exception if error occurs during instantiation
201: */
202: public ETLCollaborationTopPanel(ETLDataObject mObj)
203: throws Exception {
204: this ();
205: dObj = mObj;
206: //DataObjectProvider provider = DataObjectProvider.getProvider();
207: String collaborationName = dObj.getName();
208:
209: cLayout = new CardLayout();
210: this .setLayout(cLayout);
211: ETLCollaborationModel collabModel = dObj.getModel();
212: etlTopView = new ETLEditorTopView(collabModel, this );
213: etlTopView.setName(collaborationName);
214: this .add(etlTopView, GRAPHPANEL_NAME);
215:
216: cLayout.first(this );
217:
218: String nbBundle3 = mLoc.t("PRSR001: Validation");
219: validationView = new SQLValidationView(this .getGraphView());
220: String validationLabel = Localizer.parse(nbBundle3);
221: validationView.setName(validationLabel);
222:
223: logView = new SQLLogView();
224: String nbBundle4 = mLoc.t("PRSR001: Execution Log");
225: String logLabel = Localizer.parse(nbBundle4);
226: logView.setName(logLabel);
227: }
228:
229: /**
230: * Adds input table
231: *
232: * @param type - type
233: */
234: public void addRuntime(int type) {
235: TablePanel tPanel = new TablePanel(type);
236: tPanel.showTablePanel();
237: if (dObj.getModel().isDirty()) {
238: dObj.getETLEditorSupport().synchDocument();
239: }
240: }
241:
242: // Variables declaration - do not modify//GEN-BEGIN:variables
243: // End of variables declaration//GEN-END:variables
244: // Printing, saving, compiling, etc.: use cookies on some appropriate node and
245: // use this node as the node selection.
246: /**
247: * Is editable
248: *
249: * @return boolean - true/false
250: */
251: public boolean canEdit() {
252: if (isEditable()) {
253: return true;
254: }
255:
256: String nbBundle5 = mLoc.t(
257: "PRSR001: Please check out {0} before modifying it.",
258: DataObjectProvider.getProvider().getActiveDataObject()
259: .getName());
260: try {
261: String msg = Localizer.parse(nbBundle5);
262: DialogDisplayer.getDefault().notify(
263: new NotifyDescriptor.Message(msg,
264: NotifyDescriptor.INFORMATION_MESSAGE));
265: } catch (Exception ex) {
266: mLogger.errorNoloc(mLoc.t(
267: "PRSR044: Can't get name of data object{0}",
268: DataObjectProvider.getProvider()
269: .getActiveDataObject()), ex);
270: }
271:
272: return false;
273: }
274:
275: /**
276: * Validates the collaboration.
277: */
278: public void doValidation() {
279: try {
280: ETLCollaborationModel collabModel = DataObjectProvider
281: .getProvider().getActiveDataObject().getModel();
282:
283: if (collabModel != null) {
284: validationView.clearView();
285: ETLDefinitionImpl def = collabModel.getETLDefinition();
286: ValidationThread vThread = new ValidationThread(def
287: .getSQLDefinition());
288: vThread.start();
289: }
290: } catch (Exception ex) {
291: mLogger.errorNoloc(mLoc.t(
292: "PRSR045: \nError occurred during validation:{0}",
293: ex.getMessage()), ex);
294: String nbBundle6 = mLoc.t(
295: "PRSR001: \nError occurred during validation: {0}",
296: ex.getMessage());
297: validationView.appendToView(Localizer.parse(nbBundle6));
298: }
299: }
300:
301: /**
302: * Displays dialog box to edit database properties.
303: */
304: public void editDBModel() {
305: String nbBundle7 = mLoc
306: .t("PRSR001: Modify design-time database properties for this session.");
307: JLabel panelTitle = new JLabel(Localizer.parse(nbBundle7));
308: panelTitle.getAccessibleContext().setAccessibleName(
309: Localizer.parse(nbBundle7));
310: panelTitle.setDisplayedMnemonic(Localizer.parse(nbBundle7)
311: .charAt(0));
312: panelTitle.setFont(panelTitle.getFont().deriveFont(Font.BOLD));
313: panelTitle.setFocusable(false);
314: panelTitle.setHorizontalAlignment(SwingConstants.LEADING);
315: dObj = DataObjectProvider.getProvider().getActiveDataObject();
316: editPanel = new EditDBModelPanel(DataObjectProvider
317: .getProvider().getActiveDataObject());
318:
319: JPanel contentPane = new JPanel();
320: contentPane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2,
321: 2));
322: contentPane.setLayout(new BorderLayout());
323: contentPane.add(panelTitle, BorderLayout.NORTH);
324: contentPane.add(editPanel, BorderLayout.CENTER);
325:
326: String nbBundle8 = mLoc.t("PRSR001: Edit Database Properties");
327: DialogDescriptor dd = new DialogDescriptor(contentPane,
328: Localizer.parse(nbBundle8));
329: Dialog dlg = DialogDisplayer.getDefault().createDialog(dd);
330: dlg.getAccessibleContext().setAccessibleDescription(
331: "This is the dialog to edit database properties");
332: dlg.setSize(new Dimension(600, 450));
333: dlg.setVisible(true);
334: if (NotifyDescriptor.OK_OPTION.equals(dd.getValue())) {
335: DBModelTreeView dbModelTreeView = editPanel
336: .getDBModelTreeView();
337: if (dbModelTreeView != null) {
338: IPropertySheet propSheet = dbModelTreeView
339: .getPropSheet();
340: if (propSheet != null) {
341: propSheet.commitChanges();
342: ETLCollaborationModel collabModel = dObj.getModel();
343: collabModel.setDirty(true);
344: ETLCollaborationTopPanel.dObj.getETLEditorSupport()
345: .synchDocument();
346: }
347: }
348: } else {
349: ETLCollaborationModel collabModel = dObj.getModel();
350: collabModel.setDirty(false);
351: }
352: }
353:
354: /**
355: * Gets IGraphNode, if any, associated with the given Object.
356: *
357: * @param dataObj - data object
358: * @return IGraphNode, if any, associated with <code>dataObj</code>
359: */
360: public IGraphNode findGraphNode(Object dataObj) {
361: return etlTopView.findGraphNode(dataObj);
362: }
363:
364: /**
365: * Gets current IGraphView instance.
366: *
367: * @return current IGraphView instance
368: */
369: public IGraphView getGraphView() {
370: return this .etlTopView.getGraphView();
371: }
372:
373: public JToolBar createToolbar() {
374: if (toolBar == null) {
375: IGraphView graphView = getGraphView();
376: etlTopView.enableToolBarActions(true);
377: SQLCollaborationView collabView = etlTopView
378: .getCollaborationView();
379: SQLToolBar sqltoolBar = new SQLToolBar(collabView
380: .getIOperatorManager());
381: sqltoolBar.setGraphView(graphView);
382: sqltoolBar.setActions(etlTopView.getToolBarActions());
383: sqltoolBar.initializeToolBar();
384: toolBar = (JToolBar) sqltoolBar;
385: }
386: return toolBar;
387: }
388:
389: /**
390: * Gets name of operator folder.
391: *
392: * @return name of operator folder
393: */
394: public String getOperatorFolder() {
395: return DEFAULT_OPERATOR_FOLDER;
396: }
397:
398: /**
399: * Gets the zoom factor for this TopComponent.
400: *
401: * @return zoom factor
402: */
403: public double getZoomFactor() {
404: return etlTopView.getZoomFactor();
405: }
406:
407: /**
408: * Is editable
409: *
410: * @return boolean - true/false
411: */
412: public boolean isEditable() {
413: return true;
414: }
415:
416: public void reload() {
417: try {
418: ETLCollaborationModel collabModel = DataObjectProvider
419: .getProvider().getActiveDataObject().getModel();
420: collabModel.getUndoManager().discardAllEdits();
421: // is below required?
422: collabModel.setReloaded(true);
423: populateCanvas(collabModel);
424: } catch (Exception ex) {
425: logReloadException(ex);
426: } finally {
427: resetEditorInEventDispatchThread();
428: }
429: }
430:
431: /**
432: * Reset this view
433: */
434: public void reset() {
435: etlTopView.setModifiable(isEditable());
436: }
437:
438: /**
439: * Executes test run of this ETL Collaboration.
440: */
441: public void run() {
442: Node node = DataObjectProvider.getProvider()
443: .getActiveDataObject().getNodeDelegate();
444: final ExecuteTestCookie testCookie = node
445: .getCookie(ExecuteTestCookie.class);
446:
447: if (testCookie != null) {
448: Runnable run = new Runnable() {
449:
450: public void run() {
451: testCookie.start();
452: }
453: };
454:
455: SwingUtilities.invokeLater(run);
456: }
457: }
458:
459: /**
460: * Displays dialog to select source and target tables.
461: */
462: public void selectTables() {
463: Node node = DataObjectProvider.getProvider()
464: .getActiveDataObject().getNodeDelegate();
465: final SelectTablesCookie selTablesCookie = node
466: .getCookie(SelectTablesCookie.class);
467:
468: if (selTablesCookie != null) {
469: Runnable run = new Runnable() {
470:
471: public void run() {
472: selTablesCookie.showDialog();
473: }
474: };
475:
476: SwingUtilities.invokeLater(run);
477: }
478: }
479:
480: /**
481: * Set editable
482: *
483: * @param edit - true/false
484: */
485: public void setEditable(boolean edit) {
486: //collabView.setEditable(edit);
487: }
488:
489: public void setModifiable(boolean b) {
490: this .etlTopView.setModifiable(b);
491: }
492:
493: /**
494: * Sets the zoom factor
495: *
496: * @param factor new zoom factor
497: */
498: public void setZoomFactor(double factor) {
499: etlTopView.setZoomFactor(factor);
500: }
501:
502: /**
503: * Show log
504: *
505: * @return - ETLLogView
506: */
507: public SQLLogView showLog() {
508: logView.clearView();
509: showSplitPaneView(logView);
510: return logView;
511: }
512:
513: /**
514: * Toggle the output view
515: */
516: public void toggleOutputView() {
517: ETLOutputWindowTopComponent topComp = ETLOutputWindowTopComponent
518: .findInstance();
519: if (topComp.isOpened()) {
520: topComp.close();
521: } else {
522: topComp.open();
523: topComp.requestVisible();
524: topComp.setVisible(true);
525: }
526: }
527:
528: /**
529: * Shows output view in bottom portion of a split pane.
530: *
531: * @param c - component
532: */
533: public void showSplitPaneView(Component c) {
534: etlTopView.showSplitPaneView(c);
535: }
536:
537: // APPEARANCE
538: /**
539: * This method is called from within the constructor to initialize the form. WARNING:
540: * Do NOT modify this code. The content of this method is always regenerated by the
541: * FormEditor.
542: */
543: // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
544: private void initComponents() {
545:
546: setLayout(new java.awt.BorderLayout());
547: }// </editor-fold>//GEN-END:initComponents
548:
549: private void logReloadException(Exception e) {
550: String nbBundle9 = mLoc
551: .t(
552: "PRSR001: Error encountered while loading eTL collaboration {0}",
553: getName());
554: mLogger.errorNoloc(mLoc.t(
555: "PRSR046: Error in executing reload {0}",
556: ETLCollaborationTopPanel.class.getName()), e);
557: NotifyDescriptor d = new NotifyDescriptor.Message(Localizer
558: .parse(nbBundle9), NotifyDescriptor.WARNING_MESSAGE);
559: DialogDisplayer.getDefault().notify(d);
560: }
561:
562: /**
563: * Populates eTL editor canvas using information from given ETLCollaborationModel.
564: *
565: * @param collabModel
566: * @param disableMods
567: * @throws BaseException
568: */
569: private void populateCanvas(ETLCollaborationModel collabModel)
570: throws BaseException {
571: setModifiable(false);
572:
573: this .getGraphView().clearAll();
574: collabModel.restoreUIState();
575: setModifiable(true);
576: }
577:
578: /**
579: * Invokes editor reset in AWT event dispatch thread to ensure Swing-related updates
580: * are correctly handled.
581: */
582: private void resetEditorInEventDispatchThread() {
583: Runnable resetEditor = new Runnable() {
584:
585: public void run() {
586: reset();
587: }
588: };
589: SwingUtilities.invokeLater(resetEditor);
590: }
591:
592: /**
593: * @see reload()
594: */
595: public void refresh() {
596: mLogger.infoNoloc(mLoc.t("PRSR047: Refresh called{0}in {1}",
597: new java.util.Date(), ETLCollaborationTopPanel.class
598: .getName()));
599: this .reload();
600: }
601:
602: private void registerActions() {
603: InputMap im1 = getInputMap(WHEN_FOCUSED);
604: InputMap im2 = getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
605: ActionMap am = getActionMap();
606: CallableSystemAction saveAction = (CallableSystemAction) SystemAction
607: .get(SaveAction.class);
608:
609: im1.put(KeyStroke.getKeyStroke(KeyEvent.VK_S,
610: KeyEvent.CTRL_DOWN_MASK), "Save Collaboration"); // NOI18N
611: im1.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
612: KeyEvent.CTRL_DOWN_MASK), "undo-something"); // NOI18N
613: im1.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y,
614: KeyEvent.CTRL_DOWN_MASK), "redo-something"); // NOI18N
615: im1.put(KeyStroke.getKeyStroke(KeyEvent.VK_P,
616: KeyEvent.CTRL_DOWN_MASK), "Print Collaboration"); // NOI18N
617: im1.put(KeyStroke.getKeyStroke(KeyEvent.VK_T,
618: KeyEvent.CTRL_DOWN_MASK), "run-something"); // NOI18N
619: im2.put(KeyStroke.getKeyStroke(KeyEvent.VK_S,
620: KeyEvent.CTRL_DOWN_MASK), "Save Collaboration"); // NOI18N
621: im2.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
622: KeyEvent.CTRL_DOWN_MASK), "undo-something"); // NOI18N
623: im2.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y,
624: KeyEvent.CTRL_DOWN_MASK), "redo-something"); // NOI18N
625: im2.put(KeyStroke.getKeyStroke(KeyEvent.VK_P,
626: KeyEvent.CTRL_DOWN_MASK), "Print Collaboration"); // NOI18N
627: im2.put(KeyStroke.getKeyStroke(KeyEvent.VK_F6,
628: KeyEvent.SHIFT_DOWN_MASK), "Run Collaboration"); // NOI18N
629: am.put("Save Collaboration", saveAction); // NOI18N
630: am.put("undo-something", new UndoAction());
631: am.put("redo-something", new RedoAction());
632: am.put("Print Collaboration", new PrintAction());
633: am.put("Run Collaboration", new RunAction());
634: }
635:
636: public JComponent getSatelliteView() {
637: GraphView graphView = (GraphView) getGraphView();
638: BirdsEyeView satelliteView = graphView.getSatelliteView();
639: return satelliteView;
640: }
641:
642: public void writeExternal(ObjectOutput out) throws IOException {
643: out.writeObject(dObj);
644: }
645:
646: public void readExternal(ObjectInput in) throws IOException,
647: ClassNotFoundException {
648: dObj = (ETLDataObject) in.readObject();
649: }
650: }
|