/*=============================================================================*
* Copyright 2004 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.
*=============================================================================*/
package org.apache.ws.resource.properties.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.resource.properties.ResourcePropertyMetaData;
import org.apache.ws.resource.properties.ResourcePropertySet;
import org.apache.ws.resource.properties.ResourcePropertySetMetaData;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.i18n.Messages;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlObject;
import org.oasisOpen.docs.wsrf.x2004.x10.wsrfWSResourceMetadataDescriptor10Draft01.MetadataDescriptorType;
import org.oasisOpen.docs.wsrf.x2004.x10.wsrfWSResourceMetadataDescriptor10Draft01.PropertyType;
import javax.xml.namespace.QName;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* An Apache XMLBeans-based implementation of resource property set metadata.
*
* @author Ian P. Springer
*/
public class XmlBeansResourcePropertySetMetaData
implements ResourcePropertySetMetaData
{
private static final Log LOG = LogFactory.getLog( XmlBeansResourcePropertySetMetaData.class );
private static final Messages MSG = MessagesImpl.getInstance();
private final SchemaType m_schemaType;
private final Map m_propMetaDatas = new HashMap();
/**
* Creates a new {@link XmlBeansResourcePropertySetMetaData} object.
*
* @param schemaType DOCUMENT_ME
*/
public XmlBeansResourcePropertySetMetaData( SchemaType schemaType )
{
this( schemaType, new QName[0] );
}
/**
* Creates a new {@link XmlBeansResourcePropertySetMetaData} object.
*
* @param schemaType DOCUMENT_ME
*/
public XmlBeansResourcePropertySetMetaData( SchemaType schemaType, MetadataDescriptorType metaDataDesc )
{
if ( !schemaType.isDocumentType() )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.SCHEMA_MUST_BE_DOC ) );
}
m_schemaType = schemaType;
SchemaProperty[] elemTypes = m_schemaType.getElementProperties()[0].getType().getElementProperties();
for ( int i = 0; i < elemTypes.length; i++ )
{
PropertyType propDesc = getPropertyDesc( metaDataDesc, elemTypes[i].getName() );
m_propMetaDatas.put( elemTypes[i].getName(),
new XmlBeansResourcePropertyMetaData( elemTypes[i], propDesc ) );
}
}
/**
* Creates a new {@link XmlBeansResourcePropertySetMetaData} object.
*
* @param schemaType DOCUMENT_ME
*/
public XmlBeansResourcePropertySetMetaData( SchemaType schemaType, QName[] readOnlyPropNames )
{
if ( !schemaType.isDocumentType() )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.SCHEMA_MUST_BE_DOC ) );
}
m_schemaType = schemaType;
SchemaProperty[] elemTypes = m_schemaType.getElementProperties()[0].getType().getElementProperties();
Set readOnlyPropNameSet = toSet( readOnlyPropNames );
for ( int i = 0; i < elemTypes.length; i++ )
{
m_propMetaDatas.put( elemTypes[i].getName(),
new XmlBeansResourcePropertyMetaData( elemTypes[i], readOnlyPropNameSet.contains( elemTypes[i].getName() ) ) );
}
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public QName getName()
{
return m_schemaType.getDocumentElementName();
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public boolean isOpenContent()
{
SchemaType[] anonTypes = m_schemaType.getAnonymousTypes();
for ( int i = 0; i < anonTypes.length; i++ )
{
if ( anonTypes[i].hasElementWildcards() )
{
return true;
}
}
return false;
}
/**
* DOCUMENT_ME
*
* @param name DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourcePropertyMetaData getPropertyMetaData( QName name )
{
return (ResourcePropertyMetaData) m_propMetaDatas.get( name );
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourcePropertyMetaData[] getPropertyMetaDatas()
{
return (ResourcePropertyMetaData[]) m_propMetaDatas.values().toArray( new ResourcePropertyMetaData[0] );
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourcePropertySet create()
{
try
{
Class factoryClass = Class.forName( m_schemaType.getFullJavaName() + "$Factory" );
LOG.debug( MSG.getMessage( Keys.CREATING_PROPSET, factoryClass ) );
Method newInstanceMethod = factoryClass.getMethod( "newInstance", null );
XmlObject propsDocXBean = (XmlObject) newInstanceMethod.invoke( null, new Object[0] );
return new XmlBeansResourcePropertySet( propsDocXBean );
}
catch ( Exception e )
{
throw new RuntimeException( e );
}
}
private static PropertyType getPropertyDesc( MetadataDescriptorType metadataDesc, QName propName )
{
// TODO: recurse into inherited descriptors when looking for property descs
// (assume inherited-desc locations are absolute URLs, since we don't know our base URL)
if ( metadataDesc != null )
{
PropertyType[] propDescs = metadataDesc.getPropertyArray();
for ( int i = 0; i < propDescs.length; i++ )
{
QName name = XmlBeanUtils.getAttributeValueAsQName( propDescs[i], new QName( "", "path" ) );
if ( name.equals( propName ) )
{
return propDescs[i];
}
}
}
return null;
}
private static Set toSet( Object[] array )
{
Set set = new HashSet();
if ( array != null )
{
for ( int i = 0; i < array.length; i++ )
{
set.add( array[i] );
}
}
return set;
}
}