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: /*
043: * OperationGenerator.java
044: *
045: * Created on September 6, 2006, 4:53 PM
046: *
047: * To change this template, choose Tools | Template Manager
048: * and open the template in the editor.
049: */
050:
051: package org.netbeans.modules.xml.wsdl.ui.wizard;
052:
053: import java.util.ArrayList;
054: import java.util.Collection;
055: import java.util.HashMap;
056: import java.util.Iterator;
057: import java.util.List;
058: import java.util.Map;
059: import javax.xml.namespace.QName;
060:
061: import org.netbeans.modules.xml.schema.model.GlobalElement;
062: import org.netbeans.modules.xml.schema.model.GlobalType;
063: import org.netbeans.modules.xml.schema.model.Import;
064: import org.netbeans.modules.xml.schema.model.Schema;
065: import org.netbeans.modules.xml.schema.model.SchemaModel;
066: import org.netbeans.modules.xml.wsdl.model.Definitions;
067: import org.netbeans.modules.xml.wsdl.model.Fault;
068: import org.netbeans.modules.xml.wsdl.model.Input;
069: import org.netbeans.modules.xml.wsdl.model.Message;
070: import org.netbeans.modules.xml.wsdl.model.Operation;
071: import org.netbeans.modules.xml.wsdl.model.Output;
072: import org.netbeans.modules.xml.wsdl.model.Part;
073: import org.netbeans.modules.xml.wsdl.model.PortType;
074: import org.netbeans.modules.xml.wsdl.model.Types;
075: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
076: import org.netbeans.modules.xml.wsdl.model.extensions.xsd.WSDLSchema;
077: import org.netbeans.modules.xml.wsdl.ui.actions.NameGenerator;
078: import org.netbeans.modules.xml.wsdl.ui.netbeans.module.Utility;
079: import org.netbeans.modules.xml.wsdl.ui.view.ElementOrType;
080: import org.netbeans.modules.xml.wsdl.ui.view.OperationType;
081: import org.netbeans.modules.xml.wsdl.ui.view.PartAndElementOrTypeTableModel;
082: import org.netbeans.modules.xml.wsdl.ui.view.PartAndElementOrTypeTableModel.PartAndElementOrType;
083: import org.netbeans.modules.xml.wsdl.ui.wsdl.util.RelativePath;
084: import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
085: import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
086: import org.openide.filesystems.FileObject;
087: import org.openide.filesystems.FileUtil;
088:
089: /**
090: *
091: * @author radval
092: */
093: public class OperationGenerator implements Command {
094:
095: private WSDLModel mModel;
096:
097: private Map mConfigurationMap;
098:
099: private PortType mParentPortType;
100:
101: private Operation mOperation;
102:
103: private List<Message> mNewMessageList = new ArrayList<Message>();
104:
105: private Collection<Import> mImports = new ArrayList<Import>();
106:
107: /** Creates a new instance of OperationGenerator */
108: public OperationGenerator(WSDLModel model, PortType parent,
109: Map configurationMap) {
110: this .mModel = model;
111: this .mParentPortType = parent;
112: this .mConfigurationMap = configurationMap;
113: }
114:
115: public Operation getOperation() {
116: return this .mOperation;
117: }
118:
119: public List<Message> getNewMessages() {
120: return this .mNewMessageList;
121: }
122:
123: public Collection<Import> getImports() {
124: return this .mImports;
125: }
126:
127: public void execute() {
128: if (mModel != null) {
129: //operation
130: String operationName = (String) this .mConfigurationMap
131: .get(WizardPortTypeConfigurationStep.OPERATION_NAME);
132: OperationType ot = (OperationType) this .mConfigurationMap
133: .get(WizardPortTypeConfigurationStep.OPERATION_TYPE);
134:
135: this .mOperation = createOperation(ot, mModel);
136: this .mOperation.setName(operationName);
137: this .mParentPortType.addOperation(this .mOperation);
138:
139: //opertion type
140: List<PartAndElementOrTypeTableModel.PartAndElementOrType> inputMessageParts = (List<PartAndElementOrTypeTableModel.PartAndElementOrType>) this .mConfigurationMap
141: .get(WizardPortTypeConfigurationStep.OPERATION_INPUT);
142:
143: List<PartAndElementOrTypeTableModel.PartAndElementOrType> outputMessageParts = (List<PartAndElementOrTypeTableModel.PartAndElementOrType>) this .mConfigurationMap
144: .get(WizardPortTypeConfigurationStep.OPERATION_OUTPUT);
145:
146: List<PartAndElementOrTypeTableModel.PartAndElementOrType> faultMessageParts = (List<PartAndElementOrTypeTableModel.PartAndElementOrType>) this .mConfigurationMap
147: .get(WizardPortTypeConfigurationStep.OPERATION_FAULT);
148:
149: SchemaImportsGenerator schemaImportGenerator = new SchemaImportsGenerator(
150: this .mModel, mConfigurationMap);
151: schemaImportGenerator.execute();
152: mImports.addAll(schemaImportGenerator.getImports());
153:
154: String inputMessageName = (String) this .mConfigurationMap
155: .get(WizardPortTypeConfigurationStep.OPERATION_INPUT_MESSAGE);
156: String outputMessageName = (String) this .mConfigurationMap
157: .get(WizardPortTypeConfigurationStep.OPERATION_OUTPUT_MESSAGE);
158: String faultMessageName = (String) this .mConfigurationMap
159: .get(WizardPortTypeConfigurationStep.OPERATION_FAULT_MESSAGE);
160:
161: processOperationType(ot, this .mOperation,
162: inputMessageParts, outputMessageParts,
163: faultMessageParts, inputMessageName,
164: outputMessageName, faultMessageName);
165: }
166:
167: }
168:
169: private Operation createOperation(OperationType ot, WSDLModel model) {
170: Operation operation = null;
171: if (ot.getOperationType().equals(
172: OperationType.OPERATION_REQUEST_REPLY)) {
173: operation = model.getFactory()
174: .createRequestResponseOperation();
175: } else if (ot.getOperationType().equals(
176: OperationType.OPERATION_ONE_WAY)) {
177: operation = model.getFactory().createOneWayOperation();
178: } else if (ot.getOperationType().equals(
179: OperationType.OPERATION_SOLICIT_RESPONSE)) {
180: operation = model.getFactory()
181: .createSolicitResponseOperation();
182: } else if (ot.getOperationType().equals(
183: OperationType.OPERATION_NOTIFICATION)) {
184: operation = model.getFactory()
185: .createNotificationOperation();
186: }
187:
188: return operation;
189: }
190:
191: private void processOperationType(
192: OperationType ot,
193: Operation op,
194: List<PartAndElementOrTypeTableModel.PartAndElementOrType> inputMessageParts,
195: List<PartAndElementOrTypeTableModel.PartAndElementOrType> outputMessageParts,
196: List<PartAndElementOrTypeTableModel.PartAndElementOrType> faultMessageParts,
197: String inputMessageName, String ouputMessageName,
198: String faultMessageName) {
199: Message inputMessage = null;
200: Message outputMessage = null;
201: Message faultMessage = null;
202: NamedComponentReference<Message> inMessageRef = null;
203: NamedComponentReference<Message> outMessageRef = null;
204: NamedComponentReference<Message> faultMessageRef = null;
205:
206: //inputMessageName is provided by dialog not from wizard and this name could be name of
207: //new message which needs to be created or it could point to name of existing message.
208: if (inputMessageName != null) {
209: inputMessage = findMessage(inputMessageName);
210: } else {
211: //we are from wizard and inputMessageName is not provided
212: inputMessageName = NameGenerator.getInstance()
213: .generateUniqueInputMessageName(op.getName(),
214: this .mModel);
215: }
216:
217: //inputMessageParts are provided
218: if (inputMessage == null && inputMessageParts != null) {
219: //inputMessage is not an existing message then create and add new message
220: inputMessage = createAndAddMessage(inputMessageParts);
221: inputMessage.setName(inputMessageName);
222: }
223:
224: if (inputMessage != null) {
225: inMessageRef = op.createReferenceTo(inputMessage,
226: Message.class);
227: createAndAddInput(op, inMessageRef);
228: }
229:
230: //ouputMessageName is provided by dialog not from wizard and this name could be name of
231: //new message which needs to be created or it could point to name of existing message.
232: if (ouputMessageName != null) {
233: outputMessage = findMessage(ouputMessageName);
234: } else {
235: //we are from wizard and ouputMessageName is not provided
236: ouputMessageName = NameGenerator.getInstance()
237: .generateUniqueOutputMessageName(op.getName(),
238: this .mModel);
239: }
240:
241: if (outputMessage == null && outputMessageParts != null) {
242:
243: //ouputMessageName is not an existing message then create and add new message
244: outputMessage = createAndAddMessage(outputMessageParts);
245: outputMessage.setName(ouputMessageName);
246: }
247:
248: if (outputMessage != null) {
249: outMessageRef = op.createReferenceTo(outputMessage,
250: Message.class);
251: createAndAddOuput(op, outMessageRef);
252: }
253:
254: //faultMessageName is provided by dialog not from wizard and this name could be name of
255: //new message which needs to be created or it could point to name of existing message.
256: if (faultMessageName != null) {
257: faultMessage = findMessage(faultMessageName);
258: } else {
259: faultMessageName = NameGenerator.getInstance()
260: .generateUniqueFaultMessageName(op.getName(),
261: this .mModel);
262: }
263:
264: //if faultMessage is null meaning did not find existing message so we must create a new message
265: if (faultMessage == null && faultMessageParts != null
266: && faultMessageParts.size() > 0) {
267: //for fault we create them only if user specifies atleast one part
268: faultMessage = createAndAddMessage(faultMessageParts);
269: faultMessage.setName(faultMessageName);
270:
271: }
272:
273: if (faultMessage != null) {
274: faultMessageRef = op.createReferenceTo(faultMessage,
275: Message.class);
276: createAndAddFault(op, faultMessageRef);
277: }
278:
279: }
280:
281: private Input createAndAddInput(Operation op,
282: NamedComponentReference<Message> messageRef) {
283: Input in = this .mModel.getFactory().createInput();
284:
285: String operationInputName = NameGenerator.getInstance()
286: .generateUniqueOperationInputName(op);
287: in.setName(operationInputName);
288: op.setInput(in);
289: if (messageRef != null) {
290: in.setMessage(messageRef);
291: }
292:
293: return in;
294: }
295:
296: private Output createAndAddOuput(Operation op,
297: NamedComponentReference<Message> messageRef) {
298: Output out = this .mModel.getFactory().createOutput();
299:
300: String operationOutputName = NameGenerator.getInstance()
301: .generateUniqueOperationOutputName(op);
302: out.setName(operationOutputName);
303: op.setOutput(out);
304: if (messageRef != null) {
305: out.setMessage(messageRef);
306: }
307:
308: return out;
309: }
310:
311: private Fault createAndAddFault(Operation op,
312: NamedComponentReference<Message> messageRef) {
313: Fault fault = this .mModel.getFactory().createFault();
314:
315: String operationFaultName = NameGenerator.getInstance()
316: .generateUniqueOperationFaultName(op);
317: fault.setName(operationFaultName);
318: op.addFault(fault);
319: if (messageRef != null) {
320: fault.setMessage(messageRef);
321: }
322:
323: return fault;
324: }
325:
326: private Message createAndAddMessage(
327: List<PartAndElementOrTypeTableModel.PartAndElementOrType> inputMessageParts) {
328: Message msg = this .mModel.getFactory().createMessage();
329: this .mModel.getDefinitions().addMessage(msg);
330: mNewMessageList.add(msg);
331:
332: if (inputMessageParts != null) {
333: Iterator<PartAndElementOrTypeTableModel.PartAndElementOrType> it = inputMessageParts
334: .iterator();
335: while (it.hasNext()) {
336: PartAndElementOrTypeTableModel.PartAndElementOrType partOrElement = it
337: .next();
338: String partName = partOrElement.getPartName();
339: ElementOrType elementOrType = partOrElement
340: .getElementOrType();
341:
342: Part part = this .mModel.getFactory().createPart();
343: part.setName(partName);
344: msg.addPart(part);
345: if (elementOrType != null) {
346: GlobalElement element = elementOrType.getElement();
347: GlobalType type = elementOrType.getType();
348: if (element != null) {
349: NamedComponentReference<GlobalElement> elementRef = part
350: .createSchemaReference(element,
351: GlobalElement.class);
352: if (elementRef != null) {
353: part.setElement(elementRef);
354: }
355: } else if (type != null) {
356: NamedComponentReference<GlobalType> typeRef = part
357: .createSchemaReference(type,
358: GlobalType.class);
359: if (typeRef != null) {
360: part.setType(typeRef);
361: }
362: }
363:
364: }
365: }
366: }
367: return msg;
368: }
369:
370: private Message findMessage(String messageName) {
371: QName qName = constructQName(messageName);
372: if (qName != null) {
373: return this .mModel
374: .findComponentByName(qName, Message.class);
375: }
376:
377: return null;
378: }
379:
380: private QName constructQName(String name) {
381: if (name == null) {
382: return null;
383: }
384:
385: QName qName = null;
386: int prefixIndex = name.lastIndexOf(":");
387: String prefix = "";
388: String namespace = null;
389: String localPart = null;
390: if (prefixIndex != -1) {
391: prefix = name.substring(0, prefixIndex);
392: localPart = name.substring(prefixIndex + 1);
393: namespace = ((AbstractDocumentComponent) this .mModel
394: .getDefinitions()).lookupNamespaceURI(prefix);
395: } else {
396: localPart = name;
397: namespace = this .mModel.getDefinitions()
398: .getTargetNamespace();
399: }
400:
401: qName = new QName(namespace, localPart, prefix);
402:
403: return qName;
404: }
405: }
|