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-2006 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: package org.netbeans.modules.websvc.core.jaxws.nodes;
042:
043: import java.awt.Dialog;
044: import java.io.IOException;
045: import java.net.URL;
046: import java.util.ArrayList;
047: import java.util.Arrays;
048: import java.util.Collection;
049: import java.util.List;
050: import javax.swing.Action;
051: import org.apache.tools.ant.module.api.support.ActionUtils;
052: import org.netbeans.api.project.FileOwnerQuery;
053: import org.netbeans.api.project.Project;
054: import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
055: import org.netbeans.modules.websvc.api.jaxws.client.JAXWSClientSupport;
056: import org.netbeans.modules.websvc.api.jaxws.project.GeneratedFilesHelper;
057: import org.netbeans.modules.websvc.api.jaxws.project.config.Binding;
058: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModel;
059: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModelListener;
060: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModeler;
061: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModelerFactory;
062: import org.netbeans.modules.websvc.core.jaxws.actions.JaxWsRefreshClientAction;
063: import org.netbeans.modules.websvc.core.jaxws.bindings.model.BindingsHandler;
064: import org.netbeans.modules.websvc.core.jaxws.bindings.model.BindingsHandlerChain;
065: import org.netbeans.modules.websvc.core.jaxws.bindings.model.BindingsHandlerChains;
066: import org.netbeans.modules.websvc.core.jaxws.bindings.model.BindingsHandlerClass;
067: import org.netbeans.modules.websvc.core.jaxws.bindings.model.BindingsModel;
068: import org.netbeans.modules.websvc.core.jaxws.bindings.model.BindingsModelFactory;
069: import org.netbeans.modules.websvc.core.jaxws.bindings.model.DefinitionsBindings;
070: import org.netbeans.modules.websvc.core.jaxws.bindings.model.GlobalBindings;
071: import org.netbeans.modules.websvc.core.ConfigureHandlerAction;
072: import org.netbeans.modules.websvc.core.ConfigureHandlerCookie;
073: import org.netbeans.modules.websvc.core.webservices.ui.panels.MessageHandlerPanel;
074: import org.netbeans.modules.websvc.core.wseditor.support.WSEditAttributesAction;
075: import org.netbeans.modules.websvc.jaxws.api.JaxWsRefreshCookie;
076: import org.netbeans.modules.websvc.api.jaxws.project.config.JaxWsModel;
077: import org.netbeans.modules.websvc.api.jaxws.project.config.Client;
078: import org.netbeans.modules.websvc.core.wseditor.support.EditWSAttributesCookieImpl;
079: import org.netbeans.modules.xml.retriever.catalog.Utilities;
080: import org.netbeans.modules.xml.xam.ModelSource;
081: import org.openide.DialogDescriptor;
082: import org.openide.DialogDisplayer;
083: import org.openide.ErrorManager;
084: import org.openide.NotifyDescriptor;
085: import org.openide.actions.DeleteAction;
086: import org.openide.actions.OpenAction;
087: import org.openide.actions.PropertiesAction;
088: import org.openide.cookies.EditCookie;
089: import org.openide.cookies.OpenCookie;
090: import org.openide.execution.ExecutorTask;
091: import org.openide.filesystems.FileLock;
092: import org.openide.filesystems.FileObject;
093: import org.openide.filesystems.FileStateInvalidException;
094: import org.openide.loaders.DataObject;
095: import org.openide.nodes.AbstractNode;
096: import org.openide.nodes.PropertySupport;
097: import org.openide.nodes.Sheet;
098: import org.openide.util.HelpCtx;
099: import org.openide.util.Lookup;
100: import org.openide.util.NbBundle;
101: import org.openide.util.actions.SystemAction;
102: import org.openide.util.lookup.AbstractLookup;
103: import org.openide.util.lookup.InstanceContent;
104: import org.openide.util.lookup.Lookups;
105:
106: public class JaxWsClientNode extends AbstractNode implements
107: OpenCookie, JaxWsRefreshCookie, ConfigureHandlerCookie {
108: Client client;
109: FileObject srcRoot;
110: JaxWsModel jaxWsModel;
111: InstanceContent content;
112: private FileObject wsdlFileObject;
113: boolean modelGenerationFinished;
114:
115: public JaxWsClientNode(JaxWsModel jaxWsModel, Client client,
116: FileObject srcRoot) {
117: this (jaxWsModel, client, srcRoot, new InstanceContent());
118: }
119:
120: private JaxWsClientNode(JaxWsModel jaxWsModel, Client client,
121: FileObject srcRoot, InstanceContent content) {
122: super (new JaxWsClientChildren(client, srcRoot),
123: new AbstractLookup(content));
124: this .jaxWsModel = jaxWsModel;
125: this .client = client;
126: this .srcRoot = srcRoot;
127: this .content = content;
128: setName(client.getName());
129: setDisplayName(client.getName());
130: content.add(this );
131: content.add(client);
132: content.add(srcRoot);
133: WsdlModeler modeler = getWsdlModeler();
134: if (modeler != null) {
135: changeIcon();
136: modeler.generateWsdlModel(new WsdlModelListener() {
137: public void modelCreated(WsdlModel model) {
138: modelGenerationFinished = true;
139: changeIcon();
140: }
141: });
142: }
143: content.add(new EditWSAttributesCookieImpl(this , jaxWsModel));
144: setValue("wsdl-url", client.getWsdlUrl());
145: }
146:
147: @Override
148: public String getShortDescription() {
149: return client.getWsdlUrl();
150: }
151:
152: private static final String WAITING_BADGE = "org/netbeans/modules/websvc/core/webservices/ui/resources/waiting.png"; // NOI18N
153: private static final String ERROR_BADGE = "org/netbeans/modules/websvc/core/webservices/ui/resources/error-badge.gif"; //NOI18N
154: private static final String SERVICE_BADGE = "org/netbeans/modules/websvc/core/webservices/ui/resources/XMLServiceDataIcon.png"; //NOI18N
155:
156: private java.awt.Image cachedWaitingBadge;
157: private java.awt.Image cachedErrorBadge;
158: private java.awt.Image cachedServiceBadge;
159:
160: @Override
161: public java.awt.Image getIcon(int type) {
162: if (((JaxWsClientChildren) getChildren()).getWsdlModel() != null) {
163: return getServiceImage();
164: } else {
165: WsdlModeler wsdlModeler = getWsdlModeler();
166: if (wsdlModeler != null
167: && wsdlModeler.getCreationException() == null) {
168: if (modelGenerationFinished)
169: return getServiceImage();
170: else
171: return org.openide.util.Utilities
172: .mergeImages(getServiceImage(),
173: getWaitingBadge(), 15, 8);
174: } else {
175: java.awt.Image dirtyNodeImage = org.openide.util.Utilities
176: .mergeImages(getServiceImage(),
177: getErrorBadge(), 6, 6);
178: if (modelGenerationFinished)
179: return dirtyNodeImage;
180: else
181: return org.openide.util.Utilities.mergeImages(
182: dirtyNodeImage, getWaitingBadge(), 15, 8);
183: }
184: }
185: }
186:
187: private java.awt.Image getServiceImage() {
188: if (cachedServiceBadge == null) {
189: cachedServiceBadge = org.openide.util.Utilities
190: .loadImage(SERVICE_BADGE);
191: }
192: return cachedServiceBadge;
193: }
194:
195: private java.awt.Image getErrorBadge() {
196: if (cachedErrorBadge == null) {
197: cachedErrorBadge = org.openide.util.Utilities
198: .loadImage(ERROR_BADGE);
199: }
200: return cachedErrorBadge;
201: }
202:
203: private java.awt.Image getWaitingBadge() {
204: if (cachedWaitingBadge == null) {
205: cachedWaitingBadge = org.openide.util.Utilities
206: .loadImage(WAITING_BADGE);
207: }
208: return cachedWaitingBadge;
209: }
210:
211: @Override
212: public java.awt.Image getOpenedIcon(int type) {
213: return getIcon(type);
214: }
215:
216: public void open() {
217: EditCookie ec = getEditCookie();
218: if (ec != null) {
219: ec.edit();
220: }
221: }
222:
223: void changeIcon() {
224: fireIconChange();
225: }
226:
227: private EditCookie getEditCookie() {
228: try {
229: FileObject wsdlFo = JAXWSClientSupport
230: .getJaxWsClientSupport(srcRoot)
231: .getLocalWsdlFolderForClient(client.getName(),
232: false).getFileObject(
233: client.getLocalWsdlFile());
234: assert wsdlFo != null : "Cannot find local WSDL file"; //NOI18N
235: if (wsdlFo != null) {
236: DataObject dObj = DataObject.find(wsdlFo);
237: return (EditCookie) dObj.getCookie(EditCookie.class);
238: }
239: } catch (java.io.IOException ex) {
240: ErrorManager.getDefault().log(ex.getLocalizedMessage());
241: return null;
242: }
243: return null;
244: }
245:
246: @Override
247: public Action getPreferredAction() {
248: return SystemAction.get(OpenAction.class);
249: }
250:
251: // Create the popup menu:
252: @Override
253: public Action[] getActions(boolean context) {
254: ArrayList<Action> actions = new ArrayList<Action>(Arrays
255: .asList(SystemAction.get(OpenAction.class),
256: SystemAction
257: .get(JaxWsRefreshClientAction.class),
258: null, SystemAction
259: .get(WSEditAttributesAction.class),
260: null, SystemAction
261: .get(ConfigureHandlerAction.class),
262: null, SystemAction.get(DeleteAction.class),
263: null, SystemAction.get(PropertiesAction.class)));
264: addFromLayers(actions, "WebServices/Clients/Actions");
265: return actions.toArray(new Action[actions.size()]);
266: }
267:
268: private void addFromLayers(ArrayList<Action> actions, String path) {
269: Lookup look = Lookups.forPath(path);
270: for (Object next : look.lookupAll(Object.class)) {
271: if (next instanceof Action) {
272: actions.add((Action) next);
273: } else if (next instanceof javax.swing.JSeparator) {
274: actions.add(null);
275: }
276: }
277: }
278:
279: @Override
280: public HelpCtx getHelpCtx() {
281: return HelpCtx.DEFAULT_HELP;
282: }
283:
284: // Handle deleting:
285: @Override
286: public boolean canDestroy() {
287: return true;
288: }
289:
290: @Override
291: public void destroy() throws java.io.IOException {
292: String clientName = client.getName();
293: // NotifyDescriptor.Confirmation notifyDesc =
294: // new NotifyDescriptor.Confirmation(NbBundle.getMessage(JaxWsClientNode.class, "MSG_CONFIRM_DELETE", clientName));
295: // DialogDisplayer.getDefault().notify(notifyDesc);
296: // if(notifyDesc.getValue() == NotifyDescriptor.YES_OPTION){
297:
298: JAXWSClientSupport support = JAXWSClientSupport
299: .getJaxWsClientSupport(srcRoot);
300: // removing local wsdl and xml artifacts
301: FileObject localWsdlFolder = support
302: .getLocalWsdlFolderForClient(clientName, false);
303: if (localWsdlFolder != null) {
304: FileObject clientArtifactsFolder = localWsdlFolder
305: .getParent();
306: FileLock lock = null;
307: try {
308: lock = clientArtifactsFolder.lock();
309: clientArtifactsFolder.delete(lock);
310: } finally {
311: if (lock != null)
312: lock.releaseLock();
313: }
314: }
315:
316: Project project = FileOwnerQuery.getOwner(srcRoot);
317: // remove also client xml artifacs from WEB-INF[META-INF]/wsdl
318: if (client.getWsdlUrl().startsWith("file:")) { //NOI18N
319: if (project.getLookup().lookup(J2eeModuleProvider.class) != null) {
320: FileObject webInfClientFolder = findWsdlFolderForClient(
321: support, clientName);
322: if (webInfClientFolder != null) {
323: FileObject webInfClientRootFolder = webInfClientFolder
324: .getParent();
325: FileLock lock = null;
326: try {
327: lock = webInfClientFolder.lock();
328: webInfClientFolder.delete(lock);
329: } finally {
330: if (lock != null)
331: lock.releaseLock();
332: }
333: if (webInfClientRootFolder.getChildren().length == 0) {
334: try {
335: lock = webInfClientRootFolder.lock();
336: webInfClientRootFolder.delete(lock);
337: } finally {
338: if (lock != null)
339: lock.releaseLock();
340: }
341: }
342: }
343: }
344: }
345: // cleaning java artifacts
346: FileObject buildImplFo = project
347: .getProjectDirectory()
348: .getFileObject(GeneratedFilesHelper.BUILD_IMPL_XML_PATH);
349: try {
350: ExecutorTask wsimportTask = ActionUtils.runTarget(
351: buildImplFo,
352: new String[] { "wsimport-client-clean-"
353: + clientName }, null); //NOI18N
354: wsimportTask.waitFinished();
355: } catch (java.io.IOException ex) {
356: ErrorManager.getDefault().log(ex.getLocalizedMessage());
357: } catch (IllegalArgumentException ex) {
358: ErrorManager.getDefault().log(ex.getLocalizedMessage());
359: }
360: // removing entry from jax-ws.xml
361: support.removeServiceClient(clientName);
362: super .destroy();
363: // }
364: }
365:
366: /**
367: * refresh service information obtained from wsdl (when wsdl file was changed)
368: */
369: public void refreshService(boolean downloadWsdl) {
370: if (downloadWsdl) {
371: String result = RefreshClientDialog.open(client
372: .getWsdlUrl());
373: if (RefreshClientDialog.CLOSE.equals(result))
374: return;
375: else if (RefreshClientDialog.NO_DOWNLOAD.equals(result)) {
376: ((JaxWsClientChildren) getChildren())
377: .refreshKeys(false);
378: } else {
379: ((JaxWsClientChildren) getChildren()).refreshKeys(true,
380: result);
381: }
382: } else {
383: DialogDisplayer.getDefault().notify(
384: new NotifyDescriptor.Message(NbBundle
385: .getMessage(JaxWsClientNode.class,
386: "HINT_RefreshClient"))); //NOI18N
387: ((JaxWsClientChildren) getChildren()).refreshKeys(false);
388: }
389: }
390:
391: private void removeWsdlFolderContents() {
392: FileObject wsdlFolder = getJAXWSClientSupport()
393: .getLocalWsdlFolderForClient(getName(), false);
394: if (wsdlFolder != null) {
395: FileLock lock = null;
396:
397: FileObject[] files = wsdlFolder.getChildren();
398: for (int i = 0; i < files.length; i++) {
399: try {
400: FileObject file = files[i];
401: lock = file.lock();
402: file.delete(lock);
403: } catch (IOException e) {
404: ErrorManager.getDefault().notify(e);
405: } finally {
406: if (lock != null) {
407: lock.releaseLock();
408: lock = null;
409: }
410: }
411: }
412: }
413: }
414:
415: public void configureHandler() {
416: Project project = FileOwnerQuery.getOwner(srcRoot);
417: ArrayList<String> handlerClasses = new ArrayList<String>();
418: BindingsModel bindingsModel = getBindingsModel();
419: if (bindingsModel != null) { //if there is an existing bindings file, load it
420: GlobalBindings gb = bindingsModel.getGlobalBindings();
421: if (gb != null) {
422: DefinitionsBindings db = gb.getDefinitionsBindings();
423: if (db != null) {
424: BindingsHandlerChains handlerChains = db
425: .getHandlerChains();
426: //there is only one handler chain
427: BindingsHandlerChain handlerChain = handlerChains
428: .getHandlerChains().iterator().next();
429: Collection<BindingsHandler> handlers = handlerChain
430: .getHandlers();
431: for (BindingsHandler handler : handlers) {
432: BindingsHandlerClass handlerClass = handler
433: .getHandlerClass();
434: handlerClasses.add(handlerClass.getClassName());
435: }
436: }
437: }
438: }
439: final MessageHandlerPanel panel = new MessageHandlerPanel(
440: project, handlerClasses, true, client.getName());
441: String title = NbBundle.getMessage(JaxWsNode.class,
442: "TTL_MessageHandlerPanel");
443: DialogDescriptor dialogDesc = new DialogDescriptor(panel, title);
444: dialogDesc.setButtonListener(new ClientHandlerButtonListener(
445: panel, bindingsModel, client, this , jaxWsModel));
446: Dialog dialog = DialogDisplayer.getDefault().createDialog(
447: dialogDesc);
448: dialog.getAccessibleContext().setAccessibleDescription(
449: dialog.getTitle());
450: dialog.setVisible(true);
451: }
452:
453: private BindingsModel getBindingsModel() {
454: String handlerBindingFile = client.getHandlerBindingFile();
455: BindingsModel bindingsModel = null;
456:
457: //if there is an existing handlerBindingFile, load it
458: try {
459: if (handlerBindingFile != null) {
460: JAXWSClientSupport support = JAXWSClientSupport
461: .getJaxWsClientSupport(srcRoot);
462: FileObject bindingsFolder = support
463: .getBindingsFolderForClient(getName(), false);
464: if (bindingsFolder != null) {
465: FileObject handlerBindingFO = bindingsFolder
466: .getFileObject(handlerBindingFile);
467: if (handlerBindingFO != null) {
468: ModelSource ms = Utilities.getModelSource(
469: handlerBindingFO, true);
470: bindingsModel = BindingsModelFactory
471: .getDefault().getModel(ms);
472: }
473: }
474: }
475: } catch (Exception e) {
476: ErrorManager.getDefault().notify(e);
477: return null;
478: }
479: return bindingsModel;
480: }
481:
482: WsdlModeler getWsdlModeler() {
483: if (getLocalWsdl() != null) {
484: try {
485: WsdlModeler modeler = WsdlModelerFactory.getDefault()
486: .getWsdlModeler(wsdlFileObject.getURL());
487: if (modeler != null) {
488: String packageName = client.getPackageName();
489: if (packageName != null
490: && client.isPackageNameForceReplace()) {
491: // set the package name for the modeler
492: modeler.setPackageName(packageName);
493: } else {
494: modeler.setPackageName(null);
495: }
496: modeler.setCatalog(getJAXWSClientSupport()
497: .getCatalog());
498: setBindings(modeler);
499: return modeler;
500: }
501: } catch (FileStateInvalidException ex) {
502: ErrorManager.getDefault().log(ex.getLocalizedMessage());
503: }
504: } else {
505: ErrorManager.getDefault().log(
506: ErrorManager.ERROR,
507: NbBundle.getMessage(JaxWsNode.class,
508: "ERR_missingLocalWsdl"));
509: }
510: return null;
511: }
512:
513: FileObject getLocalWsdl() {
514: if (wsdlFileObject == null) {
515: FileObject localWsdlocalFolder = getJAXWSClientSupport()
516: .getLocalWsdlFolderForClient(client.getName(),
517: false);
518: if (localWsdlocalFolder != null)
519: wsdlFileObject = localWsdlocalFolder
520: .getFileObject(client.getLocalWsdlFile());
521: }
522: return wsdlFileObject;
523: }
524:
525: private JAXWSClientSupport getJAXWSClientSupport() {
526: return JAXWSClientSupport.getJaxWsClientSupport(srcRoot);
527: }
528:
529: private void setBindings(WsdlModeler wsdlModeler) {
530: Binding[] extbindings = client.getBindings();
531: if (extbindings == null || extbindings.length == 0) {
532: wsdlModeler.setJAXBBindings(null);
533: return;
534: }
535: String[] bindingFiles = new String[extbindings.length];
536: for (int i = 0; i < extbindings.length; i++) {
537: bindingFiles[i] = extbindings[i].getFileName();
538: }
539:
540: FileObject bindingsFolder = getJAXWSClientSupport()
541: .getBindingsFolderForClient(getName(), true);
542: List<URL> list = new ArrayList<URL>();
543: for (int i = 0; i < bindingFiles.length; i++) {
544: FileObject fo = bindingsFolder
545: .getFileObject(bindingFiles[i]);
546: try {
547: list.add(fo.getURL());
548: } catch (FileStateInvalidException ex) {
549: // if there is problem no bindings will be added
550: }
551: }
552: URL[] bindings = new URL[list.size()];
553: list.<URL> toArray(bindings);
554: wsdlModeler.setJAXBBindings(bindings);
555: }
556:
557: void setModelGenerationFinished(boolean value) {
558: modelGenerationFinished = value;
559: }
560:
561: JaxWsModel getJaxWsModel() {
562: return jaxWsModel;
563: }
564:
565: private FileObject findWsdlFolderForClient(
566: JAXWSClientSupport support, String name) throws IOException {
567: FileObject globalWsdlFolder = support.getWsdlFolder(false);
568: if (globalWsdlFolder != null) {
569: return globalWsdlFolder.getFileObject("client/" + name);
570: }
571: return null;
572: }
573:
574: @Override
575: protected Sheet createSheet() {
576: Sheet sheet = super .createSheet();
577: Sheet.Set set = sheet.get(Sheet.PROPERTIES);
578: if (set == null) {
579: set = Sheet.createPropertiesSet();
580:
581: }
582: sheet.put(set);
583: set.put(new PropertySupport("useDispatch", Boolean.class,
584: NbBundle.getMessage(JaxWsClientNode.class,
585: "TTL_USE_DISPATCH"), "", true, true) {
586:
587: public Object getValue() {
588: return client.getUseDispatch();
589: }
590:
591: public void setValue(Object value) {
592: try {
593: Boolean val = (Boolean) value;
594: client.setUseDispatch(val);
595: jaxWsModel.write();
596: } catch (IOException ex) {
597: ErrorManager.getDefault().notify(ex);
598: }
599: }
600: });
601:
602: return sheet;
603: }
604: }
|