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.PropUtil;
028: import org.enhydra.kelp.common.event.WriteListener;
029: import org.enhydra.kelp.common.node.OtterProject;
030: import org.enhydra.kelp.common.swing.ExtensionPanel;
031: import org.enhydra.kelp.common.DirectoryFilter;
032:
033: // ToolBox
034: import org.enhydra.tool.common.DataValidationException;
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.beans.*;
043: import java.io.File;
044: import java.lang.ref.WeakReference;
045: import java.util.Arrays;
046: import javax.swing.*;
047: import javax.swing.border.TitledBorder;
048: import javax.swing.event.ChangeEvent;
049: import javax.swing.event.ChangeListener;
050:
051: // Standard imports
052: import java.util.ResourceBundle;
053:
054: //
055: public class ContentPanel extends JPanel implements Instructor,
056: DeployStep {
057: static ResourceBundle res = ResourceBundle
058: .getBundle("org.enhydra.kelp.common.Res"); // nores
059: private GridBagLayout layoutMain;
060: private JTabbedPane tab;
061: private JPanel panelFiller;
062: private JPanel panelPaths;
063: private ExtensionPanel panelTypes;
064: private GridBagLayout layoutPaths;
065: private GridBagLayout layoutTypes;
066: private JPanel panelSource;
067: private JTextField textSource;
068: private GridBagLayout layoutSource;
069: private JButton buttonSource;
070: private JPanel panelDoc;
071: private GridBagLayout layoutDoc;
072: private JTextField textDoc;
073: private JPanel panelPathsFiller;
074: private JCheckBox checkEnable;
075: private LocalButtonListener buttonListener = null;
076: private LocalCheckListener checkListener = null;
077: private WeakReference projectRef = null;
078: private boolean ran = false;
079:
080: public ContentPanel() {
081: try {
082: jbInit();
083: pmInit();
084: } catch (Exception e) {
085: e.printStackTrace();
086: }
087: }
088:
089: // implements Instructor
090: public String getTab() {
091: return "Content";
092: }
093:
094: // implements Instructor
095: public String getTitle() {
096: return "Web content";
097: }
098:
099: // implements Instructor
100: public String getInstructions() {
101: return "The deployer will copy content types from the content source"
102: + " directory to the archive document root. Use the archive document "
103: + " root to select content when building web application archives.";
104: }
105:
106: // implements DeployStep
107: public void refresh() {
108: if (getProject() != null) {
109: checkEnable.setSelected(getProject().isDeployContent());
110: }
111: privateRefresh();
112: }
113:
114: private void privateRefresh() {
115: boolean enable = checkEnable.isSelected();
116:
117: buttonSource.setEnabled(enable);
118: panelTypes.setEnabled(false);
119: for (int i = 0; i < tab.getTabCount(); i++) {
120: tab.setEnabledAt(i, enable);
121: }
122: if (getProject() != null) {
123: textDoc.setText(PathUtil.getDeployContentPath(getProject(),
124: getProject().getDeployRootPath()));
125: textDoc.setToolTipText(textDoc.getText());
126: }
127: }
128:
129: // implements DeployStep
130: public void clearAll() {
131: checkEnable.removeChangeListener(checkListener);
132: buttonSource.removeActionListener(buttonListener);
133: panelTypes.clearAll();
134: if (projectRef != null) {
135: projectRef.clear();
136: }
137: removeAll();
138: projectRef = null;
139: checkListener = null;
140: buttonListener = null;
141: }
142:
143: // implements DeployStep
144: public boolean isDataValid() {
145: return DeployStepUtil.isDataValid(this );
146: }
147:
148: // implements DeployStep
149: public boolean isDataEqual(OtterProject project) {
150: PathHandle projectPath = null;
151: PathHandle panelPath = null;
152: String[] panelList = null;
153: String[] projectList = null;
154: boolean equal = true;
155:
156: projectRef = new WeakReference(project);
157: if (project == null) {
158: System.err
159: .println("ContentPanel.isDataEqual() - project null");
160: return true;
161: } else if (checkEnable.isSelected() == project
162: .isDeployContent()) {
163: equal = false;
164: }
165: if (equal) {
166: projectPath = PathHandle.createPathHandle(project
167: .getDeployResourcePath());
168: panelPath = PathHandle.createPathHandle(textSource
169: .getText());
170: if (!projectPath.equals(panelPath)) {
171: equal = false;
172: }
173: }
174: if (equal) {
175: panelList = panelTypes.getExtensions();
176: Arrays.sort(panelList);
177: projectList = project.getContentTypes();
178: Arrays.sort(projectList);
179: equal = Arrays.equals(panelList, projectList);
180: }
181: return equal;
182: }
183:
184: // implements DeployStep
185: public void validateData() throws DataValidationException {
186: PathHandle path = null;
187:
188: path = PathHandle.createPathHandle(textSource.getText());
189: if (checkEnable.isSelected()) {
190: if (!path.getPath().equalsIgnoreCase(textSource.getText())) {
191: throw new DataValidationException(
192: "Invalid content source directory: "
193: + textSource.getText());
194: }
195: if (!path.isDirectory()) {
196: throw new DataValidationException(
197: "Invalid content source directory: "
198: + path.getPath());
199: }
200: if (panelTypes.getExtensions().length == 0) {
201: throw new DataValidationException(
202: "No content types defined");
203: }
204: }
205: }
206:
207: // implements DeployStep
208: public boolean isBuilt(OtterProject project) {
209: projectRef = new WeakReference(project);
210: ran = DeployStepUtil.isBuilt(this , ran, project);
211: return ran;
212: }
213:
214: // implements DeployStep
215: public boolean isSelectable(OtterProject project, DeployStep[] steps) {
216: boolean able = false;
217:
218: projectRef = new WeakReference(project);
219: for (int i = 0; i < steps.length; i++) {
220: if (steps[i] instanceof GeneralPanel) {
221: able = steps[i].isBuilt(project);
222: break;
223: }
224: }
225: return able;
226: }
227:
228: // implements DeployStep
229: public void build(OtterProject project, WriteListener listener)
230: throws DataValidationException {
231: ContentBuilder builder = null;
232:
233: projectRef = new WeakReference(project);
234: if (!isBuilt(project)) {
235: write(project);
236: builder = new ContentBuilder(listener);
237: builder.setEcho(true);
238: builder.setProject(project);
239: builder.buildInCurrentThread();
240: ran = true;
241: }
242: }
243:
244: // implements DeployStep
245: public void read(OtterProject project) {
246: PathHandle path = null;
247:
248: projectRef = new WeakReference(project);
249: checkEnable.setSelected(project.isDeployContent());
250: path = PathHandle.createPathHandle(project
251: .getDeployResourcePath());
252: if (path.isDirectory()) {
253: textSource.setText(path.getPath());
254: } else {
255: textSource.setText(new String());
256: }
257: textSource.setToolTipText(textSource.getText());
258: textDoc.setText(PathUtil.getDeployContentPath(project,
259: textSource.getText()));
260: textDoc.setToolTipText(textDoc.getText());
261: panelTypes.setExtensions(project.getContentTypes());
262: panelTypes.setDefaults(PropUtil.getDefaultContentTypes());
263: privateRefresh();
264: }
265:
266: // implements DeployStep
267: public void write(OtterProject project)
268: throws DataValidationException {
269: projectRef = new WeakReference(project);
270: validateData();
271: if (!isDataEqual(project)) {
272: project.setDeployContent(checkEnable.isSelected());
273: project.setDeployResourcePath(PathHandle
274: .createPathString(textSource.getText()));
275: }
276: if (project == null) {
277: System.err.println("ContentPanel.write() - project null");
278: } else {
279: project.setContentTypes(panelTypes.getExtensions());
280: }
281: }
282:
283: //
284: private void chooseSourceDirectory() {
285: File choice = null;
286: PathHandle path = null;
287:
288: choice = SwingUtil.getDirectoryChoice(this , textSource
289: .getText(), "Select content source directory");
290: path = PathHandle.createPathHandle(choice);
291: if (path.isDirectory()) {
292: textSource.setText(path.getPath());
293: textSource.setToolTipText(textSource.getText());
294: privateRefresh();
295: }
296: }
297:
298: private OtterProject getProject() {
299: OtterProject project = null;
300:
301: if (projectRef != null) {
302: project = (OtterProject) projectRef.get();
303: }
304: return project;
305: }
306:
307: private void pmInit() {
308: buttonListener = new LocalButtonListener();
309: buttonSource.addActionListener(buttonListener);
310: checkListener = new LocalCheckListener();
311: checkEnable.addChangeListener(checkListener);
312: }
313:
314: private void jbInit() throws Exception {
315: tab = (JTabbedPane) Beans.instantiate(getClass()
316: .getClassLoader(), JTabbedPane.class.getName());
317: panelFiller = (JPanel) Beans.instantiate(getClass()
318: .getClassLoader(), JPanel.class.getName());
319: panelPaths = (JPanel) Beans.instantiate(getClass()
320: .getClassLoader(), JPanel.class.getName());
321: panelTypes = (ExtensionPanel) Beans.instantiate(getClass()
322: .getClassLoader(), ExtensionPanel.class.getName());
323: layoutPaths = (GridBagLayout) Beans.instantiate(getClass()
324: .getClassLoader(), GridBagLayout.class.getName());
325: layoutTypes = (GridBagLayout) Beans.instantiate(getClass()
326: .getClassLoader(), GridBagLayout.class.getName());
327: panelSource = (JPanel) Beans.instantiate(getClass()
328: .getClassLoader(), JPanel.class.getName());
329: textSource = (JTextField) Beans.instantiate(getClass()
330: .getClassLoader(), JTextField.class.getName());
331: layoutSource = (GridBagLayout) Beans.instantiate(getClass()
332: .getClassLoader(), GridBagLayout.class.getName());
333: buttonSource = (JButton) Beans.instantiate(getClass()
334: .getClassLoader(), JButton.class.getName());
335: panelDoc = (JPanel) Beans.instantiate(getClass()
336: .getClassLoader(), JPanel.class.getName());
337: layoutDoc = (GridBagLayout) Beans.instantiate(getClass()
338: .getClassLoader(), GridBagLayout.class.getName());
339: layoutMain = (GridBagLayout) Beans.instantiate(getClass()
340: .getClassLoader(), GridBagLayout.class.getName());
341: textDoc = (JTextField) Beans.instantiate(getClass()
342: .getClassLoader(), JTextField.class.getName());
343: panelPathsFiller = (JPanel) Beans.instantiate(getClass()
344: .getClassLoader(), JPanel.class.getName());
345: checkEnable = (JCheckBox) Beans.instantiate(getClass()
346: .getClassLoader(), JCheckBox.class.getName());
347: panelPaths.setLayout(layoutPaths);
348: panelTypes.setLayout(layoutTypes);
349: panelSource.setBorder(new TitledBorder(BorderFactory
350: .createEtchedBorder(new Color(187, 218, 252),
351: new Color(91, 107, 123)), "Content source"));
352: panelSource.setLayout(layoutSource);
353: textSource.setEnabled(false);
354: textSource.setEditable(false);
355: textSource.setText("Source ROOT");
356: buttonSource.setText("...");
357: panelDoc.setLayout(layoutDoc);
358: panelDoc.setBorder(new TitledBorder(BorderFactory
359: .createEtchedBorder(new Color(187, 218, 252),
360: new Color(91, 107, 123)),
361: "Archive document root"));
362: textDoc.setEnabled(false);
363: textDoc.setEditable(false);
364: textDoc.setText("DOCUMENT ROOT");
365: checkEnable.setSelected(true);
366: checkEnable.setText("Enable content deployment");
367: panelPaths.add(panelSource, new GridBagConstraints(0, 0, 1, 1,
368: 0.1, 0.0, GridBagConstraints.CENTER,
369: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5),
370: 0, 0));
371: panelSource.add(textSource, new GridBagConstraints(0, 0, 1, 1,
372: 0.8, 0.0, GridBagConstraints.WEST,
373: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 0),
374: 0, 0));
375: panelSource.add(buttonSource, new GridBagConstraints(1, 0, 1,
376: 1, 0.0, 0.0, GridBagConstraints.CENTER,
377: GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
378: panelPaths.add(panelDoc, new GridBagConstraints(0, 1, 1, 1,
379: 0.1, 0.0, GridBagConstraints.CENTER,
380: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5),
381: 0, 0));
382: panelDoc.add(textDoc, new GridBagConstraints(0, 0, 1, 1, 0.1,
383: 0.0, GridBagConstraints.WEST,
384: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 0),
385: 0, 0));
386: panelPaths.add(panelPathsFiller, new GridBagConstraints(0, 2,
387: 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
388: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
389: tab.add(panelPaths, "Paths");
390: tab.add(panelTypes, "Types");
391: this .setLayout(layoutMain);
392: this .add(tab, new GridBagConstraints(0, 1, 3, 1, 0.1, 0.1,
393: GridBagConstraints.CENTER, GridBagConstraints.BOTH,
394: new Insets(0, 0, 0, 0), 0, 0));
395: this .add(panelFiller, new GridBagConstraints(0, 2, 1, 1, 0.0,
396: 0.2, GridBagConstraints.CENTER,
397: GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0,
398: 0));
399: this .add(checkEnable, new GridBagConstraints(0, 0, 1, 1, 0.1,
400: 0.0, GridBagConstraints.WEST,
401: GridBagConstraints.HORIZONTAL,
402: new Insets(2, 10, 2, 10), 0, 0));
403: }
404:
405: //
406: private class LocalButtonListener implements ActionListener {
407: public void actionPerformed(ActionEvent event) {
408: Object source = event.getSource();
409:
410: if (source == buttonSource) {
411: //Dusan 24.11.2002.
412: // chooseSourceDirectory();
413: browseForDirectory();
414: }
415: }
416:
417: }
418:
419: private class LocalCheckListener implements ChangeListener {
420: public void stateChanged(ChangeEvent e) {
421: Object source = e.getSource();
422:
423: if (source == checkEnable) {
424: if (getProject() != null) {
425: getProject().setDeployContent(
426: checkEnable.isSelected());
427: }
428: privateRefresh();
429: }
430: }
431:
432: }
433:
434: /**
435: * Method declaration
436: *
437: */
438: private void browseForDirectory() {
439: JFileChooser chooser;
440: String fileDir = new String();
441: String fileName = new String();
442:
443: chooser = new JFileChooser();
444: if (textSource.getText().trim().length() > 0) {
445: chooser.setCurrentDirectory(new File(textSource.getText()));
446: } else {
447: chooser.setCurrentDirectory(new File(""));
448: }
449: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
450: chooser
451: .setFileFilter((javax.swing.filechooser.FileFilter) new DirectoryFilter());
452: chooser.setDialogTitle(res
453: .getString("chooser_ContentRoot_DialogTitle"));
454: chooser.setApproveButtonText(res.getString("OK"));
455: int v = chooser.showOpenDialog(this );
456:
457: this .requestFocus();
458: buttonSource.requestFocus();
459: if (v == JFileChooser.APPROVE_OPTION) {
460: if (chooser.getSelectedFile() == null) {
461: textSource.setText(new String());
462: } else {
463: fileDir = chooser.getCurrentDirectory().toString();
464: fileDir = stripSlash(fileDir);
465: fileName = chooser.getSelectedFile().getName();
466: String strDeployRoot = fileDir + File.separator
467: + fileName;
468: textSource.setText(strDeployRoot.replace('\\', '/'));
469: }
470: }
471: chooser.removeAll();
472: chooser = null;
473: }
474:
475: /**
476: * Method declaration
477: *
478: *
479: * @param dir
480: *
481: * @return
482: */
483: private String stripSlash(String dir) {
484: String stripped = new String(dir);
485:
486: if (dir != null) {
487: if (dir.length() > 0) {
488: if (dir.endsWith(File.separator)) {
489: stripped = dir.substring(0, dir.length() - 1);
490: }
491: }
492: }
493: return stripped;
494: }
495: }
|