package org.apache.axis2.wsdl.codegen.extension; | |
import org.apache.axis2.wsdl.codegen.CodeGenConfiguration; | |
import org.apache.axis2.wsdl.codegen.CodeGenerationException; | |
import org.apache.axis2.wsdl.databinding.DefaultTypeMapper; | |
import org.apache.axis2.wsdl.databinding.TypeMapper; | |
import org.apache.axis2.wsdl.i18n.CodegenMessages; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Element; | |
import org.w3c.dom.Node; | |
import org.w3c.dom.NodeList; | |
import javax.xml.namespace.QName; | |
import javax.xml.parsers.DocumentBuilder; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
/* | |
* Copyright 2004,2005 The Apache Software Foundation. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** | |
* The purpose of this extension is to populate the type mapper from the | |
* type mapping file. The format of the type mapping file is as follows | |
* <mappings dbf="adb"> | |
* <mapping> | |
* <qname namespace="ns" prefix="p1">localName</qname> | |
* <value>type</value> | |
* </mapping> | |
* </mappings> | |
* | |
* In any case it is best that the type mapper extension be after all the | |
* databinding extensions | |
*/ | |
public class TypeMapperExtension implements CodeGenExtension { | |
private static final String MAPPING_ELEMENT_NAME = "mapping"; | |
private static final String NAMESPACE_ATTRIBUTE_NAME = "namespace"; | |
private static final String QNAME_ELEMENT_NAME = "qname"; | |
private static final String VALUE_ELEMENT_NAME = "value"; | |
private static final String DB_FRAMEWORK_ATTRIBUTE_NAME = "dbf"; | |
/** | |
* | |
* @throws CodeGenerationException | |
*/ | |
public void engage(CodeGenConfiguration configuration) throws CodeGenerationException { | |
if (configuration.getTypeMappingFile()!=null){ | |
//a type mapping is present. try building the | |
//mapping from it | |
// if the configuration already has a mapping then take it | |
// the external mappings will override the currently available | |
// mappings | |
TypeMapper mapper = configuration.getTypeMapper(); | |
// there is no mapper present - so just create a new one | |
if (mapper==null){ | |
mapper = new DefaultTypeMapper(); | |
} | |
//read the file as a DOM | |
Document mappingDocument = buildDocument(configuration); | |
Element rootMappingsElement = mappingDocument.getDocumentElement(); | |
//override the databinding framework name. If a mapping file is | |
//present then the databinding framework name will be overridden | |
//if present. If a user wants to mix types then it must be | |
//from the same databinding framework! | |
//first do a sanity check to see whether the user is trying to | |
//mix databinding types! | |
String databindingName = rootMappingsElement. | |
getAttribute(DB_FRAMEWORK_ATTRIBUTE_NAME); | |
if (!databindingName.equals(configuration.getDatabindingType())){ | |
throw new CodeGenerationException( | |
CodegenMessages. | |
getMessage("extension.databindingMismatch") | |
); | |
} | |
configuration. | |
setDatabindingType( | |
databindingName); | |
NodeList mappingList = rootMappingsElement. | |
getElementsByTagName(MAPPING_ELEMENT_NAME); | |
int length = mappingList.getLength(); | |
for (int i = 0; i < length; i++) { | |
Element mappingNode = (Element)mappingList.item(i); | |
//we know this is only one - if there are multiple then | |
//it is invalid | |
Element qNameChild = | |
(Element)mappingNode. | |
getElementsByTagName(QNAME_ELEMENT_NAME).item(0); | |
Element valueChild = | |
(Element)mappingNode. | |
getElementsByTagName(VALUE_ELEMENT_NAME).item(0); | |
//generate a Qname and add to the type mapping | |
mapper.addTypeMappingName(new QName( | |
qNameChild.getAttribute(NAMESPACE_ATTRIBUTE_NAME), | |
getTextFromElement(qNameChild)), | |
getTextFromElement(valueChild)); | |
} | |
//set the type mapper to the configurtion | |
configuration.setTypeMapper(mapper); | |
} | |
} | |
/** | |
* Build a dom document from the mapping file | |
* @throws CodeGenerationException | |
*/ | |
private Document buildDocument(CodeGenConfiguration configuration) throws CodeGenerationException { | |
try { | |
DocumentBuilderFactory documentBuilderFactory | |
= DocumentBuilderFactory.newInstance(); | |
documentBuilderFactory.setNamespaceAware(true); | |
DocumentBuilder documentBuilder = | |
documentBuilderFactory.newDocumentBuilder(); | |
return documentBuilder.parse(configuration.getTypeMappingFile()); | |
} catch (Exception e) { | |
throw new CodeGenerationException(e); | |
} | |
} | |
/** | |
* Gets the string content from an element. returns null if there are | |
* no test nodes found | |
* @param elt | |
* @return text cotent of the element | |
*/ | |
private String getTextFromElement(Element elt){ | |
NodeList children = elt.getChildNodes(); | |
String returnString = null; | |
int length = children.getLength(); | |
for (int i = 0; i < length; i++) { | |
Node node = children.item(i); | |
if (Node.TEXT_NODE == node.getNodeType()){ | |
returnString = (returnString==null?"":returnString) + node.getNodeValue(); | |
} | |
} | |
return returnString; | |
} | |
} |