Package org.apache.ws.resource.properties.v1_2.porttype.impl

Source Code of org.apache.ws.resource.properties.v1_2.porttype.impl.SetResourcePropertiesProvider

/*=============================================================================*
*  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.v1_2.porttype.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.resource.ResourceContext;
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.SetResourcePropertyCallback;
import org.apache.ws.resource.properties.faults.InvalidResourcePropertyQNameFaultException;
import org.apache.ws.resource.properties.faults.InvalidSetResourcePropertiesRequestContentFaultException;
import org.apache.ws.resource.properties.faults.SetResourcePropertyRequestFailedFaultException;
import org.apache.ws.resource.properties.faults.UnableToModifyResourcePropertyFaultException;
import org.apache.ws.resource.properties.impl.AnyResourcePropertyMetaData;
import org.apache.ws.resource.properties.v1_2.porttype.SetResourcePropertiesPortType;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.i18n.Messages;
import org.apache.xmlbeans.XmlObject;
import org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.DeleteType;
import org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.InsertType;
import org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.SetResourcePropertiesDocument;
import org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.SetResourcePropertiesResponseDocument;
import org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.UpdateType;

import javax.xml.namespace.QName;
import java.util.Iterator;

/**
* LOG-DONE An operation provider for wsrp:SetResourceProperties.
*
* @author Ian P. Springer
*/
public class SetResourcePropertiesProvider
        extends AbstractResourcePropertiesPortType
        implements SetResourcePropertiesPortType
{

    private static final Log LOG = LogFactory.getLog( SetResourcePropertiesProvider.class );
    private static final Messages MSG = MessagesImpl.getInstance();

    /**
     * Creates a new {@link SetResourcePropertiesProvider} object.
     *
     * @param resourceContext DOCUMENT_ME
     */
    public SetResourcePropertiesProvider( ResourceContext resourceContext )
    {
        super( resourceContext );
    }

    /**
     * Implementation of the wsrp:SetResourceProperties operation.
     *
     * @param requestDoc the requestDoc XMLBean
     *
     * @return the response XMLBean
     *
     * @throws org.apache.ws.resource.properties.faults.InvalidResourcePropertyQNameFaultException
     *
     * @throws org.apache.ws.resource.faults.ResoureKeyHeaderNotFoundFaultException
     *
     */
    public SetResourcePropertiesResponseDocument setResourceProperties( SetResourcePropertiesDocument requestDoc )
    {
        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( MSG.getMessage( Keys.SET_RP_REQ,
                    requestDoc.toString() ) );
        }

        SetResourcePropertiesResponseDocument responseDoc = createResponseDocument();
        SetResourcePropertiesDocument.SetResourceProperties requestElem = requestDoc.getSetResourceProperties();

        InsertType[] insertElems = requestElem.getInsertArray();
        for ( int i = 0; i < insertElems.length; i++ )
        {
            insertResourceProperty( insertElems[i] );
        }

        DeleteType[] deleteElems = requestElem.getDeleteArray();
        for ( int i = 0; i < deleteElems.length; i++ )
        {
            deleteResourceProperty( deleteElems[i] );
        }

        UpdateType[] updateElems = requestElem.getUpdateArray();
        for ( int i = 0; i < updateElems.length; i++ )
        {
            updateResourceProperty( updateElems[i] );
        }

        return responseDoc;
    }

    /**
     * DOCUMENT_ME
     *
     * @param deleteElem DOCUMENT_ME
     */
    protected void deleteResourceProperty( DeleteType deleteElem )
    {
        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( MSG.getMessage( Keys.DEL_RP_REQ,
                    deleteElem.toString() ) );
        }
        QName nameOfPropToBeDeleted = deleteElem.getResourceProperty();
        if ( nameOfPropToBeDeleted == null )
        {
            throw new InvalidSetResourcePropertiesRequestContentFaultException( MSG.getMessage( Keys.DEL_MISSING_RP_ATTRIB ) );
        }
        ResourceProperty prop = getProperties().get( nameOfPropToBeDeleted );
        if ( prop == null )
        {
            if ( getProperties().getMetaData().isOpenContent() )
            {
                return;
            } else
            {
                throw new InvalidResourcePropertyQNameFaultException( nameOfPropToBeDeleted );
            }
        }
        throwFaultIfPropertyIsReadOnly( prop );
        throwFaultIfDeletionViolatesSchema( prop );
        try
        {
            deletePropertyCallback( prop );
        }
        catch ( RuntimeException re )
        {
            throw new SetResourcePropertyRequestFailedFaultException( re.toString() );
        }
        Object[] oldValue = getValue( prop );
        prop.clear();
        Object[] newValue = null;
        if ( prop.getChangeListener() != null )
        {
            firePropChangeEvent( prop, oldValue, newValue );
        }
    }

    /**
     * DOCUMENT_ME
     *
     * @param insertElem DOCUMENT_ME
     */
    protected void insertResourceProperty( InsertType insertElem )
    {
        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( MSG.getMessage( Keys.INSERT_RP_REQ,
                    insertElem.toString() ) );
        }

        XmlObject[] propElemsToBeInserted = XmlBeanUtils.getChildElements( insertElem );
        if ( propElemsToBeInserted.length == 0 )
        {
            return; // nothing to do
        }
        throwFaultIfElementNamesHeterogenous( propElemsToBeInserted );

        QName propName = XmlBeanUtils.getName( propElemsToBeInserted[0] );
        ResourceProperty prop = getProperty( propName );

        if(prop == null)
        {
            prop = createAnyProperty(propName);
            getProperties().add(prop);
        }

        if(!prop.getMetaData().isAny())
        {
            //todo probably need to check this for xsd:any to check for possible violations
            //refreshProperty( prop );
            throwFaultIfInsertionViolatesSchema( prop, propElemsToBeInserted );
        }

        throwFaultIfPropertyIsReadOnly( prop );

        try
        {
            insertPropertyCallback( prop, propElemsToBeInserted );
        }
        catch ( RuntimeException re )
        {
            throw new SetResourcePropertyRequestFailedFaultException( re.toString() );
        }

        Object[] oldValue = getValue( prop );
        for ( int i = 0; i < propElemsToBeInserted.length; i++ )
        {
            try
            {
                prop.add( propElemsToBeInserted[i] );
            }
            catch ( MetaDataViolationException mdve )
            {
                throw new InvalidSetResourcePropertiesRequestContentFaultException( mdve );
            }
        }
        Object[] newValue = getValue( prop );
        if ( prop.getChangeListener() != null )
        {
            firePropChangeEvent( prop, oldValue, newValue );
        }
    }

    private void firePropChangeEvent( ResourceProperty prop, Object[] oldValue, Object[] newValue )
    {
        prop.getChangeListener().propertyChanged( new XmlBeansResourcePropertyValueChangeEvent( oldValue, newValue ) );
    }

    /**
     * DOCUMENT_ME
     *
     * @param updateElem DOCUMENT_ME
     */
    protected void updateResourceProperty( UpdateType updateElem )
    {
        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( MSG.getMessage( Keys.UPDATE_RP_REQ,
                    updateElem.toString() ) );
        }

        XmlObject[] newPropElems = XmlBeanUtils.getChildElements( updateElem );
        if ( newPropElems.length == 0 )
        {
            return; // nothing to do
        }

        QName propName = XmlBeanUtils.getName( newPropElems[0] );
        ResourceProperty prop = getProperty( propName );

        throwFaultIfPropertyIsReadOnly( prop );
        throwFaultIfElementNamesHeterogenous( newPropElems );
        throwFaultIfUpdateViolatesSchema( prop, newPropElems );

        try
        {
            updatePropertyCallback( prop, newPropElems );
        }
        catch ( RuntimeException re )
        {
            throw new SetResourcePropertyRequestFailedFaultException( re.toString() );
        }

        Object[] oldValue = getValue( prop );
        // TODO: we might need to clone the oldValue elems, since we might be destroying them when we call clear() below
        try
        {
            prop.clear();
            for ( int i = 0; i < newPropElems.length; i++ )
            {
                prop.add( newPropElems[i] );
            }
        }
        catch ( MetaDataViolationException mdve )
        {
            throw new InvalidSetResourcePropertiesRequestContentFaultException( mdve );
        }
        Object[] newValue = getValue( prop );
        if ( prop.getChangeListener() != null )
        {
            firePropChangeEvent( prop, oldValue, newValue );
        }
    }

    private ResourceProperty createAnyProperty(QName propName)
    {
        ResourcePropertyMetaData propMetaData = new AnyResourcePropertyMetaData( propName );
        return propMetaData.create( getProperties() );
    }

    private Object[] getValue( ResourceProperty prop )
    {
        Object[] value = new Object[prop.size()];
        Iterator propElemIter = prop.iterator();
        int i = 0;
        while ( propElemIter.hasNext() )
        {
            value[i++] = propElemIter.next();
        }
        return value;
    }

    private ResourceProperty getProperty( QName propName )
    {
        LOG.debug( MSG.getMessage( Keys.GET_RP_WITH_NAME,
                propName.toString() ) );
        ResourceProperty prop = getProperties().get( propName );
        if ( prop == null )
        {
            if ( !getProperties().getMetaData().isOpenContent() )
            {
                throw new InvalidResourcePropertyQNameFaultException( propName );
            }
        }
        return prop;
    }

    private void throwFaultIfElementNamesHeterogenous( XmlObject[] propElems )
    {
        QName firstPropElemName = XmlBeanUtils.getName( propElems[0] );
        for ( int i = 1; i < propElems.length; i++ )
        {
            QName propElemName = XmlBeanUtils.getName( propElems[i] );
            if ( !firstPropElemName.equals( propElemName ) )
            {
                throw new InvalidSetResourcePropertiesRequestContentFaultException( MSG.getMessage( Keys.ERROR_PROPERTY_INSERT_VIOLATES_SCHEMA,
                        ( ( propElems.length > 1 )
                        ? "s" : "" ),
                        firstPropElemName ) );
            }
        }
    }

    private void throwFaultIfDeletionViolatesSchema( ResourceProperty prop )
    {
        if ( prop.getMetaData().getMinOccurs() != 0 )
        {
            throw new InvalidSetResourcePropertiesRequestContentFaultException( MSG.getMessage( Keys.ERROR_PROPERTY_DELETE_VIOLATES_SCHEMA,
                    prop.getMetaData().getName() ) );
        }
    }

    private void throwFaultIfInsertionViolatesSchema( ResourceProperty prop, XmlObject[] propElemsToBeInserted )
    {
        //todo probably need to check this for xsd:any to check for possible violations
        if ( prop.getMetaData().getMaxOccurs() != -1 &&( prop.size() + propElemsToBeInserted.length ) > prop.getMetaData().getMaxOccurs() )
        {
            throw new InvalidSetResourcePropertiesRequestContentFaultException( MSG.getMessage( Keys.ERROR_PROPERTY_INSERT_VIOLATES_SCHEMA,
                    ( ( propElemsToBeInserted.length > 1 )
                    ? "s" : "" ),
                    prop.getMetaData().getName() ) );
        }
    }

    private void throwFaultIfUpdateViolatesSchema( ResourceProperty prop, XmlObject[] newPropElems )
    {
        if ( prop.getMetaData().getMaxOccurs() != -1 && newPropElems.length > prop.getMetaData().getMaxOccurs() )
        {
            throw new InvalidSetResourcePropertiesRequestContentFaultException( MSG.getMessage( Keys.ERROR_PROPERTY_UPDATE_VIOLATES_SCHEMA,
                    prop.getMetaData().getName() ) );
        }
    }

    /**
     * Returns SetResourcePropertyCallback or null
     *
     * @param prop
     *
     * @return SetResourcePropertyCallback or null
     */
    private SetResourcePropertyCallback getSetResourcePropertyCallback( ResourceProperty prop )
    {
        SetResourcePropertyCallback setResourcePropertyCallback = null;
        ResourcePropertyCallback callBack = prop.getCallBack();
        if ( callBack instanceof SetResourcePropertyCallback )
        {
            setResourcePropertyCallback = (SetResourcePropertyCallback) callBack;
        }

        return setResourcePropertyCallback;
    }

    private SetResourcePropertiesResponseDocument createResponseDocument()
    {
        SetResourcePropertiesResponseDocument responseDoc =
                SetResourcePropertiesResponseDocument.Factory.newInstance();
        responseDoc.addNewSetResourcePropertiesResponse();
        return responseDoc;
    }

    private void deletePropertyCallback( ResourceProperty prop )
    {
        QName nameOfPropToBeDeleted = prop.getMetaData().getName();
        SetResourcePropertyCallback setResourcePropertyCallback = getSetResourcePropertyCallback( prop );
        if ( setResourcePropertyCallback != null )
        {
            setResourcePropertyCallback.deleteProperty( nameOfPropToBeDeleted );
        }
    }

    private void insertPropertyCallback( ResourceProperty prop,
                                         XmlObject[] propElemsToBeInserted )
    {
        SetResourcePropertyCallback setResourcePropertyCallback = getSetResourcePropertyCallback( prop );
        if ( setResourcePropertyCallback != null )
        {
            setResourcePropertyCallback.insertProperty( propElemsToBeInserted );
        }
    }

    private void throwFaultIfPropertyIsReadOnly( ResourceProperty prop )
    {
        if ( prop.getMetaData().isReadOnly() )
        {
            throw new UnableToModifyResourcePropertyFaultException( prop.getMetaData().getName() );
        }
    }

    private void updatePropertyCallback( ResourceProperty prop,
                                         XmlObject[] newPropElems )
    {
        SetResourcePropertyCallback setResourcePropertyCallback = getSetResourcePropertyCallback( prop );
        if ( setResourcePropertyCallback != null )
        {
            setResourcePropertyCallback.updateProperty( newPropElems );
        }
    }
}
TOP

Related Classes of org.apache.ws.resource.properties.v1_2.porttype.impl.SetResourcePropertiesProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.