001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.wsdl.codegen.emitter;
020:
021: import org.apache.axis2.description.AxisMessage;
022: import org.apache.axis2.description.AxisOperation;
023: import org.apache.axis2.description.PolicyInclude;
024: import org.apache.axis2.util.JavaUtils;
025: import org.apache.axis2.util.PolicyUtil;
026: import org.apache.axis2.util.Utils;
027: import org.apache.axis2.wsdl.WSDLConstants;
028: import org.apache.axis2.wsdl.codegen.CodeGenerationException;
029: import org.apache.axis2.wsdl.codegen.writer.CServiceXMLWriter;
030: import org.apache.axis2.wsdl.codegen.writer.CSkelHeaderWriter;
031: import org.apache.axis2.wsdl.codegen.writer.CSkelSourceWriter;
032: import org.apache.axis2.wsdl.codegen.writer.CStubHeaderWriter;
033: import org.apache.axis2.wsdl.codegen.writer.CStubSourceWriter;
034: import org.apache.axis2.wsdl.codegen.writer.CSvcSkeletonWriter;
035: import org.apache.axis2.wsdl.codegen.writer.FileWriter;
036: import org.apache.axis2.wsdl.databinding.CUtils;
037: import org.apache.neethi.Policy;
038: import org.w3c.dom.Document;
039: import org.w3c.dom.Element;
040:
041: import javax.xml.namespace.QName;
042: import java.io.File;
043: import java.util.ArrayList;
044: import java.util.Iterator;
045: import java.util.List;
046: import java.util.Map;
047:
048: public class CEmitter extends AxisServiceBasedMultiLanguageEmitter {
049: protected static final String C_STUB_PREFIX = "axis2_stub_";
050: protected static final String C_SKEL_PREFIX = "axis2_skel_";
051: protected static final String C_SVC_SKEL_PREFIX = "axis2_svc_skel_";
052: protected static final String C_STUB_SUFFIX = "";
053: protected static final String C_SKEL_SUFFIX = "";
054: protected static final String C_SVC_SKEL_SUFFIX = "";
055:
056: protected static final String JAVA_DEFAULT_TYPE = "org.apache.axiom.om.OMElement";
057: protected static final String C_DEFAULT_TYPE = "axiom_node_t*";
058:
059: protected static final String C_OUR_TYPE_PREFIX = "axis2_";
060: protected static final String C_OUR_TYPE_SUFFIX = "_t*";
061:
062: /**
063: * Emit the stub
064: *
065: * @throws CodeGenerationException
066: */
067: public void emitStub() throws CodeGenerationException {
068:
069: try {
070: // write interface implementations
071: writeCStub();
072:
073: } catch (Exception e) {
074: //log the error here
075: e.printStackTrace();
076: }
077: }
078:
079: /**
080: * Emit the skeltons
081: *
082: * @throws CodeGenerationException
083: */
084: public void emitSkeleton() throws CodeGenerationException {
085: try {
086: // write skeleton
087: writeCSkel();
088:
089: // write a Service Skeleton for this particular service.
090: writeCServiceSkeleton();
091:
092: writeServiceXml();
093: } catch (Exception e) {
094: e.printStackTrace();
095: }
096: }
097:
098: /**
099: * Writes the Stub.
100: *
101: * @throws Exception
102: */
103: protected void writeCStub() throws Exception {
104:
105: // first check for the policies in this service and write them
106: Document interfaceImplModel = createDOMDocumentForInterfaceImplementation();
107:
108: CStubHeaderWriter writerHStub = new CStubHeaderWriter(
109: getOutputDirectory(codeGenConfiguration
110: .getOutputLocation(), codeGenConfiguration
111: .getSourceLocation()), codeGenConfiguration
112: .getOutputLanguage());
113:
114: writeFile(interfaceImplModel, writerHStub);
115:
116: CStubSourceWriter writerCStub = new CStubSourceWriter(
117: getOutputDirectory(codeGenConfiguration
118: .getOutputLocation(), codeGenConfiguration
119: .getSourceLocation()), codeGenConfiguration
120: .getOutputLanguage());
121:
122: writeFile(interfaceImplModel, writerCStub);
123: }
124:
125: /**
126: * Writes the Skel.
127: *
128: * @throws Exception
129: */
130: protected void writeCSkel() throws Exception {
131:
132: Document skeletonModel = createDOMDocumentForSkeleton(codeGenConfiguration
133: .isServerSideInterface());
134:
135: CSkelHeaderWriter skeletonWriter = new CSkelHeaderWriter(
136: getOutputDirectory(this .codeGenConfiguration
137: .getOutputLocation(), codeGenConfiguration
138: .getSourceLocation()),
139: this .codeGenConfiguration.getOutputLanguage());
140:
141: writeFile(skeletonModel, skeletonWriter);
142:
143: CSkelSourceWriter skeletonWriterStub = new CSkelSourceWriter(
144: getOutputDirectory(this .codeGenConfiguration
145: .getOutputLocation(), codeGenConfiguration
146: .getSourceLocation()),
147: this .codeGenConfiguration.getOutputLanguage());
148:
149: writeFile(skeletonModel, skeletonWriterStub);
150: }
151:
152: /** @throws Exception */
153: protected void writeCServiceSkeleton() throws Exception {
154:
155: Document skeletonModel = createDOMDocumentForServiceSkeletonXML();
156: CSvcSkeletonWriter writer = new CSvcSkeletonWriter(
157: getOutputDirectory(codeGenConfiguration
158: .getOutputLocation(), codeGenConfiguration
159: .getSourceLocation()), codeGenConfiguration
160: .getOutputLanguage());
161:
162: writeFile(skeletonModel, writer);
163:
164: }
165:
166: /**
167: * Write the service XML
168: *
169: * @throws Exception
170: */
171: protected void writeServiceXml() throws Exception {
172: if (this .codeGenConfiguration.isGenerateDeployementDescriptor()) {
173:
174: // Write the service xml in a folder with the
175: Document serviceXMLModel = createDOMDocumentForServiceXML();
176: FileWriter serviceXmlWriter = new CServiceXMLWriter(
177: getOutputDirectory(this .codeGenConfiguration
178: .getOutputLocation(), codeGenConfiguration
179: .getResourceLocation()),
180: this .codeGenConfiguration.getOutputLanguage());
181:
182: writeFile(serviceXMLModel, serviceXmlWriter);
183: }
184: }
185:
186: /** Creates the DOM tree for implementations. */
187: protected Document createDOMDocumentForInterfaceImplementation()
188: throws Exception {
189:
190: String serviceName = axisService.getName();
191: String serviceTns = axisService.getTargetNamespace();
192: String serviceCName = makeCClassName(axisService.getName());
193: String stubName = C_STUB_PREFIX + serviceCName + C_STUB_SUFFIX;
194: Document doc = getEmptyDocument();
195: Element rootElement = doc.createElement("class");
196:
197: addAttribute(doc, "name", stubName, rootElement);
198: addAttribute(doc, "prefix", stubName, rootElement); //prefix to be used by the functions
199: addAttribute(doc, "qname", serviceName + "|" + serviceTns,
200: rootElement);
201: addAttribute(doc, "servicename", serviceCName, rootElement);
202: addAttribute(doc, "package", "", rootElement);
203:
204: addAttribute(doc, "namespace", serviceTns, rootElement);
205: addAttribute(doc, "interfaceName", serviceCName, rootElement);
206:
207: /* The following block of code is same as for the
208: * AxisServiceBasedMultiLanguageEmitter createDOMDocumentForInterfaceImplementation()
209: */
210: // add the wrap classes flag
211: if (codeGenConfiguration.isPackClasses()) {
212: addAttribute(doc, "wrapped", "yes", rootElement);
213: }
214:
215: // add SOAP version
216: addSoapVersion(doc, rootElement);
217:
218: // add the end point
219: addEndpoint(doc, rootElement);
220:
221: // set the sync/async attributes
222: fillSyncAttributes(doc, rootElement);
223:
224: // ###########################################################################################
225: // this block of code specifically applies to the integration of databinding code into the
226: // generated classes tightly (probably as inner classes)
227: // ###########################################################################################
228: // check for the special models in the mapper and if they are present process them
229: if (mapper.isObjectMappingPresent()) {
230:
231: // add an attribute to the root element showing that the writing has been skipped
232: addAttribute(doc, "skip-write", "yes", rootElement);
233:
234: // process the mapper objects
235: processModelObjects(mapper.getAllMappedObjects(),
236: rootElement, doc);
237: }
238:
239: // #############################################################################################
240:
241: // load the operations
242: loadOperations(doc, rootElement, null);
243:
244: // add the databind supporters. Now the databind supporters are completly contained inside
245: // the stubs implementation and not visible outside
246: rootElement.appendChild(createDOMElementforDatabinders(doc,
247: false));
248:
249: Object stubMethods;
250:
251: //if some extension has added the stub methods property, add them to the
252: //main document
253: if ((stubMethods = codeGenConfiguration
254: .getProperty("stubMethods")) != null) {
255: rootElement.appendChild(doc.importNode(
256: (Element) stubMethods, true));
257: }
258:
259: //add another element to have the unique list of faults
260: rootElement.appendChild(getUniqueListofFaults(doc));
261:
262: /////////////////////////////////////////////////////
263: //System.out.println(DOM2Writer.nodeToString(rootElement));
264: /////////////////////////////////////////////////////
265:
266: doc.appendChild(rootElement);
267: return doc;
268: }
269:
270: protected Document createDOMDocumentForSkeleton(
271: boolean isSkeletonInterface) {
272: Document doc = getEmptyDocument();
273: Element rootElement = doc.createElement("interface");
274:
275: String serviceCName = makeCClassName(axisService.getName());
276: String skelName = C_SKEL_PREFIX + serviceCName + C_SKEL_SUFFIX;
277:
278: // only the name is used
279: addAttribute(doc, "name", skelName, rootElement);
280: addAttribute(doc, "package", "", rootElement);
281: String serviceName = axisService.getName();
282: String serviceTns = axisService.getTargetNamespace();
283: addAttribute(doc, "prefix", skelName, rootElement); //prefix to be used by the functions
284: addAttribute(doc, "qname", serviceName + "|" + serviceTns,
285: rootElement);
286:
287: fillSyncAttributes(doc, rootElement);
288: loadOperations(doc, rootElement, null);
289:
290: //attach a list of faults
291: rootElement.appendChild(getUniqueListofFaults(doc));
292:
293: doc.appendChild(rootElement);
294: return doc;
295:
296: }
297:
298: protected Document createDOMDocumentForServiceSkeletonXML() {
299: Document doc = getEmptyDocument();
300: Element rootElement = doc.createElement("interface");
301:
302: String localPart = makeCClassName(axisService.getName());
303: String svcSkelName = C_SVC_SKEL_PREFIX + localPart
304: + C_SVC_SKEL_SUFFIX;
305: String skelName = C_SKEL_PREFIX + localPart + C_SKEL_SUFFIX;
306:
307: // only the name is used
308: addAttribute(doc, "name", svcSkelName, rootElement);
309: addAttribute(doc, "prefix", svcSkelName, rootElement); //prefix to be used by the functions
310: String serviceName = axisService.getName();
311: String serviceTns = axisService.getTargetNamespace();
312: addAttribute(doc, "qname", serviceName + "|" + serviceTns,
313: rootElement);
314:
315: addAttribute(doc, "svcname", skelName, rootElement);
316: addAttribute(doc, "svcop_prefix", skelName, rootElement);
317: addAttribute(doc, "package", "", rootElement);
318:
319: fillSyncAttributes(doc, rootElement);
320: loadOperations(doc, rootElement, null);
321:
322: // add SOAP version
323: addSoapVersion(doc, rootElement);
324:
325: //attach a list of faults
326: rootElement.appendChild(getUniqueListofFaults(doc));
327:
328: doc.appendChild(rootElement);
329: return doc;
330:
331: }
332:
333: /**
334: * @param word
335: * @return Returns character removed string.
336: */
337: protected String makeCClassName(String word) {
338: //currently avoid only java key words and service names with '.' characters
339:
340: if (CUtils.isCKeyword(word)) {
341: return CUtils.makeNonCKeyword(word);
342: }
343: String outWord = word.replace('.', '_');
344: return outWord.replace('-', '_');
345: }
346:
347: /**
348: * Loads the operations
349: *
350: * @param doc
351: * @param rootElement
352: * @param mep
353: * @return operations found
354: */
355: protected boolean loadOperations(Document doc, Element rootElement,
356: String mep) {
357: Element methodElement;
358: String portTypeName = makeCClassName(axisService.getName());
359:
360: Iterator operations = axisService.getOperations();
361: boolean opsFound = false;
362: while (operations.hasNext()) {
363: AxisOperation axisOperation = (AxisOperation) operations
364: .next();
365:
366: // populate info holder with mep information. This will used in determining which
367: // message receiver to use, etc.,
368:
369: String messageExchangePattern = axisOperation
370: .getMessageExchangePattern();
371: if (infoHolder.get(messageExchangePattern) == null) {
372: infoHolder.put(messageExchangePattern, Boolean.TRUE);
373: }
374:
375: if (mep == null) {
376:
377: opsFound = true;
378:
379: List soapHeaderInputParameterList = new ArrayList();
380: List soapHeaderOutputParameterList = new ArrayList();
381:
382: methodElement = doc.createElement("method");
383:
384: String localPart = axisOperation.getName()
385: .getLocalPart();
386: String opCName = makeCClassName(localPart);
387: String opNS = axisOperation.getName().getNamespaceURI();
388:
389: addAttribute(doc, "name", opCName, methodElement);
390: addAttribute(doc, "localpart", localPart, methodElement);
391: addAttribute(doc, "qname", localPart + "|" + opNS,
392: methodElement);
393:
394: addAttribute(doc, "namespace", opNS, methodElement);
395: String style = axisOperation.getStyle();
396: addAttribute(doc, "style", style, methodElement);
397: addAttribute(doc, "dbsupportname",
398: portTypeName + localPart
399: + DATABINDING_SUPPORTER_NAME_SUFFIX,
400: methodElement);
401:
402: addAttribute(doc, "mep", Utils
403: .getAxisSpecifMEPConstant(axisOperation
404: .getMessageExchangePattern())
405: + "", methodElement);
406: addAttribute(doc, "mepURI", axisOperation
407: .getMessageExchangePattern(), methodElement);
408:
409: addSOAPAction(doc, methodElement, axisOperation
410: .getName());
411: //add header ops for input
412: addHeaderOperations(soapHeaderInputParameterList,
413: axisOperation, true);
414: //add header ops for output
415: addHeaderOperations(soapHeaderOutputParameterList,
416: axisOperation, false);
417:
418: PolicyInclude policyInclude = axisOperation
419: .getPolicyInclude();
420: Policy policy = policyInclude.getPolicy();
421: if (policy != null) {
422: try {
423: addAttribute(doc, "policy", PolicyUtil
424: .policyComponentToString(policy),
425: methodElement);
426: } catch (Exception ex) {
427: throw new RuntimeException(
428: "can't serialize the policy to a String ",
429: ex);
430: }
431: }
432:
433: methodElement.appendChild(getInputElement(doc,
434: axisOperation, soapHeaderInputParameterList));
435: methodElement.appendChild(getOutputElement(doc,
436: axisOperation, soapHeaderOutputParameterList));
437: methodElement.appendChild(getFaultElement(doc,
438: axisOperation));
439:
440: rootElement.appendChild(methodElement);
441: } else {
442: //mep is present - we move ahead only if the given mep matches the mep of this operation
443:
444: if (mep.equals(axisOperation
445: .getMessageExchangePattern())) {
446: //at this point we know it's true
447: opsFound = true;
448: List soapHeaderInputParameterList = new ArrayList();
449: List soapHeaderOutputParameterList = new ArrayList();
450: List soapHeaderFaultParameterList = new ArrayList();
451: methodElement = doc.createElement("method");
452: String localPart = axisOperation.getName()
453: .getLocalPart();
454: String opCName = makeCClassName(localPart);
455: String opNS = axisOperation.getName()
456: .getNamespaceURI();
457:
458: addAttribute(doc, "name", opCName, methodElement);
459: addAttribute(doc, "localpart", localPart,
460: methodElement);
461: addAttribute(doc, "qname", localPart + "|" + opNS,
462: methodElement);
463:
464: addAttribute(doc, "namespace", axisOperation
465: .getName().getNamespaceURI(), methodElement);
466: addAttribute(doc, "style",
467: axisOperation.getStyle(), methodElement);
468: addAttribute(doc, "dbsupportname", portTypeName
469: + localPart
470: + DATABINDING_SUPPORTER_NAME_SUFFIX,
471: methodElement);
472:
473: addAttribute(doc, "mep", Utils
474: .getAxisSpecifMEPConstant(axisOperation
475: .getMessageExchangePattern())
476: + "", methodElement);
477: addAttribute(doc, "mepURI", axisOperation
478: .getMessageExchangePattern(), methodElement);
479:
480: addSOAPAction(doc, methodElement, axisOperation
481: .getName());
482: addHeaderOperations(soapHeaderInputParameterList,
483: axisOperation, true);
484: addHeaderOperations(soapHeaderOutputParameterList,
485: axisOperation, false);
486:
487: /*
488: * Setting the policy of the operation
489: */
490:
491: Policy policy = axisOperation.getPolicyInclude()
492: .getPolicy();
493: if (policy != null) {
494: try {
495: addAttribute(doc, "policy", PolicyUtil
496: .policyComponentToString(policy),
497: methodElement);
498: } catch (Exception ex) {
499: throw new RuntimeException(
500: "can't serialize the policy to a String",
501: ex);
502: }
503: }
504:
505: methodElement
506: .appendChild(getInputElement(doc,
507: axisOperation,
508: soapHeaderInputParameterList));
509: methodElement.appendChild(getOutputElement(doc,
510: axisOperation,
511: soapHeaderOutputParameterList));
512: methodElement.appendChild(getFaultElement(doc,
513: axisOperation));
514: rootElement.appendChild(methodElement);
515: //////////////////////
516: }
517:
518: }
519:
520: }
521:
522: return opsFound;
523: }
524:
525: /**
526: * A convenient method for the generating the parameter element
527: *
528: * @param doc
529: * @param paramName
530: * @param paramType
531: * @param opName
532: * @param paramName
533: */
534: protected Element generateParamComponent(Document doc,
535: String paramName, String paramType, QName opName,
536: String partName, boolean isPrimitive) {
537:
538: Element paramElement = doc.createElement("param");
539: //return paramElement;/*
540: addAttribute(doc, "name", paramName, paramElement);
541:
542: String typeMappingStr = (paramType == null) ? "" : paramType;
543:
544: if (JAVA_DEFAULT_TYPE.equals(typeMappingStr)) {
545: typeMappingStr = C_DEFAULT_TYPE;
546: }
547:
548: addAttribute(doc, "type", typeMappingStr, paramElement);
549: addAttribute(doc, "caps-type", typeMappingStr.toUpperCase(),
550: paramElement);
551:
552: //adds the short type
553: addShortType(paramElement, paramType);
554:
555: // add an extra attribute to say whether the type mapping is the default
556: if (mapper.getDefaultMappingName().equals(paramType)) {
557: addAttribute(doc, "default", "yes", paramElement);
558: }
559: addAttribute(doc, "value", getParamInitializer(paramType),
560: paramElement);
561: // add this as a body parameter
562: addAttribute(doc, "location", "body", paramElement);
563:
564: //if the opName and partName are present , add them
565: if (opName != null) {
566: addAttribute(doc, "opname", opName.getLocalPart(),
567: paramElement);
568:
569: }
570: if (partName != null) {
571: addAttribute(doc, "partname", JavaUtils
572: .capitalizeFirstChar(partName), paramElement);
573: }
574:
575: if (isPrimitive) {
576: addAttribute(doc, "primitive", "yes", paramElement);
577: }
578:
579: // the following methods are moved from addOurs functioin
580: Map typeMap = CTypeInfo.getTypeMap();
581: Iterator it = typeMap.keySet().iterator();
582: boolean isOurs = true;
583: while (it.hasNext()) {
584: if (it.next().equals(typeMappingStr)) {
585: isOurs = false;
586: break;
587: }
588: }
589:
590: if (isOurs && typeMappingStr.length() != 0
591: && !typeMappingStr.equals("void")
592: && !typeMappingStr.equals(C_DEFAULT_TYPE)) {
593: addAttribute(doc, "ours", "yes", paramElement);
594: } else {
595: isOurs = false;
596: }
597:
598: if (isOurs) {
599: typeMappingStr = C_OUR_TYPE_PREFIX + typeMappingStr
600: + C_OUR_TYPE_SUFFIX;
601: }
602:
603: addAttribute(doc, "axis2-type", typeMappingStr, paramElement);
604: addAttribute(doc, "axis2-caps-type", typeMappingStr
605: .toUpperCase(), paramElement);
606:
607: return paramElement; //*/
608: }
609:
610: /**
611: * @param doc
612: * @param operation
613: * @param param
614: */
615: protected void addCSpecifcAttributes(Document doc,
616: AxisOperation operation, Element param, String messageType) {
617: String typeMappingStr;
618: Map typeMap = CTypeInfo.getTypeMap();
619: Iterator typeMapIterator = typeMap.keySet().iterator();
620: AxisMessage message;
621:
622: if (messageType.equals(WSDLConstants.MESSAGE_LABEL_IN_VALUE))
623: message = operation
624: .getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
625: else
626: message = operation
627: .getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
628:
629: QName typeMapping = message.getElementQName();
630:
631: String paramType = this .mapper.getTypeMappingName(message
632: .getElementQName());
633: if (doc == null || paramType == null || param == null) {
634: return;
635: }
636:
637: if (message != null) {
638: String type = this .mapper.getTypeMappingName(message
639: .getElementQName());
640: typeMappingStr = (type == null) ? "" : type;
641: } else {
642: typeMappingStr = "";
643: }
644:
645: addAttribute(doc, "caps-type", paramType.toUpperCase(), param);
646: boolean isOurs = true;
647: while (typeMapIterator.hasNext()) {
648: if (typeMapIterator.next().equals(typeMapping)) {
649: isOurs = false;
650: break;
651: }
652: }
653:
654: if (isOurs && !paramType.equals("")
655: && !paramType.equals("void")
656: && !paramType.equals("org.apache.axiom.om.OMElement")
657: && !typeMappingStr.equals(C_DEFAULT_TYPE)) {
658: addAttribute(doc, "ours", "yes", param);
659: }
660: }
661:
662: /**
663: * @param doc
664: * @param operation
665: * @return Returns the parameter element.
666: */
667: protected Element[] getInputParamElement(Document doc,
668: AxisOperation operation) {
669: Element[] param = super .getInputParamElement(doc, operation);
670: for (int i = 0; i < param.length; i++) {
671: addCSpecifcAttributes(doc, operation, param[i],
672: WSDLConstants.MESSAGE_LABEL_IN_VALUE);
673: }
674:
675: return param;
676: }
677:
678: /**
679: * @param doc
680: * @param operation
681: * @return Returns Element.
682: */
683: protected Element getOutputParamElement(Document doc,
684: AxisOperation operation) {
685: Element param = super .getOutputParamElement(doc, operation);
686: addCSpecifcAttributes(doc, operation, param,
687: WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
688:
689: return param;
690: }
691:
692: /**
693: * Gets the output directory for source files.
694: *
695: * @param outputDir
696: * @return Returns File.
697: */
698: protected File getOutputDirectory(File outputDir, String dir2) {
699: if (dir2 != null && !"".equals(dir2)) {
700: if (outputDir.getName().equals(".")) {
701: outputDir = new File(outputDir, dir2);
702: }
703: }
704:
705: if (!outputDir.exists()) {
706: outputDir.mkdirs();
707: }
708:
709: return outputDir;
710: }
711:
712: }
|