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: /*
042: * AddEjbGroupDialog.java
043: *
044: * Created on May 5, 2004, 12:31 PM
045: */
046:
047: package org.netbeans.modules.visualweb.ejb.ui;
048:
049: import javax.swing.event.ChangeEvent;
050: import org.netbeans.modules.visualweb.ejb.datamodel.EjbDataModel;
051: import org.netbeans.modules.visualweb.ejb.datamodel.EjbGroup;
052: import org.netbeans.modules.visualweb.ejb.datamodel.EjbInfo;
053: import org.netbeans.modules.visualweb.ejb.datamodel.MethodInfo;
054: import org.netbeans.modules.visualweb.ejb.load.EjbLoadException;
055: import org.netbeans.modules.visualweb.ejb.load.EjbLoader;
056: import java.awt.Dialog;
057: import java.text.MessageFormat;
058: import java.util.*;
059: import javax.swing.event.ChangeListener;
060: import org.openide.DialogDisplayer;
061: import org.openide.NotifyDescriptor;
062: import org.openide.WizardDescriptor;
063: import org.openide.util.HelpCtx;
064: import org.openide.util.NbBundle;
065:
066: /**
067: * The dialog for adding a new EJB group. The dialog contains a two steps wizard.
068: * The first step gathers data for the EJBs to be added. The second step is to configure
069: * the business methods of the EJBs.
070: *
071: * @author cao
072: */
073: public class AddEjbGroupDialog {
074:
075: /** See org.openide.WizardDescriptor.PROP_AUTO_WIZARD_STYLE
076: */
077: private static final String PROP_AUTO_WIZARD_STYLE = "WizardPanel_autoWizardStyle"; // NOI18N
078: /** See org.openide.WizardDescriptor.PROP_CONTENT_DISPLAYED
079: */
080: private static final String PROP_CONTENT_DISPLAYED = "WizardPanel_contentDisplayed"; // NOI18N
081: /** See org.openide.WizardDescriptor.PROP_CONTENT_NUMBERED
082: */
083: private static final String PROP_CONTENT_NUMBERED = "WizardPanel_contentNumbered"; // NOI18N
084: /** See org.openide.WizardDescriptor.PROP_CONTENT_SELECTED_INDEX
085: */
086: private static final String PROP_CONTENT_SELECTED_INDEX = "WizardPanel_contentSelectedIndex"; // NOI18N
087: /** See org.openide.WizardDescriptor.PROP_HELP_DISPLAYED
088: */
089: private static final String PROP_HELP_DISPLAYED = "WizardPanel_helpDisplayed"; // NOI18N
090: /** See org.openide.WizardDescriptor.PROP_CONTENT_DATA
091: */
092: private static final String PROP_CONTENT_DATA = "WizardPanel_contentData"; // NOI18N
093:
094: private EjbWizardDescriptor wizardDescriptor;
095: private Dialog dialog;
096:
097: private EjbGroupPanel addPanel;
098: private ConfigureMethodsPanel configureMethodsPanel;
099:
100: private EjbGroup ejbGroup;
101: private EjbLoader ejbLoader;
102:
103: private boolean valid = true;
104: private AddEjbsWizardPanel addWizardPanel;
105: private ConfigureMethodWizardPanel configWizardPanel;
106:
107: public AddEjbGroupDialog() {
108:
109: // The first wizard panel
110: addPanel = new EjbGroupPanel();
111: addWizardPanel = new AddEjbsWizardPanel();
112:
113: addPanel.addChangeListener(addWizardPanel);
114: // The second wizard panel
115: configWizardPanel = new ConfigureMethodWizardPanel();
116:
117: // Create the wizard descriptor
118: WizardDescriptor.Panel[] wizardPanels = new WizardDescriptor.Panel[] {
119: addWizardPanel, configWizardPanel };
120: wizardDescriptor = new EjbWizardDescriptor(wizardPanels);
121:
122: // The following properties are need in order to get the content panel on the left side
123: wizardDescriptor.putProperty(PROP_AUTO_WIZARD_STYLE,
124: Boolean.TRUE);
125: wizardDescriptor.putProperty(PROP_CONTENT_DISPLAYED,
126: Boolean.TRUE);
127: wizardDescriptor.putProperty(PROP_CONTENT_NUMBERED,
128: Boolean.TRUE);
129: wizardDescriptor.putProperty(PROP_CONTENT_DATA, new String[] {
130: NbBundle.getMessage(AddEjbGroupDialog.class,
131: "ADD_EJB_GROUP"),
132: NbBundle.getMessage(AddEjbGroupDialog.class,
133: "CONFIGURE_METHODS") });
134: wizardDescriptor.setTitleFormat(new MessageFormat("{0}")); // NOI18N
135:
136: // Create the dialog
137: dialog = DialogDisplayer.getDefault().createDialog(
138: wizardDescriptor);
139: dialog.setTitle(NbBundle.getMessage(AddEjbGroupDialog.class,
140: "ADD_EJB_GROUP"));
141: dialog.setResizable(true);
142: dialog.pack();
143: }
144:
145: public void showDialog() {
146: dialog.setVisible(true);
147: }
148:
149: private String loadingEjbGroup() {
150: // Make sure the user has entered all the required data
151: StringBuffer errorMessage = new StringBuffer();
152: if (!addPanel.validateData(errorMessage)) {
153: return errorMessage.toString();
154: }
155:
156: // Get all the user input from the inner panel
157: ejbGroup = new EjbGroup();
158: ejbGroup.setName(addPanel.getGroupName());
159: ejbGroup.setClientJarFiles(addPanel.getClientJars());
160: ejbGroup.setAppServerVendor(addPanel.getContainerType());
161: ejbGroup.setServerHost(addPanel.getServerHost());
162: ejbGroup.setIIOPPort(Integer.parseInt(addPanel.getIIOPPort()));
163: ejbGroup.setDDLocationFile(addPanel.getDDLocationFile());
164:
165: // Check whether the client jar files are already added with
166: // different information (i.e. hostname, iiop port)
167: String check = checkClientJarInfo(ejbGroup);
168: if (check != null) {
169: return check;
170: }
171:
172: try {
173: // Try to load the EjbGroup
174: ejbLoader = new EjbLoader(ejbGroup);
175: ejbLoader.load();
176:
177: // Good, the ejbs are loaded ok
178: return null;
179: } catch (EjbLoadException ex) {
180: String msg = ex.getMessage();
181:
182: // SYSTEM_EXCEPTION means something out of user's control. It should never happen. But it did
183: if (ex.getExceptionType() == EjbLoadException.SYSTEM_EXCEPTION)
184: msg = NbBundle.getMessage(AddEjbGroupDialog.class,
185: "FAILED_TO_LOAD_EJBS", ejbGroup.getName());
186:
187: return msg;
188: }
189: }
190:
191: private boolean createEjbGroup() {
192: try {
193:
194: ejbLoader.createWrapperClientBeans();
195: EjbDataModel.getInstance().addEjbGroup(ejbGroup);
196:
197: return true;
198:
199: } catch (EjbLoadException ex) {
200: // Popup error message here to ask the them give correct information
201:
202: String msg = ex.getMessage();
203:
204: // SYSTEM_EXCEPTION means something out of user's control. It should never happen. But it did
205: if (ex.getExceptionType() == EjbLoadException.SYSTEM_EXCEPTION)
206: msg = NbBundle.getMessage(AddEjbGroupDialog.class,
207: "FAILED_TO_LOAD_EJBS", ejbGroup.getName());
208:
209: if (ex.getExceptionType() != EjbLoadException.WARNING) {
210: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
211: NotifyDescriptor.ERROR_MESSAGE);
212: DialogDisplayer.getDefault().notify(d);
213: } else {
214: // Just a warning. Need to continue on with the operation
215: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
216: NotifyDescriptor.INFORMATION_MESSAGE);
217: DialogDisplayer.getDefault().notify(d);
218: }
219:
220: return false;
221: }
222: }
223:
224: private String checkClientJarInfo(EjbGroup grp) {
225: StringBuffer msg = new StringBuffer();
226:
227: for (Iterator iter = grp.getClientJarFileNames().iterator(); iter
228: .hasNext();) {
229: String jar = (String) iter.next();
230:
231: EjbGroup existingGrpWithJar = EjbDataModel.getInstance()
232: .findEjbGroupForJar(jar);
233:
234: if (existingGrpWithJar != null
235: && (!existingGrpWithJar.getAppServerVendor()
236: .equals(grp.getAppServerVendor()) || (!existingGrpWithJar
237: .getServerHost()
238: .equals(grp.getServerHost()) || existingGrpWithJar
239: .getIIOPPort() != grp.getIIOPPort()))) {
240: // Found a group containing the client jar with different information
241: // Client Jar {0} was added in EJB set {1} with different server host name and/or RMI IIOP port.
242: msg.append(NbBundle.getMessage(AddEjbGroupDialog.class,
243: "MISMATCH_INFO_JAR", jar, existingGrpWithJar
244: .getName()));
245: msg.append("\n");
246: }
247: }
248:
249: if (msg.length() != 0) {
250: return msg.toString();
251: } else
252: return null;
253: }
254:
255: private boolean checkColElemClasses() {
256: boolean allSet = true;
257: ArrayList invalidMethodNames = new ArrayList();
258:
259: // Make sure all the collection element classes are specified
260: for (Iterator iter = ejbGroup.getSessionBeans().iterator(); iter
261: .hasNext();) {
262: EjbInfo ejbInfo = (EjbInfo) iter.next();
263:
264: for (Iterator mIter = ejbInfo.getMethods().iterator(); mIter
265: .hasNext();) {
266: MethodInfo methodInfo = (MethodInfo) mIter.next();
267:
268: if (!methodInfo.isBusinessMethod()
269: || (methodInfo.isBusinessMethod() && !methodInfo
270: .getReturnType().isCollection()))
271: continue;
272: else {
273: // Check whether the element class is set
274: if (methodInfo.getReturnType().getElemClassName() == null) {
275: invalidMethodNames.add(methodInfo.getName());
276: allSet = false;
277: }
278: }
279: }
280:
281: }
282:
283: // TODO: need to figure out the method names and have the first one selected
284: if (!allSet) {
285: NotifyDescriptor d = new NotifyDescriptor.Message(
286: "One or more collection element types are not specified: "
287: + invalidMethodNames.toString());
288: DialogDisplayer.getDefault().notify(d);
289: }
290:
291: return allSet;
292: }
293:
294: // Expose updateState() method to disable next/finish buttons
295: private static class EjbWizardDescriptor extends WizardDescriptor {
296: public EjbWizardDescriptor(WizardDescriptor.Panel[] panels) {
297: super (panels);
298: }
299:
300: public void updateNavigatingState() {
301: super .updateState();
302: }
303:
304: }
305:
306: /**
307: * The wizard panel for gathering the EJB information
308: */
309: private class AddEjbsWizardPanel implements
310: WizardDescriptor.ValidatingPanel, ChangeListener {
311:
312: private boolean valid = true;
313:
314: public AddEjbsWizardPanel() {
315: }
316:
317: public void addChangeListener(javax.swing.event.ChangeListener l) {
318: }
319:
320: public java.awt.Component getComponent() {
321: // Set the selected index so that the proper entry is selected in the content panel
322: addPanel.putClientProperty(PROP_CONTENT_SELECTED_INDEX,
323: new Integer(0));
324: return addPanel;
325: }
326:
327: public HelpCtx getHelp() {
328: return new HelpCtx("projrave_ejb_howtoejbs_ejb_add_to_IDE");
329: }
330:
331: public boolean isValid() {
332: String groupName = addPanel.getGroupName();
333: return groupName != null
334: && EjbDataModel.getInstance()
335: .getEjbGroup(groupName) == null;
336: }
337:
338: public void readSettings(Object settings) {
339: }
340:
341: public void removeChangeListener(
342: javax.swing.event.ChangeListener l) {
343: }
344:
345: public void storeSettings(Object settings) {
346:
347: }
348:
349: public void validate()
350: throws org.openide.WizardValidationException {
351: if (!isValid()) {
352: String groupName = (addPanel.getGroupName() != null) ? addPanel
353: .getGroupName()
354: : "";
355: String errorMsg = NbBundle.getMessage(
356: AddEjbGroupDialog.class, "NAME_NOT_UNIQUE",
357: groupName);
358: throw new org.openide.WizardValidationException(
359: addPanel, errorMsg, errorMsg);
360: }
361:
362: // Throw WizardValidationException will cause the wizard to stay at the same step
363: String loadResult = loadingEjbGroup();
364: if (loadResult != null)
365: throw new org.openide.WizardValidationException(
366: addPanel, NbBundle.getMessage(
367: AddEjbGroupDialog.class,
368: "IMPORT_SET_ERROR"), loadResult);
369: }
370:
371: public void stateChanged(ChangeEvent e) {
372: if (!isValid()) {
373: valid = false;
374: wizardDescriptor.updateNavigatingState();
375:
376: String groupName = (addPanel.getGroupName() != null) ? addPanel
377: .getGroupName()
378: : "";
379: String errorMsg = NbBundle.getMessage(
380: AddEjbGroupDialog.class, "NAME_NOT_UNIQUE",
381: groupName);
382:
383: wizardDescriptor.putProperty(
384: "WizardPanel_errorMessage", errorMsg); // NOI18N
385: } else if (!valid) {
386: valid = true;
387: wizardDescriptor.updateNavigatingState();
388: wizardDescriptor.putProperty(
389: "WizardPanel_errorMessage", null); // NOI18N
390: }
391: }
392:
393: }
394:
395: /**
396: * The wizard panel for configuring the ejb business method.
397: * It is the last panel in the wizard
398: */
399: private class ConfigureMethodWizardPanel implements
400: WizardDescriptor.ValidatingPanel,
401: WizardDescriptor.FinishablePanel {
402:
403: public ConfigureMethodWizardPanel() {
404:
405: }
406:
407: public void addChangeListener(javax.swing.event.ChangeListener l) {
408: }
409:
410: public java.awt.Component getComponent() {
411: configureMethodsPanel = new ConfigureMethodsPanel(ejbGroup);
412:
413: // Set the selected index so that the proper entry is selected in the content panel
414: configureMethodsPanel.putClientProperty(
415: PROP_CONTENT_SELECTED_INDEX, new Integer(1));
416: return configureMethodsPanel;
417: }
418:
419: public HelpCtx getHelp() {
420: // todo help
421: //return new HelpCtx("projrave_ui_elements_server_nav_ejb_node");
422: return HelpCtx.DEFAULT_HELP;
423: }
424:
425: public boolean isValid() {
426: return true;
427: }
428:
429: public void readSettings(Object settings) {
430: }
431:
432: public void removeChangeListener(
433: javax.swing.event.ChangeListener l) {
434: }
435:
436: public void storeSettings(Object settings) {
437: }
438:
439: public void validate()
440: throws org.openide.WizardValidationException {
441:
442: // Get the last class name input from the user in the method detail panel
443: configureMethodsPanel.getMethodDetailPanel()
444: .updateColElemClassName();
445:
446: // Programmatically stop the CellEditor so that we do not lose the very last editting value
447: configureMethodsPanel.getMethodDetailPanel()
448: .stopLastCellEditing();
449:
450: // First, make sure the collection element classes are specified
451: if (!checkColElemClasses())
452: throw new org.openide.WizardValidationException(
453: addPanel, "not valid", "not valid"); // TODO I18N
454:
455: if (!createEjbGroup())
456: throw new org.openide.WizardValidationException(
457: addPanel, "not valid", "not valid"); // TODO I18N
458: }
459:
460: public boolean isFinishPanel() {
461: return true;
462: }
463:
464: }
465:
466: }
|