001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: * Paul Mahar
021: *
022: */
023: package org.enhydra.kelp.common.deployer;
024:
025: // AddinCore
026: import org.enhydra.kelp.common.PathUtil;
027: import org.enhydra.kelp.common.event.WriteListener;
028: import org.enhydra.kelp.common.node.OtterProject;
029: import org.enhydra.kelp.common.swing.OutputPanel;
030: import org.enhydra.kelp.common.DirectoryFilter;
031:
032: // ToolBox
033: import org.enhydra.tool.common.DataValidationException;
034: import org.enhydra.tool.common.ExtensionFilter;
035: import org.enhydra.tool.common.PathHandle;
036: import org.enhydra.tool.common.SwingUtil;
037:
038: // JDK
039: import java.awt.*;
040: import java.awt.event.ActionEvent;
041: import java.awt.event.ActionListener;
042: import java.awt.event.ItemEvent;
043: import java.awt.event.ItemListener;
044: import java.io.File;
045: import java.lang.ref.WeakReference;
046: import javax.swing.*;
047: import javax.swing.border.EtchedBorder;
048: import javax.swing.event.ChangeEvent;
049: import javax.swing.event.ChangeListener;
050: import java.beans.*;
051:
052: // Standard imports
053: import java.util.ResourceBundle;
054:
055: //
056: public class GeneralPanel extends JPanel implements Instructor,
057: DeployStep {
058:
059: static ResourceBundle res = ResourceBundle
060: .getBundle("org.enhydra.kelp.common.Res"); // nores
061: private GridBagLayout layoutMain;
062: private JCheckBox checkDeployBuild;
063: private JPanel panelDeployRoot;
064: private GridBagLayout layoutDeployRoot;
065: private JTextField textDeployRoot;
066: private JButton buttonDeployRoot;
067: private JPanel panelMessage;
068: private JPanel panelFiller;
069: private JCheckBox checkWriteMessage;
070: private JTextField textOutputFilename;
071: private JButton buttonMessage;
072: private JCheckBox checkEcho;
073: private JCheckBox checkOverwrite;
074: private JTabbedPane tabMessage;
075: private JPanel panelMessageOption;
076: private OutputPanel outputPanel;
077: private GridBagLayout layoutMessageOption;
078: private BorderLayout layoutMessage;
079: private LocalButtonListener buttonListener = null;
080: private LocalCheckListener checkListener = null;
081: private LocalComboListener comboListener = null;
082: private boolean ran = false;
083: private JPanel panelType;
084: private JComboBox comboType;
085: private WeakReference projectRef = null;
086: private GridBagLayout layoutType;
087:
088: public GeneralPanel() {
089: try {
090: jbInit();
091: pmInit();
092: } catch (Exception e) {
093: e.printStackTrace();
094: }
095: }
096:
097: // implements Instructor
098: public String getTab() {
099: return "General";
100: }
101:
102: // implements Instructor
103: public String getTitle() {
104: return "General deployment options";
105: }
106:
107: // implements Instructor
108: public String getInstructions() {
109: return "Messaging options control how status messages are handled during deployment.";
110: }
111:
112: // implements DeployStep
113: public void refresh() {
114:
115: // nothing to refresh
116: }
117:
118: // implements DeployStep
119: public void clearAll() {
120: buttonDeployRoot.removeActionListener(buttonListener);
121: buttonMessage.removeActionListener(buttonListener);
122: checkWriteMessage.removeChangeListener(checkListener);
123: outputPanel.clearAll();
124: removeAll();
125: buttonListener = null;
126: checkListener = null;
127: }
128:
129: // implements DeployStep
130: public boolean isDataValid() {
131: return DeployStepUtil.isDataValid(this );
132: }
133:
134: // implements DeployStep
135: public boolean isDataEqual(OtterProject project) {
136: PathHandle projectPath = null;
137: PathHandle panelPath = null;
138: boolean equal = true;
139:
140: projectRef = new WeakReference(project);
141: if (project == null) {
142: System.err
143: .println("GeneralPanel.isDataEqual() - project null");
144: return true;
145: } else if (checkOverwrite.isSelected() != project
146: .isDeployOverwrite()) {
147: equal = false;
148: } else if (checkEcho.isSelected() != project.isDeployEcho()) {
149: equal = false;
150: } else if (checkDeployBuild.isSelected() != project
151: .isDeployBuild()) {
152: equal = false;
153: }
154: if (equal) {
155: projectPath = PathHandle.createPathHandle(project
156: .getOutputFilename());
157: panelPath = PathHandle.createPathHandle(textOutputFilename
158: .getText());
159: if (!projectPath.equals(panelPath)) {
160: equal = false;
161: }
162: }
163: if (equal) {
164: projectPath = PathHandle.createPathHandle(project
165: .getDeployRootPath());
166: panelPath = PathHandle.createPathHandle(textDeployRoot
167: .getText());
168: if (!projectPath.equals(panelPath)) {
169: equal = false;
170: }
171: }
172: return equal;
173: }
174:
175: // implements DeployStep
176: public void validateData() throws DataValidationException {
177: PathHandle path = null;
178:
179: if (checkWriteMessage.isSelected()) {
180: path = PathHandle.createPathHandle(textOutputFilename
181: .getText());
182: if (!isValidLogFile(path)) {
183: throw new DataValidationException(
184: "Invalid message log: " + path.getPath());
185: }
186: }
187: path = PathHandle.createPathHandle(textDeployRoot.getText());
188: if (!path.getPath().equals(textDeployRoot.getText())) {
189: throw new DataValidationException("Invalid deploy root: "
190: + textDeployRoot.getText());
191: }
192: if (!isValidDeployRoot(path)) {
193: throw new DataValidationException("Invalid deploy root: "
194: + textDeployRoot.getText());
195: }
196: }
197:
198: // implements DeployStep
199: public boolean isBuilt(OtterProject project) {
200: projectRef = new WeakReference(project);
201: ran = DeployStepUtil.isBuilt(this , ran, project);
202: return ran;
203: }
204:
205: // implements DeployStep
206: public boolean isSelectable(OtterProject project, DeployStep[] steps) {
207: projectRef = new WeakReference(project);
208: return true;
209: }
210:
211: // implements DeployStep
212: public void build(OtterProject project, WriteListener listener)
213: throws DataValidationException {
214: projectRef = new WeakReference(project);
215: if (!isBuilt(project)) {
216: write(project);
217: DeployBuilder.preBuild(this , project, listener);
218: ran = true;
219: }
220: }
221:
222: // implements DeployStep
223: public void read(OtterProject project) {
224: PathHandle path = null;
225: int type = -1;
226:
227: projectRef = new WeakReference(project);
228: checkOverwrite.setSelected(project.isDeployOverwrite());
229: checkEcho.setSelected(project.isDeployEcho());
230: checkDeployBuild.setSelected(project.isDeployBuild());
231: type = project.getDeployType();
232: if ((type > -1) && (type < comboType.getItemCount())) {
233: comboType.setSelectedIndex(type);
234: }
235: path = PathHandle.createPathHandle(project.getOutputFilename());
236: if (isValidLogFile(path)) {
237: checkWriteMessage.setSelected(true);
238: textOutputFilename.setText(path.getPath());
239: } else {
240: checkWriteMessage.setSelected(false);
241: textOutputFilename.setText(new String());
242: }
243: textOutputFilename.setToolTipText(textOutputFilename.getText());
244: path = PathHandle.createPathHandle(project.getDeployRootPath());
245: if (isValidDeployRoot(path)) {
246: textDeployRoot.setText(path.getPath());
247: } else {
248: textDeployRoot.setText(new String());
249: }
250: textDeployRoot.setToolTipText(textDeployRoot.getText());
251: }
252:
253: // implements DeployStep
254: public void write(OtterProject project)
255: throws DataValidationException {
256: projectRef = new WeakReference(project);
257: validateData();
258: if (!isDataEqual(project)) {
259: project.setDeployOverwrite(checkOverwrite.isSelected());
260: project.setDeployEcho(checkEcho.isSelected());
261: if (checkWriteMessage.isSelected()) {
262: project
263: .setOutputFilename(PathHandle
264: .createPathString(textOutputFilename
265: .getText()));
266: }
267: project.setDeployRootPath(PathHandle
268: .createPathString(textDeployRoot.getText()));
269: project.setDeployBuild(checkDeployBuild.isSelected());
270:
271: // deploy type auto-updated
272: }
273: }
274:
275: //
276: protected WriteListener getWriteListener() {
277: return outputPanel;
278: }
279:
280: protected Component[] getFirstFocusComponents() {
281: Component[] comps = new Component[6];
282:
283: comps[0] = buttonDeployRoot;
284: comps[1] = tabMessage;
285: comps[2] = checkDeployBuild;
286: comps[3] = checkWriteMessage;
287: comps[4] = checkEcho;
288: comps[5] = checkOverwrite;
289: return comps;
290: }
291:
292: //
293: private boolean isValidDeployRoot(PathHandle ph) {
294: boolean valid = false;
295:
296: if (!ph.isFile()) {
297: if (ph.getParent() != null) {
298: valid = ph.getParent().isDirectory();
299: }
300: }
301: return valid;
302: }
303:
304: private boolean isValidLogFile(PathHandle ph) {
305: boolean valid = false;
306:
307: if (ph.hasExtension("txt")) {
308: if (ph.isFile()) {
309: valid = true;
310: } else if (ph.getParent() != null) {
311: valid = ph.getParent().isDirectory();
312: }
313: }
314: return valid;
315: }
316:
317: //Dusan 24.11.2002.
318: /* private void chooseDeployRoot() {
319: File choice = null;
320: PathHandle path = null;
321:
322: choice =
323: SwingUtil.getDirectoryChoice(this, textDeployRoot.getText(),
324: "Select deployment root directory");
325: path = PathHandle.createPathHandle(choice);
326: if (path.isDirectory()) {
327: textDeployRoot.setText(path.getPath());
328: textDeployRoot.setToolTipText(textDeployRoot.getText());
329: }
330: }
331: */
332: private void chooseMessageFile() {
333: File choice = null;
334: PathHandle path = null;
335: ExtensionFilter filter = null;
336:
337: filter = new ExtensionFilter();
338: filter.setDescriptionTitle("Message Log");
339: filter.addExtension("txt");
340: choice = SwingUtil.getFileChoice(this , textOutputFilename
341: .getText(), filter,
342: "Select or enter a message log file");
343: path = PathHandle.createPathHandle(choice);
344: if (!path.isDirectory()) {
345: if (!path.hasExtension("txt")) {
346: path.setExtension("txt");
347: }
348: textOutputFilename.setText(path.getPath());
349: textOutputFilename.setToolTipText(textOutputFilename
350: .getText());
351: }
352: }
353:
354: private void checkWriteRefresh() {
355: boolean write = checkWriteMessage.isSelected();
356:
357: buttonMessage.setEnabled(write);
358: if (write) {
359: textOutputFilename.setBackground(SystemColor.info);
360: } else {
361: textOutputFilename.setBackground(SystemColor.control);
362: }
363: }
364:
365: private void pmInit() {
366: buttonListener = new LocalButtonListener();
367: buttonDeployRoot.addActionListener(buttonListener);
368: buttonMessage.addActionListener(buttonListener);
369:
370: //
371: checkListener = new LocalCheckListener();
372: checkWriteMessage.addChangeListener(checkListener);
373: outputPanel.setRows(4);
374:
375: //
376: comboListener = new LocalComboListener();
377: comboType.removeAllItems();
378: comboType.addItem("Web Application");
379: // comboType.addItem("Enhydra Service");
380: comboType.addItem("Enhydra Application");
381: comboType.setSelectedIndex(0);
382: comboType.addItemListener(comboListener);
383: }
384:
385: private void jbInit() throws Exception {
386: panelDeployRoot = (JPanel) Beans.instantiate(getClass()
387: .getClassLoader(), JPanel.class.getName());
388: layoutDeployRoot = (GridBagLayout) Beans.instantiate(getClass()
389: .getClassLoader(), GridBagLayout.class.getName());
390:
391: textDeployRoot = (JTextField) Beans.instantiate(getClass()
392: .getClassLoader(), JTextField.class.getName());
393: buttonDeployRoot = (JButton) Beans.instantiate(getClass()
394: .getClassLoader(), JButton.class.getName());
395: panelMessage = (JPanel) Beans.instantiate(getClass()
396: .getClassLoader(), JPanel.class.getName());
397: panelFiller = (JPanel) Beans.instantiate(getClass()
398: .getClassLoader(), JPanel.class.getName());
399: checkWriteMessage = (JCheckBox) Beans.instantiate(getClass()
400: .getClassLoader(), JCheckBox.class.getName());
401: checkOverwrite = (JCheckBox) Beans.instantiate(getClass()
402: .getClassLoader(), JCheckBox.class.getName());
403: textOutputFilename = (JTextField) Beans.instantiate(getClass()
404: .getClassLoader(), JTextField.class.getName());
405: buttonMessage = (JButton) Beans.instantiate(getClass()
406: .getClassLoader(), JButton.class.getName());
407: checkEcho = (JCheckBox) Beans.instantiate(getClass()
408: .getClassLoader(), JCheckBox.class.getName());
409: checkDeployBuild = (JCheckBox) Beans.instantiate(getClass()
410: .getClassLoader(), JCheckBox.class.getName());
411: layoutMain = (GridBagLayout) Beans.instantiate(getClass()
412: .getClassLoader(), GridBagLayout.class.getName());
413: tabMessage = (JTabbedPane) Beans.instantiate(getClass()
414: .getClassLoader(), JTabbedPane.class.getName());
415: panelMessageOption = (JPanel) Beans.instantiate(getClass()
416: .getClassLoader(), JPanel.class.getName());
417: outputPanel = (OutputPanel) Beans.instantiate(getClass()
418: .getClassLoader(), OutputPanel.class.getName());
419: layoutMessageOption = (GridBagLayout) Beans.instantiate(
420: getClass().getClassLoader(), GridBagLayout.class
421: .getName());
422: layoutMessage = (BorderLayout) Beans.instantiate(getClass()
423: .getClassLoader(), BorderLayout.class.getName());
424: panelType = (JPanel) Beans.instantiate(getClass()
425: .getClassLoader(), JPanel.class.getName());
426: comboType = (JComboBox) Beans.instantiate(getClass()
427: .getClassLoader(), JComboBox.class.getName());
428: layoutType = (GridBagLayout) Beans.instantiate(getClass()
429: .getClassLoader(), GridBagLayout.class.getName());
430: checkDeployBuild.setText("Deploy during project make/rebuild");
431: textDeployRoot.setEnabled(false);
432: textDeployRoot.setEditable(false);
433: textDeployRoot.setText("DEPLOY ROOT");
434: buttonDeployRoot.setText("...");
435: checkWriteMessage.setText("Write to file");
436: textOutputFilename.setEnabled(false);
437: textOutputFilename.setEditable(false);
438: textOutputFilename.setText("MESSAGE LOG");
439: buttonMessage.setText("...");
440: checkEcho.setText("Display during project make/rebuild");
441: panelDeployRoot.setLayout(layoutDeployRoot);
442: panelDeployRoot.setBorder(BorderFactory.createTitledBorder(
443: new EtchedBorder(), "Deploy root"));
444: checkOverwrite.setText("Overwrite without warning");
445: panelMessageOption.setLayout(layoutMessageOption);
446: panelType.setLayout(layoutType);
447: panelDeployRoot.add(textDeployRoot, new GridBagConstraints(0,
448: 0, 1, 1, 0.8, 0.0, GridBagConstraints.WEST,
449: GridBagConstraints.HORIZONTAL, new Insets(3, 5, 3, 5),
450: 0, 0));
451: panelDeployRoot.add(buttonDeployRoot, new GridBagConstraints(1,
452: 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
453: GridBagConstraints.NONE, new Insets(3, 5, 3, 5), 0, 0));
454: panelMessage.setLayout(layoutMessage);
455: panelMessage.setBorder(BorderFactory.createTitledBorder(
456: new EtchedBorder(), "Deploy messages"));
457: panelMessageOption.add(checkWriteMessage,
458: new GridBagConstraints(0, 2, 2, 1, 0.1, 0.0,
459: GridBagConstraints.WEST,
460: GridBagConstraints.HORIZONTAL, new Insets(0, 5,
461: 2, 5), 0, 0));
462: panelMessageOption.add(textOutputFilename,
463: new GridBagConstraints(0, 3, 1, 1, 0.9, 0.0,
464: GridBagConstraints.CENTER,
465: GridBagConstraints.HORIZONTAL, new Insets(2, 5,
466: 3, 5), 0, 0));
467: panelMessageOption.add(buttonMessage, new GridBagConstraints(1,
468: 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
469: GridBagConstraints.NONE, new Insets(2, 5, 3, 5), 0, 0));
470: panelMessageOption.add(checkEcho, new GridBagConstraints(0, 1,
471: 2, 1, 0.1, 0.0, GridBagConstraints.CENTER,
472: GridBagConstraints.HORIZONTAL, new Insets(3, 5, 3, 5),
473: 0, 0));
474: panelMessage.add(tabMessage, BorderLayout.CENTER);
475: tabMessage.add(outputPanel, "Messages");
476: tabMessage.add(panelMessageOption, "Options");
477: panelType.setBorder((BorderFactory.createTitledBorder(
478: new EtchedBorder(), "Deploy type")));
479: panelType.add(comboType, new GridBagConstraints(0, 0, 1, 1,
480: 0.1, 0.0, GridBagConstraints.CENTER,
481: GridBagConstraints.HORIZONTAL, new Insets(2, 5, 2, 5),
482: 0, 0));
483: this .setLayout(layoutMain);
484: this .add(panelFiller, new GridBagConstraints(0, 6, 1, 1, 0.1,
485: 0.01, GridBagConstraints.CENTER,
486: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
487: this .add(checkDeployBuild, new GridBagConstraints(0, 3, 1, 1,
488: 0.0, 0.0, GridBagConstraints.WEST,
489: GridBagConstraints.HORIZONTAL,
490: new Insets(2, 10, 2, 10), 0, 0));
491: this .add(panelMessage, new GridBagConstraints(0, 2, 2, 1, 0.1,
492: 0.0, GridBagConstraints.CENTER,
493: GridBagConstraints.HORIZONTAL, new Insets(2, 5, 2, 5),
494: 0, 0));
495: this .add(panelDeployRoot, new GridBagConstraints(0, 0, 2, 1,
496: 0.1, 0.0, GridBagConstraints.CENTER,
497: GridBagConstraints.HORIZONTAL, new Insets(2, 5, 2, 5),
498: 0, 0));
499: this .add(checkOverwrite, new GridBagConstraints(1, 3, 1, 1,
500: 0.1, 0.0, GridBagConstraints.CENTER,
501: GridBagConstraints.HORIZONTAL,
502: new Insets(2, 10, 2, 10), 0, 0));
503: this .add(panelType, new GridBagConstraints(0, 1, 2, 1, 0.0,
504: 0.0, GridBagConstraints.CENTER,
505: GridBagConstraints.HORIZONTAL, new Insets(2, 5, 2, 5),
506: 2, 0));
507: }
508:
509: //
510: private class LocalCheckListener implements ChangeListener {
511: public void stateChanged(ChangeEvent e) {
512: Object source = e.getSource();
513:
514: if (source == checkWriteMessage) {
515: checkWriteRefresh();
516: }
517: }
518:
519: }
520:
521: //
522: private class LocalButtonListener implements ActionListener {
523: public void actionPerformed(ActionEvent event) {
524: Object source = event.getSource();
525:
526: if (source == buttonDeployRoot) {
527: //Dusan 24.11.2002.
528: // chooseDeployRoot();
529: browseForDirectory();
530: } else if (source == buttonMessage) {
531: chooseMessageFile();
532: }
533: }
534:
535: }
536:
537: private void saveType() {
538: OtterProject project = null;
539: int newType = OtterProject.TYPE_UNKNOWN;
540: int oldType = OtterProject.TYPE_UNKNOWN;
541:
542: if (projectRef != null) {
543: project = (OtterProject) projectRef.get();
544: newType = comboType.getSelectedIndex();
545: oldType = project.getDeployType();
546: if (newType != oldType) {
547: //Dusan
548: // project.setDeployType(newType);
549: //Dusan
550: /* if (newType == OtterProject.TYPE_SERVICE) {
551: project.setDeployContent(false);
552: project.setDeployInput(false);
553: } else if (oldType == OtterProject.TYPE_SERVICE) {
554: project.setDeployContent(true);
555: project.setDeployInput(true);
556: } */
557:
558: //Dusan
559: if (newType == OtterProject.TYPE_WEBAPP) {
560: comboType.setSelectedIndex(1);
561: } else if (oldType == OtterProject.TYPE_EN3APP) {
562: project.setDeployType(newType);
563: project.setDeployContent(false);
564: project.setDeployInput(false);
565: }
566:
567: project.setDeployBootstrapPath(PathUtil
568: .getAutoDeployPath(newType));
569: }
570: }
571: }
572:
573: private class LocalComboListener implements ItemListener {
574: public void itemStateChanged(ItemEvent event) {
575: if (event.getStateChange() == ItemEvent.SELECTED) {
576: saveType();
577: }
578: }
579:
580: }
581:
582: /**
583: * Method declaration
584: *
585: */
586: private void browseForDirectory() {
587: JFileChooser chooser;
588: String fileDir = new String();
589: String fileName = new String();
590:
591: chooser = new JFileChooser();
592: if (textDeployRoot.getText().trim().length() > 0) {
593: chooser.setCurrentDirectory(new File(textDeployRoot
594: .getText()));
595: } else {
596: chooser.setCurrentDirectory(new File(""));
597: }
598: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
599: chooser
600: .setFileFilter((javax.swing.filechooser.FileFilter) new DirectoryFilter());
601: chooser.setDialogTitle(res
602: .getString("chooser_DeployRoot_DialogTitle"));
603: chooser.setApproveButtonText(res.getString("OK"));
604: int v = chooser.showOpenDialog(this );
605:
606: this .requestFocus();
607: buttonDeployRoot.requestFocus();
608: if (v == JFileChooser.APPROVE_OPTION) {
609: if (chooser.getSelectedFile() == null) {
610: textDeployRoot.setText(new String());
611: } else {
612: fileDir = chooser.getCurrentDirectory().toString();
613: fileDir = stripSlash(fileDir);
614: fileName = chooser.getSelectedFile().getName();
615: String strDeployRoot = fileDir + File.separator
616: + fileName;
617: textDeployRoot
618: .setText(strDeployRoot.replace('\\', '/'));
619: }
620: }
621: chooser.removeAll();
622: chooser = null;
623: }
624:
625: /**
626: * Method declaration
627: *
628: *
629: * @param dir
630: *
631: * @return
632: */
633: private String stripSlash(String dir) {
634: String stripped = new String(dir);
635:
636: if (dir != null) {
637: if (dir.length() > 0) {
638: if (dir.endsWith(File.separator)) {
639: stripped = dir.substring(0, dir.length() - 1);
640: }
641: }
642: }
643: return stripped;
644: }
645: }
|