/*=============================================================================*
* 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.lang.SerializationException;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.resource.properties.MetaDataViolationException;
import org.apache.ws.resource.properties.ResourceProperty;
import org.apache.ws.resource.properties.ResourcePropertyCallback;
import org.apache.ws.resource.properties.ResourcePropertyMetaData;
import org.apache.ws.resource.properties.ResourcePropertySet;
import org.apache.ws.resource.properties.ResourcePropertyValueChangeListener;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.i18n.Messages;
import org.apache.xmlbeans.XmlAnySimpleType;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.w3c.dom.Element;
import javax.xml.soap.SOAPElement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* LOG-DONE
* An Apache XMLBeans-based implementation of a resource property.
*
* @author Ian P. Springer
*/
public class XmlBeansResourceProperty
implements ResourceProperty
{
private static final Messages MSG = MessagesImpl.getInstance();
private ResourcePropertyMetaData m_metaData;
private XmlBeansResourcePropertySet m_propSet;
private List m_propElems = new ArrayList();
private ResourcePropertyCallback m_callBack;
private ResourcePropertyValueChangeListener m_changeListener;
/**
* Creates a new {@link XmlBeansResourceProperty} object.
*
* @param metaData DOCUMENT_ME
* @param propSet DOCUMENT_ME
*/
public XmlBeansResourceProperty( ResourcePropertyMetaData metaData,
XmlBeansResourcePropertySet propSet )
{
m_metaData = metaData;
m_propSet = propSet;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourcePropertyCallback getCallBack()
{
return m_callBack;
}
/**
* DOCUMENT_ME
*
* @param callback DOCUMENT_ME
*/
public void setCallback( ResourcePropertyCallback callback )
{
m_callBack = callback;
}
/**
* @return
*/
public boolean isEmpty()
{
return m_propElems.isEmpty();
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourcePropertyMetaData getMetaData()
{
return m_metaData;
}
/**
* @return
*/
public ResourcePropertySet getSet()
{
return m_propSet;
}
/**
* DOCUMENT_ME
*
* @param propElem DOCUMENT_ME
*
* @throws MetaDataViolationException if the name of the element to be added does not match the name associated with this property
*/
public void add( Object propElem )
{
XmlObject propXBean = toPropXBean( propElem );
trimValue( propXBean );
load( propXBean );
XmlBeanUtils.addChildElement( m_propSet.toXmlObject(),
propXBean );
}
/**
* @see org.apache.ws.resource.properties.ResourceProperty#clear()
*/
public void clear()
{
XmlBeanUtils.removeChildElements( m_propSet.toXmlObject(),
m_metaData.getName() );
m_propElems.clear();
}
/**
* DOCUMENT_ME
*
* @param index DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public Object get( int index )
{
return m_propElems.get( index );
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public Iterator iterator()
{
return m_propElems.iterator();
}
/**
* This method loads a property element XMLBean, which is already in the resource properties document, into this
* {@link XmlBeansResourceProperty}. It is called by {@link XmlBeansResourcePropertySet#XmlBeansResourcePropertySet(org.apache.xmlbeans.XmlObject)}
* to populate newly created {@link XmlBeansResourceProperty} objects.
*
* @param propXBean a property element XMLBean that is already in the resource properties document
*
* @throws MetaDataViolationException if the name of the element to be added does not match the name associated with this property
*/
public void load( XmlObject propXBean )
{
if ( !XmlBeanUtils.getName( propXBean ).equals( m_metaData.getName() ) )
{
throw new MetaDataViolationException( MSG.getMessage( Keys.PROP_MUST_BE_NAMED,
m_metaData.getName() ) );
}
m_propElems.add( propXBean );
}
/**
* DOCUMENT_ME
*
* @param propElem DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public boolean remove( Object propElem )
{
XmlObject propXBeanToRemove;
try
{
propXBeanToRemove = XmlBeanUtils.toXmlObject( propElem );
}
catch ( Exception e )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.UNABLE_TO_CONVERT_TO_XMLOBJECT ) );
}
if ( propXBeanToRemove.schemaType().getName().equals( m_metaData.getName() ) )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.PROP_ELEM_TO_REMOVE_MST_B_NAMED,
m_metaData.getName() ) );
}
for ( int index = 0; index < m_propElems.size(); index++ )
{
XmlObject propXBean = (org.apache.xmlbeans.XmlObject) m_propElems.get( index );
if ( propXBean.valueEquals( propXBeanToRemove ) )
{
XmlBeanUtils.remove( propXBean );
m_propElems.remove( index );
return true;
}
}
return false;
}
/**
* @see ResourceProperty#set(int, Object)
*/
public void set( int index,
Object propElem )
{
XmlObject propXBean = toPropXBean( propElem );
if ( !XmlBeanUtils.getName( propXBean ).equals( m_metaData.getName() ) )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.PROP_SET_MST_B_NAMED,
m_metaData.getName() ) );
}
if ( index >= m_propElems.size() )
{
throw new IndexOutOfBoundsException( MSG.getMessage( Keys.INDEX_MST_B_GTR0,
Integer.toString( m_propElems.size() ) ) );
}
XmlObject currentPropXBean = (XmlObject) m_propElems.get( index );
trimValue( propXBean );
currentPropXBean.set( propXBean );
}
/**
* @see ResourceProperty#size()
*/
public int size()
{
return m_propElems.size();
}
/**
* @see ResourceProperty#toElements()
*/
public Element[] toElements()
throws SerializationException
{
List elems = new ArrayList();
for ( int i = 0; i < m_propElems.size(); i++ )
{
XmlObject propXBean = (XmlObject) m_propElems.get( i );
elems.add( propXBean.newDomNode() );
}
return (Element[]) elems.toArray( new Element[0] );
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws SerializationException DOCUMENT_ME
*/
public SOAPElement[] toSOAPElements()
throws SerializationException
{
try
{
return XmlBeanUtils.toSOAPElementArray( (XmlObject[]) m_propElems.toArray( new XmlObject[0] ) );
}
catch ( Exception e )
{
throw new SerializationException( e );
}
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public String toString()
{
return toXML();
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public String toXML()
{
StringBuffer buf = new StringBuffer();
for ( int i = 0; i < m_propElems.size(); i++ )
{
XmlObject propXBean = (XmlObject) m_propElems.get( i );
buf.append( propXBean.xmlText( new XmlOptions().setSaveOuter().setSavePrettyPrint() ) );
}
return buf.toString();
}
/**
* @return
*/
public XmlObject[] toXmlObjects()
{
return (XmlObject[]) m_propElems.toArray( new XmlObject[0] );
}
public ResourcePropertyValueChangeListener getChangeListener()
{
return m_changeListener;
}
public void setChangeListener( ResourcePropertyValueChangeListener changeListener )
{
m_changeListener = changeListener;
}
private XmlObject toPropXBean( Object propElem )
{
XmlObject propXBean;
try
{
propXBean = XmlBeanUtils.getRootElement( XmlBeanUtils.toXmlObject( propElem ) );
}
catch ( Exception e )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.UNABLE_TO_CONVERT_TO_XMLOBJECT ) );
}
return propXBean;
}
private void trimValue( XmlObject propXBean )
{
// TODO: make this a configurable option
if ( propXBean instanceof XmlAnySimpleType )
{
XmlAnySimpleType simplePropXBean = (XmlAnySimpleType) propXBean;
String untrimmedValue = simplePropXBean.getStringValue();
String trimmedValue = ( untrimmedValue != null ) ? untrimmedValue.trim() : null;
simplePropXBean.setStringValue( trimmedValue );
}
}
}