001: package com.xoetrope.carousel.services.dialog;
002:
003: import com.xoetrope.carousel.services.RouteManager;
004:
005: import java.awt.BorderLayout;
006: import java.awt.GridLayout;
007: import java.awt.Color;
008: import java.awt.Dimension;
009: import java.awt.Rectangle;
010: import java.awt.event.ActionEvent;
011: import java.awt.event.ActionListener;
012: import java.awt.event.ItemEvent;
013: import java.awt.event.ItemListener;
014: import java.io.BufferedReader;
015: import java.io.BufferedWriter;
016: import java.io.File;
017: import java.io.FileReader;
018: import java.io.FileWriter;
019: import javax.swing.BorderFactory;
020: import javax.swing.DefaultListModel;
021: import javax.swing.JButton;
022: import javax.swing.JCheckBox;
023: import javax.swing.JComboBox;
024: import javax.swing.JDialog;
025: import javax.swing.JLabel;
026: import javax.swing.JList;
027: import javax.swing.JPanel;
028: import javax.swing.JTextField;
029: import net.xoetrope.editor.XEditorUtilities;
030: import net.xoetrope.editor.project.XEditorProject;
031: import net.xoetrope.editor.project.XEditorProjectManager;
032: import net.xoetrope.xui.data.XBaseModel;
033:
034: /**
035: * Dialog to allow developer to create their own custom ServiceProxy classes.
036: * These can subclass the ServiceProxy class directly or subclass any of the
037: * existing classes
038: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
039: * the GNU Public License (GPL), please see license.txt for more details. If
040: * you make commercial use of this software you must purchase a commercial
041: * license from Xoetrope.</p>
042: * <p> $Revision: 1.6 $</p>
043: * @author val
044: */
045: public class NewRouteDlg extends JDialog implements ActionListener,
046: ItemListener {
047: private JComboBox cmbLayerType, cmbClassType;
048: JList lstAttribs, lstInheritedAttribs;
049: DefaultListModel attribsListMdl, inheritedAttribsListMdl;
050: JButton btnOK, btnCancel, btnAddAttrib, btnRemoveAttrib;
051: JTextField newClassName, attribName;
052: JCheckBox chkCreate;
053: boolean okClicked;
054: private RouteManager routeMgr;
055: private final String BASE_NONE = "[NONE]";
056:
057: /**
058: * The owner project and the context in which this object operates.
059: */
060: protected XEditorProject currentProject = (XEditorProject) XEditorProjectManager
061: .getCurrentProject();
062:
063: /**
064: * Creates a new instance of NewRouteDlg and obtain a reference to the current
065: * XEditorProject.
066: */
067: public NewRouteDlg() {
068: currentProject = (XEditorProject) XEditorProjectManager
069: .getCurrentProject();
070: }
071:
072: /**
073: * Method to be called from the RouteDataEditor class. The screen is
074: * constructed, the combos are populated, the dialog is set to modal and
075: * then set to visible. When OK or Cancel are clicked the result of that
076: * click is passed back to the calling class.
077: * @param routeManager the RouteManager object for the current projects
078: * @baseClass If this dialog is presented in order to subclass an abstract
079: * class the subclass needs to be set automatically in the combo
080: * @return true if OK was clicked otherwise false
081: */
082: public boolean setupNewRoute(RouteManager routeManager,
083: String baseClass) {
084: routeMgr = routeManager;
085: constructScreen();
086: XBaseModel table = routeManager.getRouteDefs();
087: cmbLayerType.addItem(BASE_NONE);
088: for (int i = 0; i < table.getNumChildren(); i++) {
089: XBaseModel route = (XBaseModel) table.get(i);
090: cmbLayerType.addItem(route.getId());
091: }
092: if (baseClass != null)
093: cmbLayerType.setSelectedItem(baseClass);
094: cmbClassType.addItem("");
095: cmbClassType.addItem("abstract");
096: cmbClassType.addItem("clientEndPoint");
097: setSize(430, 320);
098: setTitle("New ServiceProxy");
099: setModal(true);
100: centerScreen();
101: setVisible(true);
102: return okClicked;
103: }
104:
105: /*
106: * Construct the screen
107: */
108: private void constructScreen() {
109: setLayout(new BorderLayout());
110:
111: JPanel topPanel = new JPanel(new GridLayout(3, 2));
112: JLabel lblNewClassName = new JLabel("Class name:");
113: lblNewClassName.setPreferredSize(new Dimension(100, 20));
114: newClassName = new JTextField();
115: newClassName.setText(currentProject.getPackageName()
116: + ".service.");
117: topPanel.add(lblNewClassName);
118: topPanel.add(newClassName);
119:
120: JLabel lblBase = new JLabel("Base Class:");
121: lblBase.setPreferredSize(new Dimension(100, 20));
122: cmbLayerType = new JComboBox();
123: cmbLayerType.addItemListener(this );
124: topPanel.add(lblBase);
125: topPanel.add(cmbLayerType);
126:
127: JLabel lblType = new JLabel("Class type:");
128: lblType.setPreferredSize(new Dimension(100, 20));
129: cmbClassType = new JComboBox();
130: topPanel.add(lblType);
131: topPanel.add(cmbClassType);
132: add(topPanel, BorderLayout.NORTH);
133:
134: JPanel attribsPnl = new JPanel(new BorderLayout());
135: attribsPnl.setBorder(BorderFactory
136: .createLineBorder(Color.black));
137: JLabel lblAttribs = new JLabel("Attributes");
138: lblAttribs.setHorizontalAlignment(JLabel.CENTER);
139:
140: // inherited attribs
141: JLabel inheritedLbl = new JLabel("Inherited");
142: JPanel inheritPnl = new JPanel(new BorderLayout());
143: inheritedAttribsListMdl = new DefaultListModel();
144: lstInheritedAttribs = new JList(inheritedAttribsListMdl);
145: lstInheritedAttribs.setBorder(BorderFactory
146: .createLineBorder(Color.black));
147:
148: inheritPnl.add(inheritedLbl, BorderLayout.NORTH);
149: inheritPnl.add(lstInheritedAttribs, BorderLayout.CENTER);
150:
151: // attribs
152: JPanel customPanel = new JPanel(new BorderLayout());
153: JLabel customLbl = new JLabel("Custom");
154: attribsListMdl = new DefaultListModel();
155: lstAttribs = new JList(attribsListMdl);
156: lstAttribs.setBorder(BorderFactory
157: .createLineBorder(Color.black));
158: JPanel customBtmPnl = new JPanel(new BorderLayout());
159: attribName = new JTextField();
160: btnAddAttrib = new JButton("Add");
161: btnAddAttrib.addActionListener(this );
162: btnRemoveAttrib = new JButton("Remove");
163: btnRemoveAttrib.addActionListener(this );
164:
165: customBtmPnl.add(btnRemoveAttrib, BorderLayout.NORTH);
166: customBtmPnl.add(attribName, BorderLayout.CENTER);
167: customBtmPnl.add(btnAddAttrib, BorderLayout.EAST);
168: customPanel.add(customLbl, BorderLayout.NORTH);
169: customPanel.add(lstAttribs, BorderLayout.CENTER);
170: customPanel.add(customBtmPnl, BorderLayout.SOUTH);
171: attribsPnl.add(lblAttribs, BorderLayout.NORTH);
172: inheritPnl.setPreferredSize(new Dimension(120, 100));
173: attribsPnl.add(inheritPnl, BorderLayout.WEST);
174: attribsPnl.add(customPanel, BorderLayout.CENTER);
175: add(attribsPnl, BorderLayout.CENTER);
176:
177: JPanel bottomPanel = new JPanel();
178: chkCreate = new JCheckBox("Create the class");
179: chkCreate.setBounds(100, 230, 300, 20);
180: bottomPanel.add(chkCreate);
181:
182: btnOK = new JButton("OK");
183: btnOK.setBounds(100, 260, 80, 20);
184: btnCancel = new JButton("Cancel");
185: btnCancel.setBounds(220, 260, 80, 20);
186: btnOK.addActionListener(this );
187: btnCancel.addActionListener(this );
188: bottomPanel.add(btnOK);
189: bottomPanel.add(btnCancel);
190: add(bottomPanel, BorderLayout.SOUTH);
191: }
192:
193: /*
194: * Retrieve the name of the new class as entered by the user
195: * @return String containing the name of the new class
196: */
197: public String getNewClassName() {
198: return newClassName.getText();
199: }
200:
201: /*
202: * Retrieve the class type as selected in the classtype combo
203: * @return String containing the class type
204: */
205: public String getClassType() {
206: return (String) cmbClassType.getSelectedItem();
207: }
208:
209: /*
210: * Retrieve the base class name as selected in the layer type combo. If
211: * '[NONE]' is selected then return null
212: * @return String containing the base class name or null if none is selected
213: */
214: public String getBaseClass() {
215: String baseClass = (String) cmbLayerType.getSelectedItem();
216: if (baseClass.compareTo(BASE_NONE) == 0)
217: return null;
218: else
219: return (String) cmbLayerType.getSelectedItem();
220: }
221:
222: /**
223: * Retrieve an array of the custom attribs for this newly defined ServiceProxy
224: * @return String array containing the custom attributes
225: */
226: public String[] getAttribs() {
227: String[] attribs = new String[attribsListMdl.size()];
228: attribsListMdl.copyInto(attribs);
229: return attribs;
230: }
231:
232: /*
233: * Handle clicks for OK, Cancel, Add attrib, Remove attrib buttons
234: */
235: public void actionPerformed(ActionEvent ae) {
236: if (ae.getSource().equals(btnOK)) {
237: okClicked = true;
238: if (chkCreate.isSelected())
239: createSourceFile();
240: setVisible(false);
241: } else if (ae.getSource().equals(btnCancel)) {
242: okClicked = false;
243: setVisible(false);
244: } else if (ae.getSource().equals(btnAddAttrib)) {
245: String newAttrib = attribName.getText().trim();
246: if (newAttrib.length() > 0) {
247: for (int i = 0; i < attribsListMdl.size(); i++) {
248: if (attribsListMdl.elementAt(i).toString()
249: .compareTo(newAttrib) == 0)
250: return;
251: }
252:
253: for (int i = 0; i < inheritedAttribsListMdl.size(); i++) {
254: if (inheritedAttribsListMdl.elementAt(i).toString()
255: .compareTo(newAttrib) == 0)
256: return;
257: }
258:
259: attribsListMdl.addElement(attribName.getText());
260: lstAttribs.updateUI();
261: attribName.setText("");
262: }
263: } else if (ae.getSource().equals(btnRemoveAttrib)) {
264: if (lstAttribs.getSelectedIndex() > -1)
265: attribsListMdl.remove(lstAttribs.getSelectedIndex());
266: }
267: }
268:
269: /**
270: * Handle changes in the selection of the base class. Clear the inherited
271: * attribs model and populate it with attributes from the selected route
272: * definition.
273: */
274: public void itemStateChanged(ItemEvent ie) {
275: inheritedAttribsListMdl.clear();
276: String baseClassName = (String) ie.getItem();
277: XBaseModel mdl = (XBaseModel) routeMgr.getRouteDefs().get(
278: baseClassName);
279: if (mdl.getNumChildren() > 0) {
280: XBaseModel attribsMdl = (XBaseModel) mdl.get(0);
281: for (int i = 0; i < attribsMdl.getNumChildren(); i++) {
282: String id = attribsMdl.get(i).getId();
283: inheritedAttribsListMdl.addElement(id);
284: }
285: }
286: lstInheritedAttribs.updateUI();
287: }
288:
289: /**
290: * Center the dialog
291: */
292: public void centerScreen() {
293: Dimension dim = getToolkit().getScreenSize();
294: Rectangle abounds = getBounds();
295: setLocation((dim.width - abounds.width) / 2,
296: (dim.height - abounds.height) / 2);
297: }
298:
299: /**
300: * If the create checkbox is selected copy the ServiceProxy template file to
301: * the appropriate package and change the class and package names
302: */
303: public void createSourceFile() {
304: String packageName = getPackageName();
305: String className = getJavaSourceFileName();
306: String path = currentProject.getPath() + "\\src\\"
307: + packageName.replace(".", "\\") + "\\" + className
308: + ".java";
309: XEditorUtilities
310: .copyFile(
311: currentProject,
312: "com/xoetrope/carousel/resources/routes/ServiceProxy.javax",
313: path);
314: changeClassName(path, packageName, className);
315: openSourceFile(path);
316: }
317:
318: /**
319: * When a template file is created we need to change the class name and the
320: * ctor. These are specified in the source by 'NEW_CLASS_NAME',
321: * 'PROJECT_PACKAGE_NAME'
322: * @param path The path to the copied file
323: * @param packageName The name of the package to be set in the new file
324: * @param className The name of the new class
325: */
326: public void changeClassName(String path, String packageName,
327: String className) {
328: try {
329: BufferedReader in = new BufferedReader(new FileReader(path));
330: String temp = in.readLine();
331: StringBuffer sb = new StringBuffer("");
332:
333: while (temp != null) {
334: sb.append(temp + "\n");
335: temp = in.readLine();
336: }
337:
338: in.close();
339: temp = sb.toString();
340: if (packageName != null)
341: temp = temp.replaceAll("PROJECT_PACKAGE_NAME",
342: "package " + packageName + ";");
343: else
344: temp = temp.replaceAll("PROJECT_PACKAGE_NAME", "");
345:
346: temp = temp.replaceAll("NEW_CLASS_NAME", className);
347:
348: String super Class = (String) cmbLayerType.getSelectedItem();
349: String importClass = "";
350: String extendsClass = "ServiceProxy";
351: if (super Class.compareTo(BASE_NONE) != 0) {
352: importClass = "import " + super Class + ";";
353: extendsClass = super Class.substring(super Class
354: .lastIndexOf(".") + 1, super Class.length());
355: }
356:
357: temp = temp.replaceAll("IMPORT_SUPER", importClass);
358: temp = temp.replaceAll("SUPER_CLASS", extendsClass);
359:
360: BufferedWriter out = new BufferedWriter(
361: new FileWriter(path));
362: out.write(temp, 0, temp.length());
363: out.flush();
364: out.close();
365: } catch (Exception ex) {
366: ex.printStackTrace();
367: }
368: }
369:
370: /**
371: * Parse the new class and package name textfield and return the package name
372: * @return the name of the pagkage
373: */
374: private String getPackageName() {
375: String temp = newClassName.getText();
376: int pos = temp.lastIndexOf(".");
377: if (pos > -1) {
378: return temp.substring(0, pos);
379: }
380: return null;
381: }
382:
383: /**
384: * Parse the new class and package name and return the file name
385: * @return String containing the name of the java file
386: */
387: private String getJavaSourceFileName() {
388: String temp = newClassName.getText();
389: int pos = temp.lastIndexOf(".");
390: if (pos > -1) {
391: return temp.substring(pos + 1, temp.length());
392: } else {
393: return temp;
394: }
395: }
396:
397: private void openSourceFile(String file) {
398: currentProject.getEditorUtility().openSourceFile(
399: currentProject, null, file);
400: }
401: }
|