001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: // Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: // This program is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU General Public License version 2
007: // as published by the Free Software Foundation;
008: //
009: // This program is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: // For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020:
021: package com.salmonllc.ideTools;
022:
023: import java.awt.Container;
024: import java.awt.Dimension;
025: import java.awt.Frame;
026: import java.awt.Rectangle;
027: import java.awt.Toolkit;
028: import java.awt.event.ActionEvent;
029: import java.awt.event.ActionListener;
030: import java.io.File;
031: import java.io.IOException;
032: import java.util.Enumeration;
033: import java.util.Hashtable;
034:
035: import javax.swing.Box;
036: import javax.swing.BoxLayout;
037: import javax.swing.Icon;
038: import javax.swing.ImageIcon;
039: import javax.swing.JDialog;
040: import javax.swing.JFileChooser;
041: import javax.swing.JOptionPane;
042: import javax.swing.JPanel;
043: import javax.swing.JScrollPane;
044:
045: import com.salmonllc.properties.Props;
046: import com.salmonllc.sitemap.SiteMap;
047: import com.salmonllc.sql.DataStoreBuffer;
048: import com.salmonllc.sql.DataStoreException;
049: import com.salmonllc.sql.ModelChangedEvent;
050: import com.salmonllc.sql.ModelChangedListener;
051: import com.salmonllc.swing.SButton;
052: import com.salmonllc.swing.SCheckBox;
053: import com.salmonllc.swing.SComboBox;
054: import com.salmonllc.swing.SComponentHelper;
055: import com.salmonllc.swing.SOption;
056: import com.salmonllc.swing.STable;
057:
058: /**
059: * IDE Tool to edit a project site map
060: */
061: public class SiteMapDialog extends JDialog implements
062: ModelChangedListener {
063: private SiteMapModel _mod;
064: private SiteMapActionModel _actMod;
065: private ActionDialog _actDialog;
066:
067: private STable _tab;
068: private STable _actTab;
069: private SButton _add, _delete, _save, _export, _lookup, _actions,
070: _cancel;
071: private SComboBox _entryNames;
072: private SiteMapDialog _this = this ;
073: private String _exportClassName = "";
074:
075: private static final String COL_NAME = "name";
076: private static final String COL_COTXT = "context";
077: private static final String COL_URI = "uri";
078: private static final String COL_SECURE = "secure";
079: private static final String COL_FORWARD = "forward";
080: private static final String COL_POPUP = "popup";
081: private static final String COL_ACTION_NAME = "actionName";
082: private static final String COL_ACTION_ENTRY = "actionEntry";
083:
084: private class ActionDialog extends JDialog implements
085: ActionListener {
086: private SButton _addAction, _delAction, _okAction,
087: _cancelAction;
088: private boolean _okClicked = false;
089:
090: public ActionDialog(Frame owner) {
091: super (owner, "Site Map Actions", true);
092: setModal(true);
093: setResizable(false);
094: int width = 500;
095: int height = 300;
096: Dimension frameBounds = Toolkit.getDefaultToolkit()
097: .getScreenSize();
098: int x = (frameBounds.width - width) / 2;
099: int y = (frameBounds.height - height) / 2;
100: setBounds(x, y, width, height);
101: Container cp = getContentPane();
102: cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
103:
104: _actTab = new STable();
105: _actTab.setDataStore(_actMod);
106: try {
107: _actTab.addEditColumn(COL_ACTION_NAME, "Name");
108: _actTab.addEditColumn(COL_ACTION_ENTRY, "Entry",
109: _entryNames);
110:
111: } catch (Exception ex) {
112: ex.printStackTrace();
113: }
114: JScrollPane sp = new JScrollPane(_actTab);
115: cp.add(sp);
116: cp.add(Box.createRigidArea(new Dimension(0, 20)));
117:
118: JPanel buttonBar = new JPanel();
119: buttonBar.setLayout(new BoxLayout(buttonBar,
120: BoxLayout.X_AXIS));
121: buttonBar.add(_addAction = new SButton("Add"));
122: buttonBar.add(_delAction = new SButton("Delete"));
123: buttonBar.add(Box.createRigidArea(new Dimension(10, 0)));
124: buttonBar.add(_okAction = new SButton("OK"));
125: buttonBar.add(_cancelAction = new SButton("Cancel"));
126: cp.add(buttonBar);
127: cp.add(Box.createRigidArea(new Dimension(0, 20)));
128: _addAction
129: .addActionListener(new AddAction(_actMod, _actTab));
130: _delAction.addActionListener(new DeleteAction(_actMod));
131: _cancelAction.addActionListener(new CancelAction(this ));
132: _okAction.addActionListener(this );
133: }
134:
135: public void display() {
136: _okClicked = false;
137: setVisible(true);
138: _actTab.revalidate();
139: _actTab.repaint();
140: }
141:
142: public boolean getOKClicked() {
143: return _okClicked;
144: }
145:
146: public void actionPerformed(ActionEvent e) {
147: SComponentHelper.acceptCurrentValue();
148: for (int i = 0; i < _actMod.getRowCount(); i++) {
149: DataStoreException ex[] = _actMod.validateRow(i, null);
150: if (ex.length > 0) {
151: IDETool.displayError(ex[0].getMessage(), false);
152: _actMod.gotoRow(i);
153: _actTab.editCellAt(i, _actMod.getColumnIndex(ex[0]
154: .getColumn()) - 1);
155: return;
156: }
157: }
158:
159: _okClicked = true;
160: setVisible(false);
161: }
162: }
163:
164: private class SiteMapActionModel extends DataStoreBuffer {
165: public SiteMapActionModel() {
166: addBucket(COL_NAME, DataStoreBuffer.DATATYPE_STRING);
167: addBucket(COL_ACTION_NAME, DataStoreBuffer.DATATYPE_STRING);
168: addBucket(COL_ACTION_ENTRY, DataStoreBuffer.DATATYPE_STRING);
169:
170: try {
171: addExpressionRule(COL_ACTION_NAME, COL_ACTION_NAME
172: + " != null",
173: "Action name Cannot Be Left Blank!");
174: addExpressionRule(COL_ACTION_ENTRY, COL_ACTION_ENTRY
175: + " != null",
176: "Action Entry Cannot Be Left Blank!");
177: } catch (DataStoreException e) {
178: e.printStackTrace();
179: }
180: }
181:
182: }
183:
184: private class SiteMapModel extends DataStoreBuffer {
185: String _appName;
186:
187: public SiteMapModel(String appName) {
188: _appName = appName;
189:
190: addBucket(COL_URI, DataStoreBuffer.DATATYPE_STRING);
191: addBucket(COL_NAME, DataStoreBuffer.DATATYPE_STRING);
192: addBucket(COL_SECURE, DataStoreBuffer.DATATYPE_INT);
193: addBucket(COL_FORWARD, DataStoreBuffer.DATATYPE_INT);
194: addBucket(COL_POPUP, DataStoreBuffer.DATATYPE_STRING);
195: addBucket(COL_COTXT, DataStoreBuffer.DATATYPE_STRING);
196: try {
197: addExpressionRule(COL_NAME, COL_NAME + " != null",
198: "Name Cannot Be Left Blank!");
199: addExpressionRule(COL_URI, COL_URI + " != null",
200: "URI Cannot Be Left Blank!");
201: } catch (DataStoreException e) {
202: e.printStackTrace();
203: }
204: }
205:
206: public void retrieve(SiteMap map) {
207: reset();
208: Enumeration en = map.getEntryNames();
209: while (en.hasMoreElements()) {
210: String name = (String) en.nextElement();
211: insertRow();
212: try {
213: setString(COL_NAME, name);
214: setString(COL_URI, map.getURI(name));
215: setInt(COL_SECURE, map.isSecure(name) ? 1 : 0);
216: setInt(COL_FORWARD, map.useForward(name) ? 1 : 0);
217: setString(COL_POPUP, map.getPopupFeatures(name));
218: setString(COL_COTXT, map.getContext(name));
219: String actions[] = map.getActionEntries(name);
220: for (int i = 0; i < actions.length; i++) {
221: String entry = map.getActionEntry(name,
222: actions[i]);
223: _actMod.insertRow();
224: _actMod.setString(COL_NAME, name);
225: _actMod.setString(COL_ACTION_NAME, actions[i]);
226: _actMod.setString(COL_ACTION_ENTRY, entry);
227: }
228: } catch (Exception e) {
229: }
230: }
231: }
232:
233: public SiteMap update(boolean doUpdate)
234: throws DataStoreException, IOException {
235: SiteMap map = new SiteMap(_appName);
236: for (int i = 0; i < getRowCount(); i++) {
237: gotoRow(i);
238: map.putEntry(getString(COL_NAME), getString(COL_URI),
239: getString(COL_POPUP),
240: getInt(COL_FORWARD) == 1 ? true : false,
241: getInt(COL_SECURE) == 1 ? true : false,
242: getString(COL_COTXT));
243: }
244: _actMod.filter(null);
245: for (int i = 0; i < _actMod.getRowCount(); i++) {
246: _actMod.gotoRow(i);
247: map.addActionEntry(_actMod.getString(COL_NAME), _actMod
248: .getString(COL_ACTION_NAME), _actMod
249: .getString(COL_ACTION_ENTRY));
250: }
251: if (doUpdate)
252: map.update();
253: return map;
254: }
255: }
256:
257: private class AddAction implements ActionListener {
258: DataStoreBuffer _ds;
259: STable _table;
260:
261: public AddAction(DataStoreBuffer ds, STable tab) {
262: _ds = ds;
263: _table = tab;
264: }
265:
266: public void actionPerformed(ActionEvent e) {
267: _ds.insertRow();
268: if (_ds == _actMod) {
269: try {
270: _actMod.setString(COL_NAME, _mod
271: .getString(COL_NAME));
272: } catch (DataStoreException e1) {
273: e1.printStackTrace();
274: }
275: }
276: _table.editCellAt(_ds.getRow(), 0);
277: }
278: }
279:
280: private class CancelAction implements ActionListener {
281: JDialog _diag;
282:
283: public CancelAction(JDialog d) {
284: _diag = d;
285: }
286:
287: public void actionPerformed(ActionEvent e) {
288: _diag.setVisible(false);
289: }
290: }
291:
292: private class AddActionsAction implements ActionListener {
293: public void actionPerformed(ActionEvent e) {
294: Object oldValues[] = null;
295: try {
296: String name = _mod.getString(COL_NAME);
297: _actDialog.setTitle("Actions for:" + name);
298: _actMod.filter(COL_NAME + " == null");
299: _actMod.filter(COL_NAME + " == '" + name + "'");
300: oldValues = new Object[_actMod.getRowCount()];
301: for (int i = 0; i < _actMod.getRowCount(); i++) {
302: String row[] = new String[3];
303: row[0] = _actMod.getString(i, 0);
304: row[1] = _actMod.getString(i, 1);
305: row[2] = _actMod.getString(i, 2);
306: oldValues[i] = row;
307: }
308: _actMod.sort(COL_ACTION_NAME, DataStoreBuffer.SORT_ASC);
309: _entryNames.removeAllItems();
310: for (int i = 0; i < _mod.getRowCount(); i++)
311: _entryNames.addItem(new SOption(_mod.getString(i,
312: COL_NAME), _mod.getString(i, COL_NAME)));
313:
314: } catch (DataStoreException e1) {
315: e1.printStackTrace();
316: }
317:
318: _actDialog.display();
319: SComponentHelper.acceptCurrentValue();
320:
321: if (!_actDialog.getOKClicked()) {
322: for (int i = _actMod.getRowCount() - 1; i >= 0; i--)
323: _actMod.removeRow(i);
324: try {
325: for (int i = 0; i < oldValues.length; i++) {
326: _actMod.insertRow();
327: String row[] = (String[]) oldValues[i];
328: _actMod.setString(0, row[0]);
329: _actMod.setString(1, row[1]);
330: _actMod.setString(2, row[2]);
331: }
332: } catch (DataStoreException e1) {
333: e1.printStackTrace();
334: }
335: }
336:
337: }
338: }
339:
340: private class DeleteAction implements ActionListener {
341: DataStoreBuffer _ds;
342:
343: public DeleteAction(DataStoreBuffer ds) {
344: _ds = ds;
345: }
346:
347: public void actionPerformed(ActionEvent e) {
348: if (_ds.getRow() > -1)
349: _ds.deleteRow();
350: }
351: }
352:
353: private class SaveAction implements ActionListener {
354: public void actionPerformed(ActionEvent e) {
355: if (save())
356: setVisible(false);
357: }
358:
359: public boolean save() {
360: for (int i = 0; i < _mod.getRowCount(); i++) {
361: DataStoreException ex[] = _mod.validateRow(i, null);
362: if (ex.length > 0) {
363: IDETool.displayError(ex[0].getMessage(), false);
364: _mod.gotoRow(i);
365: _tab.editCellAt(i, _mod.getColumnIndex(ex[0]
366: .getColumn()));
367: return false;
368: }
369: }
370: try {
371: _mod.update(true);
372: return true;
373: } catch (Exception e1) {
374: e1.printStackTrace();
375: return false;
376: }
377: }
378: }
379:
380: private class LookupAction implements ActionListener {
381: public void actionPerformed(ActionEvent e) {
382: JFileChooser c = new JFileChooser();
383: String defaultPath = Props
384: .getSystemProps()
385: .getProperty(
386: IDETool
387: .getProjectProperty(Props.IDE_DEFAULT_SOURCE_PATH));
388: if (IDETool.getDocumentRoot() != null)
389: defaultPath = IDETool.getDocumentRoot();
390: c.setCurrentDirectory(new File(defaultPath));
391: c.setDialogTitle("Choose File Or Folder");
392: c.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
393: if (c.showSaveDialog(_this ) == JFileChooser.APPROVE_OPTION) {
394: String defaultWebApp = Props
395: .getSystemProps()
396: .getProperty(
397: IDETool
398: .getProjectProperty(Props.IDE_WEB_APP));
399: String path = c.getSelectedFile().getAbsolutePath();
400: int pos = path.indexOf(defaultWebApp + File.separator);
401: if (pos > -1) {
402: path = path.substring(pos + defaultWebApp.length());
403: StringBuffer sb = new StringBuffer(path.length());
404: for (int i = 0; i < path.length(); i++) {
405: char ch = path.charAt(i);
406: if (ch == File.separatorChar)
407: sb.append("/");
408: else
409: sb.append(ch);
410: }
411: path = sb.toString();
412: }
413: try {
414: _mod.setString(COL_URI, path);
415: _tab.editCellAt(_mod.getRow(), 1);
416: } catch (DataStoreException e1) {
417: e1.printStackTrace();
418: }
419: }
420: }
421: }
422:
423: private class ExportAction implements ActionListener {
424: private String _appName;
425:
426: public ExportAction(String appName) {
427: _appName = appName;
428: }
429:
430: public void actionPerformed(ActionEvent e) {
431: boolean loop = true;
432:
433: if (!new SaveAction().save())
434: return;
435:
436: while (loop) {
437: String exportClassName = JOptionPane
438: .showInputDialog(
439: _this ,
440: "Please enter the class name for the generated constants:",
441: _exportClassName,
442: JOptionPane.QUESTION_MESSAGE);
443: if (exportClassName == null)
444: return;
445: _exportClassName = exportClassName;
446: if (exportClassName.trim().length() == 0)
447: JOptionPane.showMessageDialog(_this ,
448: "Please Fill in an class name.");
449: else if (exportClassName.indexOf(".") == -1)
450: JOptionPane.showMessageDialog(_this ,
451: "Class name must include a package name.");
452: else if (exportClassName.indexOf(" ") != -1)
453: JOptionPane.showMessageDialog(_this ,
454: "Class name cannot include spaces.");
455: else {
456: SiteMap map;
457: try {
458: map = _mod.update(false);
459: String interfaceString = map
460: .generateConstants(exportClassName);
461: Hashtable props = new Hashtable();
462: props.put(_appName + "."
463: + Props.IDE_SITE_MAP_INTERFACE,
464: exportClassName);
465: Props.updateSystemProperties(props);
466: int pos = exportClassName.lastIndexOf(".");
467: String clazz = exportClassName
468: .substring(pos + 1);
469: String packag = exportClassName.substring(0,
470: pos);
471: String fileName = IDETool.genClassFileName(
472: packag, clazz, IDETool
473: .getDefaultSourcePath(),
474: IDETool.getDefaultFwApp(), IDETool
475: .getDontAppendProject());
476: if (IDETool
477: .saveClass(fileName, interfaceString)) {
478: loop = false;
479: setVisible(false);
480: }
481: } catch (Exception e1) {
482: e1.printStackTrace();
483: }
484: }
485: }
486: }
487: }
488:
489: public SiteMapDialog(Frame owner) {
490: super (owner, "Site Map", true);
491:
492: _entryNames = new SComboBox();
493: _entryNames.setEditable(true);
494: String app = Props
495: .getSystemProps()
496: .getProperty(
497: IDETool
498: .getProjectProperty(Props.IDE_DEFAULT_FRAMEWORK_APP));
499: setTitle("Site Map for " + app);
500: _exportClassName = Props
501: .getSystemProps()
502: .getProperty(
503: IDETool
504: .getProjectProperty(Props.IDE_SITE_MAP_INTERFACE),
505: "");
506: IDETool.setPropsPath();
507: _mod = new SiteMapModel(app);
508: _mod.addModelChangedListener(this );
509:
510: _actMod = new SiteMapActionModel();
511: _actMod.addModelChangedListener(this );
512:
513: _actDialog = new ActionDialog(owner);
514:
515: setModal(true);
516: setResizable(false);
517: int width = 780;
518: int height = 400;
519: Dimension frameBounds = Toolkit.getDefaultToolkit()
520: .getScreenSize();
521: int x = (frameBounds.width - width) / 2;
522: int y = (frameBounds.height - height) / 2;
523: setBounds(x, y, width, height);
524: Container cp = getContentPane();
525: cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
526:
527: _tab = new STable();
528: _tab.setDataStore(_mod);
529: try {
530: _tab.addEditColumn(COL_URI, "URI");
531: _tab.addEditColumn(COL_NAME, "Logical Name");
532: _tab.addEditColumn(COL_POPUP, "Popup Features");
533: SCheckBox cbx = new SCheckBox();
534: cbx.setTrueValue("1");
535:
536: _tab.addEditColumn(COL_FORWARD, "Use Forward", cbx);
537: _tab.addEditColumn(COL_SECURE, "Secure", cbx);
538: _tab.addEditColumn(COL_COTXT, "Context");
539:
540: _tab.setColumnWidth(COL_URI, 200);
541: _tab.setColumnWidth(COL_NAME, 200);
542: _tab.setColumnWidth(COL_POPUP, 200);
543: _tab.setColumnWidth(COL_FORWARD, 80);
544: _tab.setColumnWidth(COL_SECURE, 80);
545: _tab.setColumnWidth(COL_COTXT, 100);
546:
547: Icon errorIcon = null;
548: try {
549: errorIcon = new ImageIcon(getClass().getResource(
550: "error.gif"));
551: } catch (Exception e) {
552: }
553:
554: _tab.addColumnValidations(_tab.getTableColumn(1), COL_NAME,
555: errorIcon);
556: _tab.addColumnValidations(_tab.getTableColumn(0), COL_URI,
557: errorIcon);
558:
559: _actTab.addColumnValidations(_actTab.getTableColumn(0),
560: COL_ACTION_NAME, errorIcon);
561: _actTab.addColumnValidations(_actTab.getTableColumn(1),
562: COL_ACTION_ENTRY, errorIcon);
563: JScrollPane sp = new JScrollPane(_tab);
564: cp.add(sp);
565: } catch (DataStoreException e) {
566: e.printStackTrace();
567: }
568:
569: JPanel buttonBar = new JPanel();
570: buttonBar.setLayout(new BoxLayout(buttonBar, BoxLayout.X_AXIS));
571: buttonBar.add(_add = new SButton("Add"));
572: buttonBar.add(_delete = new SButton("Delete"));
573: buttonBar.add(_lookup = new SButton("URI Lookup"));
574: buttonBar.add(_actions = new SButton("Actions"));
575: buttonBar.add(Box.createRigidArea(new Dimension(20, 0)));
576: buttonBar.add(_export = new SButton("Generate Constants"));
577: buttonBar.add(Box.createRigidArea(new Dimension(20, 0)));
578: buttonBar.add(_save = new SButton("Save"));
579: buttonBar.add(_cancel = new SButton("Cancel"));
580: _add.addActionListener(new AddAction(_mod, _tab));
581: _delete.addActionListener(new DeleteAction(_mod));
582: _save.addActionListener(new SaveAction());
583: _lookup.addActionListener(new LookupAction());
584: _export.addActionListener(new ExportAction(app));
585: _actions.addActionListener(new AddActionsAction());
586: _cancel.addActionListener(new CancelAction(this ));
587:
588: cp.add(Box.createRigidArea(new Dimension(0, 10)));
589: cp.add(buttonBar);
590: cp.add(Box.createRigidArea(new Dimension(0, 10)));
591:
592: _mod.retrieve(SiteMap.getSiteMap(app));
593: _save.setEnabled(false);
594:
595: if (_mod.gotoFirst()) {
596: _tab.editCellAt(0, 0);
597: _tab.getEditorComponent().requestFocus();
598: }
599: _tab.scrollRectToVisible(new Rectangle(0, 0, 0, 0));
600: }
601:
602: /**
603: * Handles stuff when the model changes
604: */
605: public void modelChanged(ModelChangedEvent evt) {
606: _delete.setEnabled(_mod.getRowCount() > 0);
607: _lookup.setEnabled(_mod.getRowCount() > 0);
608: _export.setEnabled(_mod.getRowCount() > 0);
609: _actions.setEnabled(_mod.getRowCount() > 0);
610:
611: if (evt.getType() == ModelChangedEvent.TYPE_DATA_CHANGED
612: || evt.getType() == ModelChangedEvent.TYPE_ROW_INSERTED_OR_DELETED)
613: _save.setEnabled(_mod.getRowCount() > 0);
614:
615: }
616: }
|