/*=============================================================================*
* 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 (low priority): 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;
}
}