/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ws.metadata.umdm;
// $Id: TypesMetaData.java 2275 2007-02-05 11:19:25Z heiko.braun@jboss.com $
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTypeDefinition;
import org.jboss.logging.Logger;
import org.jboss.ws.WSException;
import org.jboss.ws.core.jaxrpc.LiteralTypeMapping;
import org.jboss.ws.metadata.wsdl.xmlschema.JBossXSModel;
/**
* Types meta data
*
* @author Thomas.Diesler@jboss.org
* @since 12-May-2005
*/
public class TypesMetaData
{
// provide logging
private static final Logger log = Logger.getLogger(TypesMetaData.class);
// The parent meta data.
private ServiceMetaData serviceMetaData;
// The list of type meta data
private List<TypeMappingMetaData> typeList = new ArrayList<TypeMappingMetaData>();
private JBossXSModel schemaModel;
public TypesMetaData(ServiceMetaData serviceMetaData)
{
this.serviceMetaData = serviceMetaData;
}
public ServiceMetaData getServiceMetaData()
{
return serviceMetaData;
}
public JBossXSModel getSchemaModel()
{
return schemaModel;
}
public void setSchemaModel(JBossXSModel model)
{
this.schemaModel = model;
}
public void addSchemaModel(JBossXSModel model)
{
if (this.schemaModel == null)
{
this.schemaModel = model;
}
else
{
this.schemaModel.merge(model);
}
}
public List<TypeMappingMetaData> getTypeMappings()
{
return new ArrayList<TypeMappingMetaData>(typeList);
}
public void addTypeMapping(TypeMappingMetaData tmMetaData)
{
if (typeList.contains(tmMetaData) == false)
{
log.trace("Add type mapping: " + tmMetaData);
typeList.add(tmMetaData);
}
}
public TypeMappingMetaData getTypeMappingByXMLType(QName xmlType)
{
TypeMappingMetaData tmMetaData = null;
for (TypeMappingMetaData aux : typeList)
{
boolean isElementScope = TypeMappingMetaData.QNAME_SCOPE_ELEMENT.equals(aux.getQNameScope());
if (aux.getXmlType().equals(xmlType) && isElementScope == false)
{
if (tmMetaData != null)
{
log.error(tmMetaData + "\n" + aux);
throw new WSException("Ambiguous type mappping for: " + xmlType);
}
tmMetaData = aux;
}
}
if (tmMetaData == null && schemaModel != null)
{
// Simple types are not neccessary mapped in jaxrpc-mapping.xml, lazily add the mapping here
XSTypeDefinition xsType = schemaModel.getTypeDefinition(xmlType.getLocalPart(), xmlType.getNamespaceURI());
if (xsType instanceof XSSimpleTypeDefinition)
{
XSSimpleTypeDefinition xsSimpleType = (XSSimpleTypeDefinition)xsType;
String javaTypeName = null;
// <simpleType name="FooStringListType">
// <list itemType="string"/>
// </simpleType>
if (xsSimpleType.getVariety() == XSSimpleTypeDefinition.VARIETY_LIST)
{
XSSimpleTypeDefinition itemType = xsSimpleType.getItemType();
QName xmlBaseType = new QName(itemType.getNamespace(), itemType.getName());
javaTypeName = new LiteralTypeMapping().getJavaTypeName(xmlBaseType);
if (javaTypeName != null)
{
javaTypeName += "[]";
}
}
// <simpleType name="FooIType">
// <restriction base="normalizedString">
// <pattern value="\d{3}-[A-Z0-9]{5}"/>
// </restriction>
// </simpleType>
XSTypeDefinition xsBaseType = xsType.getBaseType();
while (javaTypeName == null && xsBaseType != null)
{
QName xmlBaseType = new QName(xsBaseType.getNamespace(), xsBaseType.getName());
javaTypeName = new LiteralTypeMapping().getJavaTypeName(xmlBaseType);
xsBaseType = xsBaseType.getBaseType();
}
if (javaTypeName != null)
{
tmMetaData = new TypeMappingMetaData(this, xmlType, javaTypeName);
tmMetaData.setQNameScope(TypeMappingMetaData.QNAME_SCOPE_SIMPLE_TYPE);
if(log.isDebugEnabled()) log.debug("Adding a simpleType without jaxrpc-mapping: " + tmMetaData);
addTypeMapping(tmMetaData);
}
else
{
log.warn("Cannot obtain javaTypeName for xmlType: " + xmlType);
}
}
}
return tmMetaData;
}
public TypeMappingMetaData getTypeMappingByJavaType(String javaTypeName)
{
TypeMappingMetaData tmMetaData = null;
for (TypeMappingMetaData aux : typeList)
{
if (aux.getJavaTypeName().equals(javaTypeName))
tmMetaData = aux;
}
return tmMetaData;
}
public String toString()
{
StringBuilder buffer = new StringBuilder("\nTypesMetaData: ");
for (TypeMappingMetaData tmd : typeList)
{
buffer.append("\n " + tmd);
}
buffer.append("\n" + (schemaModel != null ? schemaModel.serialize() : "<schema/>"));
return buffer.toString();
}
}