<commit_before>/*************************************************************************
 *
 *  $RCSfile: dispatchrecordersupplier.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: as $ $Date: 2002-04-22 13:49:47 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
// include own things

#ifndef __FRAMEWORK_RECORDING_DISPATCHRECORDERSUPPLIER_HXX_
#include <recording/dispatchrecordersupplier.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
// include interfaces

#ifndef _COM_SUN_STAR_FRAME_XRECORDABLEDISPATCH_HPP_
#include <com/sun/star/frame/XRecordableDispatch.hpp>
#endif

//_________________________________________________________________________________________________________________
// include other projects

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

//_________________________________________________________________________________________________________________
// namespace

namespace framework{

//_________________________________________________________________________________________________________________
// non exported const

//_________________________________________________________________________________________________________________
// non exported definitions

//_________________________________________________________________________________________________________________
// declarations

//*****************************************************************************************************************
//  XInterface, XTypeProvider
//*****************************************************************************************************************
DEFINE_XINTERFACE_3(
    DispatchRecorderSupplier,
    OWeakObject,
    DIRECT_INTERFACE(css::lang::XTypeProvider),
    DIRECT_INTERFACE(css::lang::XServiceInfo),
    DIRECT_INTERFACE(css::frame::XDispatchRecorderSupplier))

DEFINE_XTYPEPROVIDER_3(
    DispatchRecorderSupplier,
    css::lang::XTypeProvider,
    css::lang::XServiceInfo,
    css::frame::XDispatchRecorderSupplier)

DEFINE_XSERVICEINFO_MULTISERVICE(
    DispatchRecorderSupplier,
    ::cppu::OWeakObject,
    SERVICENAME_DISPATCHRECORDERSUPPLIER,
    IMPLEMENTATIONNAME_DISPATCHRECORDERSUPPLIER)

DEFINE_INIT_SERVICE(
    DispatchRecorderSupplier,
    {
        /*Attention
            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
            to create a new instance of this class by our own supported service factory.
            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
        */
    }
)

//_____________________________________________________________________________
/**
    @short  standard constructor to create instance
    @descr  Because an instance will be initialized by her interface methods
            it's not neccessary to do anything here.
 */
DispatchRecorderSupplier::DispatchRecorderSupplier( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
        //  init baseclasses first!
        //  Attention: Don't change order of initialization!
        : ThreadHelpBase     ( &Application::GetSolarMutex() )
        , ::cppu::OWeakObject(                               )
        //  init member
        , m_xFactory         ( xFactory                      )
        , m_xDispatchRecorder( NULL                          )
{
}

//_____________________________________________________________________________
/**
    @short  standard destructor
    @descr  We are a helper and not a real service. So we doesn't provide
            dispose() functionality. This supplier dies by ref count mechanism
            and should release all internal used ones too.
 */
DispatchRecorderSupplier::~DispatchRecorderSupplier()
{
    m_xFactory          = NULL;
    m_xDispatchRecorder = NULL;
}

//_____________________________________________________________________________
/**
    @short      set a new dispatch recorder on this supplier
    @descr      Because there can exist more then one recorder implementations
                (to generate java/basic/... scripts from recorded data) it must
                be possible to set it on a supplier.

    @see        getDispatchRecorder()

    @param      xRecorder
                the new recorder to set it

<NULL/> isn't recommended, because recording without a
                valid recorder can't work. But it's not checked here. So user
                of this supplier can decide that without changing this
                implementation.

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::setDispatchRecorder( const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    WriteGuard aWriteLock(m_aLock);
    m_xDispatchRecorder=xRecorder;
    // => SAFE
}
//_____________________________________________________________________________
/**
    @short      provides access to the dispatch recorder of this supplier
    @descr      Such recorder can be used outside to record dispatches.
                But normaly he is used internaly only. Of course he must used
                from outside to get the recorded data e.g. for saving it as a
                script.

    @see        setDispatchRecorder()

    @return     the internal used dispatch recorder

May it can be <NULL/> if no one was set before.

    @change     09.04.2002 by Andreas Schluens
 */
css::uno::Reference< css::frame::XDispatchRecorder > SAL_CALL DispatchRecorderSupplier::getDispatchRecorder() throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    return m_xDispatchRecorder;
    // => SAFE
}

//_____________________________________________________________________________
/**
    @short      execute a dispatch request and record it
    @descr      If given dispatch object provides right recording interface it
                will be used. If it's not supported it record the pure dispatch
                parameters only. There is no code neither the possibility to
                check if recording is enabled or not.

    @param      aURL            the command URL
    @param      lArguments      optional arguments (see com.sun.star.document.MediaDescriptor for further informations)
    @param      xDispatcher     the original dispatch object which should be recorded

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::dispatchAndRecord( const css::util::URL&                                  aURL        ,
                                                           const css::uno::Sequence< css::beans::PropertyValue >& lArguments  ,
                                                           const css::uno::Reference< css::frame::XDispatch >&    xDispatcher ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::frame::XDispatchRecorder > xRecorder = m_xDispatchRecorder;
    aReadLock.unlock();
    // => SAFE

    css::uno::Reference< css::frame::XRecordableDispatch > xRecordable(
        xDispatcher,
        css::uno::UNO_QUERY);

    if (xRecordable.is())
        xRecordable->dispatchAndRecord(aURL,lArguments,xRecorder);
    else
    {
        // There is no reason to wait for information about success
        // of this request. Because status information of a dispatch
        // are not guaranteed. So we execute it and record used
        // parameters only.
        xDispatcher->dispatch(aURL,lArguments);
        xRecorder->recordDispatch(aURL,lArguments);
    }
}

}   // namespace framework
<commit_msg>#103542# react for wrong using of API<commit_after>/*************************************************************************
 *
 *  $RCSfile: dispatchrecordersupplier.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: as $ $Date: 2002-09-23 05:52:38 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
// include own things

#ifndef __FRAMEWORK_RECORDING_DISPATCHRECORDERSUPPLIER_HXX_
#include <recording/dispatchrecordersupplier.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
// include interfaces

#ifndef _COM_SUN_STAR_FRAME_XRECORDABLEDISPATCH_HPP_
#include <com/sun/star/frame/XRecordableDispatch.hpp>
#endif

//_________________________________________________________________________________________________________________
// include other projects

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

//_________________________________________________________________________________________________________________
// namespace

namespace framework{

//_________________________________________________________________________________________________________________
// non exported const

//_________________________________________________________________________________________________________________
// non exported definitions

//_________________________________________________________________________________________________________________
// declarations

//*****************************************************************************************************************
//  XInterface, XTypeProvider
//*****************************************************************************************************************
DEFINE_XINTERFACE_3(
    DispatchRecorderSupplier,
    OWeakObject,
    DIRECT_INTERFACE(css::lang::XTypeProvider),
    DIRECT_INTERFACE(css::lang::XServiceInfo),
    DIRECT_INTERFACE(css::frame::XDispatchRecorderSupplier))

DEFINE_XTYPEPROVIDER_3(
    DispatchRecorderSupplier,
    css::lang::XTypeProvider,
    css::lang::XServiceInfo,
    css::frame::XDispatchRecorderSupplier)

DEFINE_XSERVICEINFO_MULTISERVICE(
    DispatchRecorderSupplier,
    ::cppu::OWeakObject,
    SERVICENAME_DISPATCHRECORDERSUPPLIER,
    IMPLEMENTATIONNAME_DISPATCHRECORDERSUPPLIER)

DEFINE_INIT_SERVICE(
    DispatchRecorderSupplier,
    {
        /*Attention
            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
            to create a new instance of this class by our own supported service factory.
            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
        */
    }
)

//_____________________________________________________________________________
/**
    @short  standard constructor to create instance
    @descr  Because an instance will be initialized by her interface methods
            it's not neccessary to do anything here.
 */
DispatchRecorderSupplier::DispatchRecorderSupplier( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
        //  init baseclasses first!
        //  Attention: Don't change order of initialization!
        : ThreadHelpBase     ( &Application::GetSolarMutex() )
        , ::cppu::OWeakObject(                               )
        //  init member
        , m_xFactory         ( xFactory                      )
        , m_xDispatchRecorder( NULL                          )
{
}

//_____________________________________________________________________________
/**
    @short  standard destructor
    @descr  We are a helper and not a real service. So we doesn't provide
            dispose() functionality. This supplier dies by ref count mechanism
            and should release all internal used ones too.
 */
DispatchRecorderSupplier::~DispatchRecorderSupplier()
{
    m_xFactory          = NULL;
    m_xDispatchRecorder = NULL;
}

//_____________________________________________________________________________
/**
    @short      set a new dispatch recorder on this supplier
    @descr      Because there can exist more then one recorder implementations
                (to generate java/basic/... scripts from recorded data) it must
                be possible to set it on a supplier.

    @see        getDispatchRecorder()

    @param      xRecorder
                the new recorder to set it

<NULL/> isn't recommended, because recording without a
                valid recorder can't work. But it's not checked here. So user
                of this supplier can decide that without changing this
                implementation.

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::setDispatchRecorder( const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    WriteGuard aWriteLock(m_aLock);
    m_xDispatchRecorder=xRecorder;
    // => SAFE
}
//_____________________________________________________________________________
/**
    @short      provides access to the dispatch recorder of this supplier
    @descr      Such recorder can be used outside to record dispatches.
                But normaly he is used internaly only. Of course he must used
                from outside to get the recorded data e.g. for saving it as a
                script.

    @see        setDispatchRecorder()

    @return     the internal used dispatch recorder

May it can be <NULL/> if no one was set before.

    @change     09.04.2002 by Andreas Schluens
 */
css::uno::Reference< css::frame::XDispatchRecorder > SAL_CALL DispatchRecorderSupplier::getDispatchRecorder() throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    return m_xDispatchRecorder;
    // => SAFE
}

//_____________________________________________________________________________
/**
    @short      execute a dispatch request and record it
    @descr      If given dispatch object provides right recording interface it
                will be used. If it's not supported it record the pure dispatch
                parameters only. There is no code neither the possibility to
                check if recording is enabled or not.

    @param      aURL            the command URL
    @param      lArguments      optional arguments (see com.sun.star.document.MediaDescriptor for further informations)
    @param      xDispatcher     the original dispatch object which should be recorded

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::dispatchAndRecord( const css::util::URL&                                  aURL        ,
                                                           const css::uno::Sequence< css::beans::PropertyValue >& lArguments  ,
                                                           const css::uno::Reference< css::frame::XDispatch >&    xDispatcher ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::frame::XDispatchRecorder > xRecorder = m_xDispatchRecorder;
    aReadLock.unlock();
    // => SAFE

    // clear unspecific situations
    if (!xDispatcher.is())
        throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: dispatcher is NULL"), static_cast< ::cppu::OWeakObject* >(this));

    if (!xRecorder.is())
        throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: no valid dispatch recorder available"), static_cast< ::cppu::OWeakObject* >(this));

    // check, if given dispatch supports record functionality by itself ...
    // or must be wrapped.
    css::uno::Reference< css::frame::XRecordableDispatch > xRecordable(
        xDispatcher,
        css::uno::UNO_QUERY);

    if (xRecordable.is())
        xRecordable->dispatchAndRecord(aURL,lArguments,xRecorder);
    else
    {
        // There is no reason to wait for information about success
        // of this request. Because status information of a dispatch
        // are not guaranteed. So we execute it and record used
        // parameters only.
        xDispatcher->dispatch(aURL,lArguments);
        xRecorder->recordDispatch(aURL,lArguments);
    }
}

}   // namespace framework
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dispatchrecordersupplier.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 14:06:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

//_________________________________________________________________________________________________________________
// include own things

#ifndef __FRAMEWORK_RECORDING_DISPATCHRECORDERSUPPLIER_HXX_
#include <recording/dispatchrecordersupplier.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
// include interfaces

#ifndef _COM_SUN_STAR_FRAME_XRECORDABLEDISPATCH_HPP_
#include <com/sun/star/frame/XRecordableDispatch.hpp>
#endif

//_________________________________________________________________________________________________________________
// include other projects

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

//_________________________________________________________________________________________________________________
// namespace

namespace framework{

//_________________________________________________________________________________________________________________
// non exported const

//_________________________________________________________________________________________________________________
// non exported definitions

//_________________________________________________________________________________________________________________
// declarations

//*****************************************************************************************************************
//  XInterface, XTypeProvider
//*****************************************************************************************************************
DEFINE_XINTERFACE_3(
    DispatchRecorderSupplier,
    OWeakObject,
    DIRECT_INTERFACE(css::lang::XTypeProvider),
    DIRECT_INTERFACE(css::lang::XServiceInfo),
    DIRECT_INTERFACE(css::frame::XDispatchRecorderSupplier))

DEFINE_XTYPEPROVIDER_3(
    DispatchRecorderSupplier,
    css::lang::XTypeProvider,
    css::lang::XServiceInfo,
    css::frame::XDispatchRecorderSupplier)

DEFINE_XSERVICEINFO_MULTISERVICE(
    DispatchRecorderSupplier,
    ::cppu::OWeakObject,
    SERVICENAME_DISPATCHRECORDERSUPPLIER,
    IMPLEMENTATIONNAME_DISPATCHRECORDERSUPPLIER)

DEFINE_INIT_SERVICE(
    DispatchRecorderSupplier,
    {
        /*Attention
            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
            to create a new instance of this class by our own supported service factory.
            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
        */
    }
)

//_____________________________________________________________________________
/**
    @short  standard constructor to create instance
    @descr  Because an instance will be initialized by her interface methods
            it's not neccessary to do anything here.
 */
DispatchRecorderSupplier::DispatchRecorderSupplier( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
        //  init baseclasses first!
        //  Attention: Don't change order of initialization!
        : ThreadHelpBase     ( &Application::GetSolarMutex() )
        , ::cppu::OWeakObject(                               )
        //  init member
        , m_xDispatchRecorder( NULL                          )
        , m_xFactory         ( xFactory                      )
{
}

//_____________________________________________________________________________
/**
    @short  standard destructor
    @descr  We are a helper and not a real service. So we doesn't provide
            dispose() functionality. This supplier dies by ref count mechanism
            and should release all internal used ones too.
 */
DispatchRecorderSupplier::~DispatchRecorderSupplier()
{
    m_xFactory          = NULL;
    m_xDispatchRecorder = NULL;
}

//_____________________________________________________________________________
/**
    @short      set a new dispatch recorder on this supplier
    @descr      Because there can exist more then one recorder implementations
                (to generate java/basic/... scripts from recorded data) it must
                be possible to set it on a supplier.

    @see        getDispatchRecorder()

    @param      xRecorder
                the new recorder to set it

<NULL/> isn't recommended, because recording without a
                valid recorder can't work. But it's not checked here. So user
                of this supplier can decide that without changing this
                implementation.

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::setDispatchRecorder( const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    WriteGuard aWriteLock(m_aLock);
    m_xDispatchRecorder=xRecorder;
    // => SAFE
}
//_____________________________________________________________________________
/**
    @short      provides access to the dispatch recorder of this supplier
    @descr      Such recorder can be used outside to record dispatches.
                But normaly he is used internaly only. Of course he must used
                from outside to get the recorded data e.g. for saving it as a
                script.

    @see        setDispatchRecorder()

    @return     the internal used dispatch recorder

May it can be <NULL/> if no one was set before.

    @change     09.04.2002 by Andreas Schluens
 */
css::uno::Reference< css::frame::XDispatchRecorder > SAL_CALL DispatchRecorderSupplier::getDispatchRecorder() throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    return m_xDispatchRecorder;
    // => SAFE
}

//_____________________________________________________________________________
/**
    @short      execute a dispatch request and record it
    @descr      If given dispatch object provides right recording interface it
                will be used. If it's not supported it record the pure dispatch
                parameters only. There is no code neither the possibility to
                check if recording is enabled or not.

    @param      aURL            the command URL
    @param      lArguments      optional arguments (see com.sun.star.document.MediaDescriptor for further informations)
    @param      xDispatcher     the original dispatch object which should be recorded

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::dispatchAndRecord( const css::util::URL&                                  aURL        ,
                                                           const css::uno::Sequence< css::beans::PropertyValue >& lArguments  ,
                                                           const css::uno::Reference< css::frame::XDispatch >&    xDispatcher ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::frame::XDispatchRecorder > xRecorder = m_xDispatchRecorder;
    aReadLock.unlock();
    // => SAFE

    // clear unspecific situations
    if (!xDispatcher.is())
        throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: dispatcher is NULL"), static_cast< ::cppu::OWeakObject* >(this));

    if (!xRecorder.is())
        throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: no valid dispatch recorder available"), static_cast< ::cppu::OWeakObject* >(this));

    // check, if given dispatch supports record functionality by itself ...
    // or must be wrapped.
    css::uno::Reference< css::frame::XRecordableDispatch > xRecordable(
        xDispatcher,
        css::uno::UNO_QUERY);

    if (xRecordable.is())
        xRecordable->dispatchAndRecord(aURL,lArguments,xRecorder);
    else
    {
        // There is no reason to wait for information about success
        // of this request. Because status information of a dispatch
        // are not guaranteed. So we execute it and record used
        // parameters only.
        xDispatcher->dispatch(aURL,lArguments);
        xRecorder->recordDispatch(aURL,lArguments);
    }
}

}   // namespace framework
<commit_msg>INTEGRATION: CWS changefileheader (1.5.262); FILE MERGED 2008/04/01 15:18:44 thb 1.5.262.3: #i85898# Stripping all external header guards 2008/04/01 10:58:11 thb 1.5.262.2: #i85898# Stripping all external header guards 2008/03/28 15:35:24 rt 1.5.262.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: dispatchrecordersupplier.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

//_________________________________________________________________________________________________________________
// include own things
#include <recording/dispatchrecordersupplier.hxx>
#include <threadhelp/writeguard.hxx>
#include <threadhelp/readguard.hxx>
#include <services.h>

//_________________________________________________________________________________________________________________
// include interfaces
#include <com/sun/star/frame/XRecordableDispatch.hpp>

//_________________________________________________________________________________________________________________
// include other projects
#include <vcl/svapp.hxx>

//_________________________________________________________________________________________________________________
// namespace

namespace framework{

//_________________________________________________________________________________________________________________
// non exported const

//_________________________________________________________________________________________________________________
// non exported definitions

//_________________________________________________________________________________________________________________
// declarations

//*****************************************************************************************************************
//  XInterface, XTypeProvider
//*****************************************************************************************************************
DEFINE_XINTERFACE_3(
    DispatchRecorderSupplier,
    OWeakObject,
    DIRECT_INTERFACE(css::lang::XTypeProvider),
    DIRECT_INTERFACE(css::lang::XServiceInfo),
    DIRECT_INTERFACE(css::frame::XDispatchRecorderSupplier))

DEFINE_XTYPEPROVIDER_3(
    DispatchRecorderSupplier,
    css::lang::XTypeProvider,
    css::lang::XServiceInfo,
    css::frame::XDispatchRecorderSupplier)

DEFINE_XSERVICEINFO_MULTISERVICE(
    DispatchRecorderSupplier,
    ::cppu::OWeakObject,
    SERVICENAME_DISPATCHRECORDERSUPPLIER,
    IMPLEMENTATIONNAME_DISPATCHRECORDERSUPPLIER)

DEFINE_INIT_SERVICE(
    DispatchRecorderSupplier,
    {
        /*Attention
            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
            to create a new instance of this class by our own supported service factory.
            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
        */
    }
)

//_____________________________________________________________________________
/**
    @short  standard constructor to create instance
    @descr  Because an instance will be initialized by her interface methods
            it's not neccessary to do anything here.
 */
DispatchRecorderSupplier::DispatchRecorderSupplier( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
        //  init baseclasses first!
        //  Attention: Don't change order of initialization!
        : ThreadHelpBase     ( &Application::GetSolarMutex() )
        , ::cppu::OWeakObject(                               )
        //  init member
        , m_xDispatchRecorder( NULL                          )
        , m_xFactory         ( xFactory                      )
{
}

//_____________________________________________________________________________
/**
    @short  standard destructor
    @descr  We are a helper and not a real service. So we doesn't provide
            dispose() functionality. This supplier dies by ref count mechanism
            and should release all internal used ones too.
 */
DispatchRecorderSupplier::~DispatchRecorderSupplier()
{
    m_xFactory          = NULL;
    m_xDispatchRecorder = NULL;
}

//_____________________________________________________________________________
/**
    @short      set a new dispatch recorder on this supplier
    @descr      Because there can exist more then one recorder implementations
                (to generate java/basic/... scripts from recorded data) it must
                be possible to set it on a supplier.

    @see        getDispatchRecorder()

    @param      xRecorder
                the new recorder to set it

<NULL/> isn't recommended, because recording without a
                valid recorder can't work. But it's not checked here. So user
                of this supplier can decide that without changing this
                implementation.

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::setDispatchRecorder( const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    WriteGuard aWriteLock(m_aLock);
    m_xDispatchRecorder=xRecorder;
    // => SAFE
}
//_____________________________________________________________________________
/**
    @short      provides access to the dispatch recorder of this supplier
    @descr      Such recorder can be used outside to record dispatches.
                But normaly he is used internaly only. Of course he must used
                from outside to get the recorded data e.g. for saving it as a
                script.

    @see        setDispatchRecorder()

    @return     the internal used dispatch recorder

May it can be <NULL/> if no one was set before.

    @change     09.04.2002 by Andreas Schluens
 */
css::uno::Reference< css::frame::XDispatchRecorder > SAL_CALL DispatchRecorderSupplier::getDispatchRecorder() throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    return m_xDispatchRecorder;
    // => SAFE
}

//_____________________________________________________________________________
/**
    @short      execute a dispatch request and record it
    @descr      If given dispatch object provides right recording interface it
                will be used. If it's not supported it record the pure dispatch
                parameters only. There is no code neither the possibility to
                check if recording is enabled or not.

    @param      aURL            the command URL
    @param      lArguments      optional arguments (see com.sun.star.document.MediaDescriptor for further informations)
    @param      xDispatcher     the original dispatch object which should be recorded

    @change     09.04.2002 by Andreas Schluens
 */
void SAL_CALL DispatchRecorderSupplier::dispatchAndRecord( const css::util::URL&                                  aURL        ,
                                                           const css::uno::Sequence< css::beans::PropertyValue >& lArguments  ,
                                                           const css::uno::Reference< css::frame::XDispatch >&    xDispatcher ) throw (css::uno::RuntimeException)
{
    // SAFE =>
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::frame::XDispatchRecorder > xRecorder = m_xDispatchRecorder;
    aReadLock.unlock();
    // => SAFE

    // clear unspecific situations
    if (!xDispatcher.is())
        throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: dispatcher is NULL"), static_cast< ::cppu::OWeakObject* >(this));

    if (!xRecorder.is())
        throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: no valid dispatch recorder available"), static_cast< ::cppu::OWeakObject* >(this));

    // check, if given dispatch supports record functionality by itself ...
    // or must be wrapped.
    css::uno::Reference< css::frame::XRecordableDispatch > xRecordable(
        xDispatcher,
        css::uno::UNO_QUERY);

    if (xRecordable.is())
        xRecordable->dispatchAndRecord(aURL,lArguments,xRecorder);
    else
    {
        // There is no reason to wait for information about success
        // of this request. Because status information of a dispatch
        // are not guaranteed. So we execute it and record used
        // parameters only.
        xDispatcher->dispatch(aURL,lArguments);
        xRecorder->recordDispatch(aURL,lArguments);
    }
}

}   // namespace framework
<|endoftext|>


<commit_before><?hh // strict

/**
 * This file is part of hhpack\process package.
 *
 * (c) Noritaka Horio <holy.shared.design@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace hhpack\process;

final class NullPipeManager implements PipeManager
{

    public function read() : void
    {
    }

    public function close() : void
    {
    }

    public function getOutputResult() : OutputResult
    {
        return OutputResult::emptyResult();
    }

}
<commit_msg>Remove old classes<commit_after><|endoftext|>


<commit_before>/***********************************************************************

Copyright (c) 2014, Carnegie Mellon University
All rights reserved.

Authors: Michael Koval <mkoval@cs.cmu.edu>

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

  Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*************************************************************************/
#include <boost/make_shared.hpp>
#include <ompl/base/ScopedState.h>
#include <ompl/util/Time.h>
#include "OMPLConversions.h"
#include "OMPLSimplifer.h"

namespace or_ompl
{

OMPLSimplifier::OMPLSimplifier(OpenRAVE::EnvironmentBasePtr env)
    : OpenRAVE::PlannerBase(env)
{
}

OMPLSimplifier::~OMPLSimplifier()
{
}

bool OMPLSimplifier::InitPlan(OpenRAVE::RobotBasePtr robot,
                              PlannerParametersConstPtr params_raw)
{
    if (!robot) {
        RAVELOG_ERROR("Robot must not be NULL.\n");
        return false;
    } else if (!params_raw) {
        RAVELOG_ERROR("Parameters must not be NULL.\n");
        return false;
    }

    m_robot = robot;
    m_cspec = m_robot->GetActiveConfigurationSpecification();

    m_parameters = boost::make_shared<OMPLPlannerParameters>();
    m_parameters->copy(params_raw);

    try {
        using ompl::base::SpaceInformation;
        using ompl::geometric::PathSimplifier;

        m_state_space = CreateStateSpace(robot, *m_parameters);
        m_space_info = boost::make_shared<SpaceInformation>(m_state_space);
        m_space_info->setStateValidityChecker(
                boost::bind(&OMPLSimplifier::IsStateValid, this, _1));
        m_space_info->setup();
        m_simplifier = boost::make_shared<PathSimplifier>(m_space_info);
        return true;
    } catch (std::runtime_error const &e) {
        RAVELOG_ERROR("IntPlan failed: %s\n", e.what());
        return false;
    }
}

bool OMPLSimplifier::InitPlan(OpenRAVE::RobotBasePtr robot, std::istream &input)
{
    OMPLPlannerParametersPtr params = boost::make_shared<OMPLPlannerParameters>();
    input >> *params;
    return InitPlan(robot, params);
}

OpenRAVE::PlannerStatus OMPLSimplifier::PlanPath(OpenRAVE::TrajectoryBasePtr ptraj)
{
    typedef ompl::base::RealVectorStateSpace::StateType StateType;
    typedef ompl::base::ScopedState<ompl::base::RealVectorStateSpace> ScopedState;

    if (!m_simplifier) {
        RAVELOG_ERROR("Not initialized. Did you call InitPlan?\n");
        return OpenRAVE::PS_Failed;
    } else if (!ptraj) {
        RAVELOG_ERROR("Input trajectory is NULL.\n");
        return OpenRAVE::PS_Failed;
    } else if (m_parameters->m_timeLimit <= 0) {
        RAVELOG_ERROR("Time limit must be positive; got %f.",
                      m_parameters->m_timeLimit);
        return OpenRAVE::PS_Failed;
    } else if (ptraj->GetNumWaypoints() == 0) {
        RAVELOG_WARN("Input trajectory is empty; there is nothing to do.\n");
        return OpenRAVE::PS_HasSolution;
    }

    // Convert the OpenRAVE trajectory into an OMPL path.
    BOOST_ASSERT(m_space_info);
    ompl::geometric::PathGeometric path(m_space_info);
    size_t const num_dof = m_cspec.GetDOF();

    RAVELOG_DEBUG("Create OMPL path with %d DOF and %d waypoints.\n",
                  num_dof, ptraj->GetNumWaypoints());

    for (size_t iwaypoint = 0; iwaypoint < ptraj->GetNumWaypoints(); ++iwaypoint) {
        // Extract the OpenRAVE waypoint. Default to the current configuration
        // for any missing DOFs.
        std::vector<OpenRAVE::dReal> waypoint_openrave;
        m_robot->GetActiveDOFValues(waypoint_openrave);
        ptraj->GetWaypoint(iwaypoint, waypoint_openrave, m_cspec);

        // Insert the waypoint into the OMPL path.
        ScopedState waypoint_ompl(m_space_info);
        for (size_t idof = 0; idof < num_dof; ++idof) {
            waypoint_ompl[idof] = waypoint_openrave[idof];
        }
        path.append(waypoint_ompl.get());
    }

    // Run path simplification.
    double const length_before = path.length();
    int num_iterations = 0;
    int num_changes = 0;

    ompl::time::duration const time_limit
        = ompl::time::seconds(m_parameters->m_timeLimit);
    ompl::time::point const time_before = ompl::time::now();
    ompl::time::point time_current;

    RAVELOG_DEBUG("Running path simplification for %f seconds.\n",
                  m_parameters->m_timeLimit);

    do {
        bool const is_change = m_simplifier->shortcutPath(path, 1, 1, 1.0, 0.005);

        time_current = ompl::time::now();
        num_iterations += 1;
        num_changes += !!is_change;
    } while (time_current - time_before <= time_limit);

    double const length_after = path.length();

    RAVELOG_DEBUG(
        "Ran %d iterations of smoothing over %.3f seconds. %d of %d iterations"
        " (%.2f%%) were effective. Reduced path length from %.3f to %.3f.\n",
        num_iterations,
        ompl::time::seconds(time_current - time_before),
        num_changes,
        num_iterations,
        100 * static_cast<double>(num_changes) / num_iterations,
        length_before, length_after
    );

    // Store the result in the OpenRAVE trajectory.
    RAVELOG_DEBUG("Reconstructing OpenRAVE trajectory with %d waypoints.\n",
                  path.getStateCount());
    BOOST_ASSERT(ptraj);
    ptraj->Remove(0, ptraj->GetNumWaypoints());

    for (size_t iwaypoint = 0; iwaypoint < path.getStateCount(); ++iwaypoint) {
        ompl::base::State const *waypoint_generic = path.getState(iwaypoint);
        StateType const &waypoint_ompl = *waypoint_generic->as<StateType>();

        std::vector<OpenRAVE::dReal> waypoint_openrave(num_dof);
        for (size_t idof = 0; idof < num_dof; ++idof) {
            waypoint_openrave[idof] = waypoint_ompl[idof];
        }
        ptraj->Insert(iwaypoint, waypoint_openrave, m_cspec);
    }
    return OpenRAVE::PS_HasSolution;
}

bool OMPLSimplifier::IsInOrCollision(std::vector<double> const &values)
{
    m_robot->SetActiveDOFValues(values, OpenRAVE::KinBody::CLA_Nothing);
    return GetEnv()->CheckCollision(m_robot) || m_robot->CheckSelfCollision();
}

bool OMPLSimplifier::IsStateValid(ompl::base::State const *state)
{
    typedef ompl::base::RealVectorStateSpace::StateType StateType;
    StateType const *realVectorState = state->as<StateType>();
    size_t const num_dof = m_robot->GetActiveDOF();

    if (realVectorState) {
        std::vector<OpenRAVE::dReal> values(num_dof);
        for (size_t i = 0; i < num_dof; i++) {
            values[i] = realVectorState->values[i];
        }
        return !IsInOrCollision(values);
    } else {
        RAVELOG_ERROR("Invalid StateType. This should never happen.\n");
        return false;
    }
}

}
<commit_msg>Commented the shortcutPath arguments.<commit_after>/***********************************************************************

Copyright (c) 2014, Carnegie Mellon University
All rights reserved.

Authors: Michael Koval <mkoval@cs.cmu.edu>

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

  Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*************************************************************************/
#include <boost/make_shared.hpp>
#include <ompl/base/ScopedState.h>
#include <ompl/util/Time.h>
#include "OMPLConversions.h"
#include "OMPLSimplifer.h"

namespace or_ompl
{

OMPLSimplifier::OMPLSimplifier(OpenRAVE::EnvironmentBasePtr env)
    : OpenRAVE::PlannerBase(env)
{
}

OMPLSimplifier::~OMPLSimplifier()
{
}

bool OMPLSimplifier::InitPlan(OpenRAVE::RobotBasePtr robot,
                              PlannerParametersConstPtr params_raw)
{
    if (!robot) {
        RAVELOG_ERROR("Robot must not be NULL.\n");
        return false;
    } else if (!params_raw) {
        RAVELOG_ERROR("Parameters must not be NULL.\n");
        return false;
    }

    m_robot = robot;
    m_cspec = m_robot->GetActiveConfigurationSpecification();

    m_parameters = boost::make_shared<OMPLPlannerParameters>();
    m_parameters->copy(params_raw);

    try {
        using ompl::base::SpaceInformation;
        using ompl::geometric::PathSimplifier;

        m_state_space = CreateStateSpace(robot, *m_parameters);
        m_space_info = boost::make_shared<SpaceInformation>(m_state_space);
        m_space_info->setStateValidityChecker(
                boost::bind(&OMPLSimplifier::IsStateValid, this, _1));
        m_space_info->setup();
        m_simplifier = boost::make_shared<PathSimplifier>(m_space_info);
        return true;
    } catch (std::runtime_error const &e) {
        RAVELOG_ERROR("IntPlan failed: %s\n", e.what());
        return false;
    }
}

bool OMPLSimplifier::InitPlan(OpenRAVE::RobotBasePtr robot, std::istream &input)
{
    OMPLPlannerParametersPtr params = boost::make_shared<OMPLPlannerParameters>();
    input >> *params;
    return InitPlan(robot, params);
}

OpenRAVE::PlannerStatus OMPLSimplifier::PlanPath(OpenRAVE::TrajectoryBasePtr ptraj)
{
    typedef ompl::base::RealVectorStateSpace::StateType StateType;
    typedef ompl::base::ScopedState<ompl::base::RealVectorStateSpace> ScopedState;

    if (!m_simplifier) {
        RAVELOG_ERROR("Not initialized. Did you call InitPlan?\n");
        return OpenRAVE::PS_Failed;
    } else if (!ptraj) {
        RAVELOG_ERROR("Input trajectory is NULL.\n");
        return OpenRAVE::PS_Failed;
    } else if (m_parameters->m_timeLimit <= 0) {
        RAVELOG_ERROR("Time limit must be positive; got %f.",
                      m_parameters->m_timeLimit);
        return OpenRAVE::PS_Failed;
    } else if (ptraj->GetNumWaypoints() == 0) {
        RAVELOG_WARN("Input trajectory is empty; there is nothing to do.\n");
        return OpenRAVE::PS_HasSolution;
    }

    // Convert the OpenRAVE trajectory into an OMPL path.
    BOOST_ASSERT(m_space_info);
    ompl::geometric::PathGeometric path(m_space_info);
    size_t const num_dof = m_cspec.GetDOF();

    RAVELOG_DEBUG("Create OMPL path with %d DOF and %d waypoints.\n",
                  num_dof, ptraj->GetNumWaypoints());

    for (size_t iwaypoint = 0; iwaypoint < ptraj->GetNumWaypoints(); ++iwaypoint) {
        // Extract the OpenRAVE waypoint. Default to the current configuration
        // for any missing DOFs.
        std::vector<OpenRAVE::dReal> waypoint_openrave;
        m_robot->GetActiveDOFValues(waypoint_openrave);
        ptraj->GetWaypoint(iwaypoint, waypoint_openrave, m_cspec);

        // Insert the waypoint into the OMPL path.
        ScopedState waypoint_ompl(m_space_info);
        for (size_t idof = 0; idof < num_dof; ++idof) {
            waypoint_ompl[idof] = waypoint_openrave[idof];
        }
        path.append(waypoint_ompl.get());
    }

    // Run path simplification.
    double const length_before = path.length();
    int num_iterations = 0;
    int num_changes = 0;

    ompl::time::duration const time_limit
        = ompl::time::seconds(m_parameters->m_timeLimit);
    ompl::time::point const time_before = ompl::time::now();
    ompl::time::point time_current;

    RAVELOG_DEBUG("Running path simplification for %f seconds.\n",
                  m_parameters->m_timeLimit);

    do {
        // Run one iteration of shortcutting. This gives us fine control over
        // the termination condition and allows us to invoke the planner
        // callbacks between iterations.
        //
        // The numeric arguments are the following:
        // - maxSteps: maximum number of iterations
        // - maxEmptySteps: maximum number of iterations without improvement
        // - rangeRatio: maximum connection distance attempted, specified as a
        //               ratio of the total number of states
        // - snapToVertex: ratio of total path length used to snap samples to
        //                 vertices
        bool const changed = m_simplifier->shortcutPath(path, 1, 1, 1.0, 0.005);

        time_current = ompl::time::now();
        num_iterations += 1;
        num_changes += !!changed;
    } while (time_current - time_before <= time_limit);

    double const length_after = path.length();

    RAVELOG_DEBUG(
        "Ran %d iterations of smoothing over %.3f seconds. %d of %d iterations"
        " (%.2f%%) were effective. Reduced path length from %.3f to %.3f.\n",
        num_iterations,
        ompl::time::seconds(time_current - time_before),
        num_changes,
        num_iterations,
        100 * static_cast<double>(num_changes) / num_iterations,
        length_before, length_after
    );

    // Store the result in the OpenRAVE trajectory.
    RAVELOG_DEBUG("Reconstructing OpenRAVE trajectory with %d waypoints.\n",
                  path.getStateCount());
    BOOST_ASSERT(ptraj);
    ptraj->Remove(0, ptraj->GetNumWaypoints());

    for (size_t iwaypoint = 0; iwaypoint < path.getStateCount(); ++iwaypoint) {
        ompl::base::State const *waypoint_generic = path.getState(iwaypoint);
        StateType const &waypoint_ompl = *waypoint_generic->as<StateType>();

        std::vector<OpenRAVE::dReal> waypoint_openrave(num_dof);
        for (size_t idof = 0; idof < num_dof; ++idof) {
            waypoint_openrave[idof] = waypoint_ompl[idof];
        }
        ptraj->Insert(iwaypoint, waypoint_openrave, m_cspec);
    }
    return OpenRAVE::PS_HasSolution;
}

bool OMPLSimplifier::IsInOrCollision(std::vector<double> const &values)
{
    m_robot->SetActiveDOFValues(values, OpenRAVE::KinBody::CLA_Nothing);
    return GetEnv()->CheckCollision(m_robot) || m_robot->CheckSelfCollision();
}

bool OMPLSimplifier::IsStateValid(ompl::base::State const *state)
{
    typedef ompl::base::RealVectorStateSpace::StateType StateType;
    StateType const *realVectorState = state->as<StateType>();
    size_t const num_dof = m_robot->GetActiveDOF();

    if (realVectorState) {
        std::vector<OpenRAVE::dReal> values(num_dof);
        for (size_t i = 0; i < num_dof; i++) {
            values[i] = realVectorState->values[i];
        }
        return !IsInOrCollision(values);
    } else {
        RAVELOG_ERROR("Invalid StateType. This should never happen.\n");
        return false;
    }
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "app/l10n_util.h"
#include "base/sys_info.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/app_modal_dialog.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"

const std::string BEFORE_UNLOAD_HTML =
    "<title>beforeunload</title>"
    ""
    "";

const std::wstring OPEN_NEW_BEFOREUNLOAD_PAGE =
    L"w=window.open(); w.onbeforeunload=function(e){return 'foo'};";

namespace {

// Given a page title, returns the expected window caption string.
std::wstring WindowCaptionFromPageTitle(std::wstring page_title) {
#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
  // On Mac or ChromeOS, we don't want to suffix the page title with
  // the application name.
  if (page_title.empty())
    return l10n_util::GetString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED);
  return page_title;
#elif defined(OS_WIN) || defined(OS_LINUX)
  if (page_title.empty())
    return l10n_util::GetString(IDS_PRODUCT_NAME);

  return l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT, page_title);
#endif
}

// Returns the number of active RenderProcessHosts.
int CountRenderProcessHosts() {
  int result = 0;
  for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
       !i.IsAtEnd(); i.Advance())
    ++result;
  return result;
}

}  // namespace

class BrowserTest : public InProcessBrowserTest {
 protected:
  // In RTL locales wrap the page title with RTL embedding characters so that it
  // matches the value returned by GetWindowTitle().
  std::wstring LocaleWindowCaptionFromPageTitle(
      const std::wstring& expected_title) {
    std::wstring page_title = WindowCaptionFromPageTitle(expected_title);
#if defined(OS_WIN)
    std::string locale = g_browser_process->GetApplicationLocale();
    if (l10n_util::GetTextDirectionForLocale(locale.c_str()) ==
        l10n_util::RIGHT_TO_LEFT) {
      l10n_util::WrapStringWithLTRFormatting(&page_title);
    }

    return page_title;
#else
    // Do we need to use the above code on POSIX as well?
    return page_title;
#endif
  }
};

// Launch the app on a page with no title, check that the app title was set
// correctly.
IN_PROC_BROWSER_TEST_F(BrowserTest, NoTitle) {
  ui_test_utils::NavigateToURL(browser(),
                               ui_test_utils::GetTestUrl(L".", L"title1.html"));
  EXPECT_EQ(LocaleWindowCaptionFromPageTitle(L"title1.html"),
            UTF16ToWideHack(browser()->GetWindowTitleForCurrentTab()));
  string16 tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title);
}

// Launch the app, navigate to a page with a title, check that the app title
// was set correctly.
IN_PROC_BROWSER_TEST_F(BrowserTest, Title) {
  ui_test_utils::NavigateToURL(browser(),
                               ui_test_utils::GetTestUrl(L".", L"title2.html"));
  const std::wstring test_title(L"Title Of Awesomeness");
  EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title),
            UTF16ToWideHack(browser()->GetWindowTitleForCurrentTab()));
  string16 tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(WideToUTF16(test_title), tab_title);
}

#if !defined(OS_MACOSX)
// TODO(port): BUG16322
IN_PROC_BROWSER_TEST_F(BrowserTest, JavascriptAlertActivatesTab) {
  GURL url(ui_test_utils::GetTestUrl(L".", L"title1.html"));
  ui_test_utils::NavigateToURL(browser(), url);
  browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED,
                           true, 0, false, NULL);
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  TabContents* second_tab = browser()->GetTabContentsAt(1);
  ASSERT_TRUE(second_tab);
  second_tab->render_view_host()->ExecuteJavascriptInWebFrame(L"",
      L"alert('Activate!');");
  AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  alert->CloseModalDialog();
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());
}
#endif  // !defined(OS_MACOSX)

// Create 34 tabs and verify that a lot of processes have been created. The
// exact number of processes depends on the amount of memory. Previously we
// had a hard limit of 31 processes and this test is mainly directed at
// verifying that we don't crash when we pass this limit.
IN_PROC_BROWSER_TEST_F(BrowserTest, ThirtyFourTabs) {
  GURL url(ui_test_utils::GetTestUrl(L".", L"title2.html"));

  // There is one initial tab.
  for (int ix = 0; ix != 33; ++ix) {
    browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED,
                             true, 0, false, NULL);
  }
  EXPECT_EQ(34, browser()->tab_count());

  // See browser\renderer_host\render_process_host.cc for the algorithm to
  // decide how many processes to create.
  if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) {
    EXPECT_GE(CountRenderProcessHosts(), 24);
  } else {
    EXPECT_LE(CountRenderProcessHosts(), 23);
  }
}

// Test for crbug.com/22004.  Reloading a page with a before unload handler and
// then canceling the dialog should not leave the throbber spinning.
#if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ReloadThenCancelBeforeUnload) {
#else
IN_PROC_BROWSER_TEST_F(BrowserTest, ReloadThenCancelBeforeUnload) {
#endif
  GURL url("data:text/html," + BEFORE_UNLOAD_HTML);
  ui_test_utils::NavigateToURL(browser(), url);

  // Navigate to another page, but click cancel in the dialog.  Make sure that
  // the throbber stops spinning.
  browser()->Reload();
  AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  alert->CloseModalDialog();
  EXPECT_FALSE(browser()->GetSelectedTabContents()->is_loading());

  // Clear the beforeunload handler so the test can easily exit.
  browser()->GetSelectedTabContents()->render_view_host()->
      ExecuteJavascriptInWebFrame(L"", L"onbeforeunload=null;");
}

// Test for crbug.com/11647.  A page closed with window.close() should not have
// two beforeunload dialogs shown.
#if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(BrowserTest,
                       DISABLED_SingleBeforeUnloadAfterWindowClose) {
#else
IN_PROC_BROWSER_TEST_F(BrowserTest, FLAKY_SingleBeforeUnloadAfterWindowClose) {
#endif
  browser()->GetSelectedTabContents()->render_view_host()->
      ExecuteJavascriptInWebFrame(L"", OPEN_NEW_BEFOREUNLOAD_PAGE);

  // Close the new window with JavaScript, which should show a single
  // beforeunload dialog.  Then show another alert, to make it easy to verify
  // that a second beforeunload dialog isn't shown.
  browser()->GetTabContentsAt(0)->render_view_host()->
      ExecuteJavascriptInWebFrame(L"", L"w.close(); alert('bar');");
  AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  alert->AcceptWindow();

  alert = ui_test_utils::WaitForAppModalDialog();
  EXPECT_FALSE(alert->is_before_unload_dialog());
  alert->AcceptWindow();
}

// Test that get_process_idle_time() returns reasonable values when compared
// with time deltas measured locally.
IN_PROC_BROWSER_TEST_F(BrowserTest, RenderIdleTime) {
  base::TimeTicks start = base::TimeTicks::Now();
  ui_test_utils::NavigateToURL(browser(),
                               ui_test_utils::GetTestUrl(L".", L"title1.html"));
  RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
  for (; !it.IsAtEnd(); it.Advance()) {
    base::TimeDelta renderer_td =
        it.GetCurrentValue()->get_child_process_idle_time();
    base::TimeDelta browser_td = base::TimeTicks::Now() - start;
    EXPECT_TRUE(browser_td >= renderer_td);
  }
}

// Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http
// and https and disabled for chrome://, about:// etc.
#if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(BrowserTest,
                       DISABLED_CommandCreateAppShortcut) {
#else
IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcut) {
#endif
  static const wchar_t kDocRoot[] = L"chrome/test/data";

  CommandUpdater* command_updater = browser()->command_updater();

  // Urls that are okay to have shortcuts.
  GURL file_url(ui_test_utils::GetTestUrl(L".", L"empty.html"));
  ASSERT_TRUE(file_url.SchemeIs(chrome::kFileScheme));
  ui_test_utils::NavigateToURL(browser(), file_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  scoped_refptr<FTPTestServer> ftp_server(
        FTPTestServer::CreateServer(kDocRoot));
  ASSERT_TRUE(NULL != ftp_server.get());
  GURL ftp_url(ftp_server->TestServerPage(""));
  ASSERT_TRUE(ftp_url.SchemeIs(chrome::kFtpScheme));
  ui_test_utils::NavigateToURL(browser(), ftp_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  scoped_refptr<HTTPTestServer> http_server(
        HTTPTestServer::CreateServer(kDocRoot, NULL));
  ASSERT_TRUE(NULL != http_server.get());
  GURL http_url(http_server->TestServerPage(""));
  ASSERT_TRUE(http_url.SchemeIs(chrome::kHttpScheme));
  ui_test_utils::NavigateToURL(browser(), http_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  scoped_refptr<HTTPSTestServer> https_server(
        HTTPSTestServer::CreateGoodServer(kDocRoot));
  ASSERT_TRUE(NULL != https_server.get());
  GURL https_url(https_server->TestServerPage("/"));
  ASSERT_TRUE(https_url.SchemeIs(chrome::kHttpsScheme));
  ui_test_utils::NavigateToURL(browser(), https_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  // Urls that should not have shortcuts.
  GURL new_tab_url(chrome::kChromeUINewTabURL);
  ui_test_utils::NavigateToURL(browser(), new_tab_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  GURL history_url(chrome::kChromeUIHistoryURL);
  ui_test_utils::NavigateToURL(browser(), history_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  GURL downloads_url(chrome::kChromeUIDownloadsURL);
  ui_test_utils::NavigateToURL(browser(), downloads_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  GURL blank_url(chrome::kAboutBlankURL);
  ui_test_utils::NavigateToURL(browser(), blank_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));
}
<commit_msg>enabled one browser test and tag JavascriptAlertActivatesTab, ReloadThenCancelBeforeUnload, & SingleBeforeUnloadAfterWindowClose as disabled so they compile but don't run on the Mac<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "app/l10n_util.h"
#include "base/sys_info.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/app_modal_dialog.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"

const std::string BEFORE_UNLOAD_HTML =
    "<title>beforeunload</title>"
    ""
    "";

const std::wstring OPEN_NEW_BEFOREUNLOAD_PAGE =
    L"w=window.open(); w.onbeforeunload=function(e){return 'foo'};";

namespace {

// Given a page title, returns the expected window caption string.
std::wstring WindowCaptionFromPageTitle(std::wstring page_title) {
#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
  // On Mac or ChromeOS, we don't want to suffix the page title with
  // the application name.
  if (page_title.empty())
    return l10n_util::GetString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED);
  return page_title;
#elif defined(OS_WIN) || defined(OS_LINUX)
  if (page_title.empty())
    return l10n_util::GetString(IDS_PRODUCT_NAME);

  return l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT, page_title);
#endif
}

// Returns the number of active RenderProcessHosts.
int CountRenderProcessHosts() {
  int result = 0;
  for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
       !i.IsAtEnd(); i.Advance())
    ++result;
  return result;
}

}  // namespace

class BrowserTest : public InProcessBrowserTest {
 protected:
  // In RTL locales wrap the page title with RTL embedding characters so that it
  // matches the value returned by GetWindowTitle().
  std::wstring LocaleWindowCaptionFromPageTitle(
      const std::wstring& expected_title) {
    std::wstring page_title = WindowCaptionFromPageTitle(expected_title);
#if defined(OS_WIN)
    std::string locale = g_browser_process->GetApplicationLocale();
    if (l10n_util::GetTextDirectionForLocale(locale.c_str()) ==
        l10n_util::RIGHT_TO_LEFT) {
      l10n_util::WrapStringWithLTRFormatting(&page_title);
    }

    return page_title;
#else
    // Do we need to use the above code on POSIX as well?
    return page_title;
#endif
  }
};

// Launch the app on a page with no title, check that the app title was set
// correctly.
IN_PROC_BROWSER_TEST_F(BrowserTest, NoTitle) {
  ui_test_utils::NavigateToURL(browser(),
                               ui_test_utils::GetTestUrl(L".", L"title1.html"));
  EXPECT_EQ(LocaleWindowCaptionFromPageTitle(L"title1.html"),
            UTF16ToWideHack(browser()->GetWindowTitleForCurrentTab()));
  string16 tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title);
}

// Launch the app, navigate to a page with a title, check that the app title
// was set correctly.
IN_PROC_BROWSER_TEST_F(BrowserTest, Title) {
  ui_test_utils::NavigateToURL(browser(),
                               ui_test_utils::GetTestUrl(L".", L"title2.html"));
  const std::wstring test_title(L"Title Of Awesomeness");
  EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title),
            UTF16ToWideHack(browser()->GetWindowTitleForCurrentTab()));
  string16 tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(WideToUTF16(test_title), tab_title);
}

#if defined(OS_MACOSX)
// http://crbug.com//29424
#define JavascriptAlertActivatesTab DISABLED_JavascriptAlertActivatesTab
#endif

IN_PROC_BROWSER_TEST_F(BrowserTest, JavascriptAlertActivatesTab) {
  GURL url(ui_test_utils::GetTestUrl(L".", L"title1.html"));
  ui_test_utils::NavigateToURL(browser(), url);
  browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED,
                           true, 0, false, NULL);
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  TabContents* second_tab = browser()->GetTabContentsAt(1);
  ASSERT_TRUE(second_tab);
  second_tab->render_view_host()->ExecuteJavascriptInWebFrame(L"",
      L"alert('Activate!');");
  AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  alert->CloseModalDialog();
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());
}

// Create 34 tabs and verify that a lot of processes have been created. The
// exact number of processes depends on the amount of memory. Previously we
// had a hard limit of 31 processes and this test is mainly directed at
// verifying that we don't crash when we pass this limit.
IN_PROC_BROWSER_TEST_F(BrowserTest, ThirtyFourTabs) {
  GURL url(ui_test_utils::GetTestUrl(L".", L"title2.html"));

  // There is one initial tab.
  for (int ix = 0; ix != 33; ++ix) {
    browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED,
                             true, 0, false, NULL);
  }
  EXPECT_EQ(34, browser()->tab_count());

  // See browser\renderer_host\render_process_host.cc for the algorithm to
  // decide how many processes to create.
  if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) {
    EXPECT_GE(CountRenderProcessHosts(), 24);
  } else {
    EXPECT_LE(CountRenderProcessHosts(), 23);
  }
}

#if defined(OS_MACOSX)
// http://crbug.com//29424
#define ReloadThenCancelBeforeUnload DISABLED_ReloadThenCancelBeforeUnload
#endif

// Test for crbug.com/22004.  Reloading a page with a before unload handler and
// then canceling the dialog should not leave the throbber spinning.
IN_PROC_BROWSER_TEST_F(BrowserTest, ReloadThenCancelBeforeUnload) {
  GURL url("data:text/html," + BEFORE_UNLOAD_HTML);
  ui_test_utils::NavigateToURL(browser(), url);

  // Navigate to another page, but click cancel in the dialog.  Make sure that
  // the throbber stops spinning.
  browser()->Reload();
  AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  alert->CloseModalDialog();
  EXPECT_FALSE(browser()->GetSelectedTabContents()->is_loading());

  // Clear the beforeunload handler so the test can easily exit.
  browser()->GetSelectedTabContents()->render_view_host()->
      ExecuteJavascriptInWebFrame(L"", L"onbeforeunload=null;");
}

#if defined(OS_MACOSX)
// http://crbug.com//29424
#define MAYBE_SingleBeforeUnloadAfterWindowClose DISABLED_SingleBeforeUnloadAfterWindowClose
#else
#define MAYBE_SingleBeforeUnloadAfterWindowClose FLAKY_SingleBeforeUnloadAfterWindowClose
#endif

// Test for crbug.com/11647.  A page closed with window.close() should not have
// two beforeunload dialogs shown.
IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_SingleBeforeUnloadAfterWindowClose) {
  browser()->GetSelectedTabContents()->render_view_host()->
      ExecuteJavascriptInWebFrame(L"", OPEN_NEW_BEFOREUNLOAD_PAGE);

  // Close the new window with JavaScript, which should show a single
  // beforeunload dialog.  Then show another alert, to make it easy to verify
  // that a second beforeunload dialog isn't shown.
  browser()->GetTabContentsAt(0)->render_view_host()->
      ExecuteJavascriptInWebFrame(L"", L"w.close(); alert('bar');");
  AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  alert->AcceptWindow();

  alert = ui_test_utils::WaitForAppModalDialog();
  EXPECT_FALSE(alert->is_before_unload_dialog());
  alert->AcceptWindow();
}

// Test that get_process_idle_time() returns reasonable values when compared
// with time deltas measured locally.
IN_PROC_BROWSER_TEST_F(BrowserTest, RenderIdleTime) {
  base::TimeTicks start = base::TimeTicks::Now();
  ui_test_utils::NavigateToURL(browser(),
                               ui_test_utils::GetTestUrl(L".", L"title1.html"));
  RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
  for (; !it.IsAtEnd(); it.Advance()) {
    base::TimeDelta renderer_td =
        it.GetCurrentValue()->get_child_process_idle_time();
    base::TimeDelta browser_td = base::TimeTicks::Now() - start;
    EXPECT_TRUE(browser_td >= renderer_td);
  }
}

// Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http
// and https and disabled for chrome://, about:// etc.
IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcut) {
  static const wchar_t kDocRoot[] = L"chrome/test/data";

  CommandUpdater* command_updater = browser()->command_updater();

  // Urls that are okay to have shortcuts.
  GURL file_url(ui_test_utils::GetTestUrl(L".", L"empty.html"));
  ASSERT_TRUE(file_url.SchemeIs(chrome::kFileScheme));
  ui_test_utils::NavigateToURL(browser(), file_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  scoped_refptr<FTPTestServer> ftp_server(
        FTPTestServer::CreateServer(kDocRoot));
  ASSERT_TRUE(NULL != ftp_server.get());
  GURL ftp_url(ftp_server->TestServerPage(""));
  ASSERT_TRUE(ftp_url.SchemeIs(chrome::kFtpScheme));
  ui_test_utils::NavigateToURL(browser(), ftp_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  scoped_refptr<HTTPTestServer> http_server(
        HTTPTestServer::CreateServer(kDocRoot, NULL));
  ASSERT_TRUE(NULL != http_server.get());
  GURL http_url(http_server->TestServerPage(""));
  ASSERT_TRUE(http_url.SchemeIs(chrome::kHttpScheme));
  ui_test_utils::NavigateToURL(browser(), http_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  scoped_refptr<HTTPSTestServer> https_server(
        HTTPSTestServer::CreateGoodServer(kDocRoot));
  ASSERT_TRUE(NULL != https_server.get());
  GURL https_url(https_server->TestServerPage("/"));
  ASSERT_TRUE(https_url.SchemeIs(chrome::kHttpsScheme));
  ui_test_utils::NavigateToURL(browser(), https_url);
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  // Urls that should not have shortcuts.
  GURL new_tab_url(chrome::kChromeUINewTabURL);
  ui_test_utils::NavigateToURL(browser(), new_tab_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  GURL history_url(chrome::kChromeUIHistoryURL);
  ui_test_utils::NavigateToURL(browser(), history_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  GURL downloads_url(chrome::kChromeUIDownloadsURL);
  ui_test_utils::NavigateToURL(browser(), downloads_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));

  GURL blank_url(chrome::kAboutBlankURL);
  ui_test_utils::NavigateToURL(browser(), blank_url);
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));
}
<|endoftext|>


<commit_before>
#pragma once

#include "base/mappable.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/linear_map.hpp"
#include "geometry/quaternion.hpp"
#include "geometry/r3_element.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "geometry/sign.hpp"
#include "serialization/geometry.pb.h"

namespace principia {
namespace geometry {

template<typename FromFrame, typename ToFrame>
class OrthogonalMap;

template<typename FromFrame, typename ToFrame>
std::ostream& operator<<(std::ostream& out,
                         Rotation<FromFrame, ToFrame> const& rotation);

// |EulerAngles| and |CardanoAngles| have values in binary-coded ternary
// representing the sequence of rotation axes.

// |AxisConvention| concatenates ternary digits.  Implementation here so it is
// defined by the time we use it as a constant expression.
constexpr int AxisConvention(int const first_axis,
                             int const second_axis,
                             int const third_axis) {
  return (((first_axis << 2) + second_axis) << 2 + third_axis);
}

constexpr int X = 0;
constexpr int Y = 1;
constexpr int Z = 2;

enum class EulerAngles {
  // |ZXZ| is The most common convention, e.g. orbital elements (Ω, i, ω),
  // rotational elements (90˚ + α₀, 90˚ - δ₀, W).
  ZXZ = AxisConvention(Z, X, Z),
  XYX = AxisConvention(X, Y, X),
  YZY = AxisConvention(Y, Z, Y),
  ZYZ = AxisConvention(Z, Y, Z),
  XZX = AxisConvention(X, Z, X),
  YXY = AxisConvention(Y, X, Y),
};

enum class CardanoAngles {
  XYZ = AxisConvention(X, Y, Z),
  YZX = AxisConvention(Y, Z, X),
  ZXY = AxisConvention(Z, X, Y),
  XZY = AxisConvention(X, Z, Y),
  ZYX = AxisConvention(Z, Y, X),  // Yaw, Pitch, Roll.
  YXZ = AxisConvention(Y, X, Z),
};

template<typename Frame>
struct DefinesFrame {};

// An orientation-preserving orthogonal map between the inner product spaces
// |FromFrame| and |ToFrame|, as well as the induced maps on the exterior
// algebra.
template<typename FromFrame, typename ToFrame>
class Rotation : public LinearMap<FromFrame, ToFrame> {
 public:
  explicit Rotation(Quaternion const& quaternion);

  // A rotation of |angle| around |axis|; no coordinate change is involved, this
  // is an active rotation.
  template<typename Scalar,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<std::is_same<F, T>::value>>
  Rotation(Angle const& angle, Bivector<Scalar, FromFrame> const& axis);

  // The constructors below define passive rotations (changes of coordinates
  // between orthonormal bases sharing the same orientation, rather than
  // physical rotations).  As a consequence, they require that |FromFrame| be
  // distinct from |ToFrame|.

  // Construct a rotation from the axes of |ToFrame|, expressed in |FromFrame|.
  template<int rank_x, int rank_y, int rank_z,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Multivector<double, FromFrame, rank_x> x_to_frame,
           Multivector<double, FromFrame, rank_y> y_to_frame,
           Multivector<double, FromFrame, rank_z> z_to_frame);
  // Construct a rotation from the axes of |FromFrame|, expressed in |ToFrame|.
  // The |typename = void| template parameter gives it a different signature
  // from the above when |FromFrame| and |ToFrame| are the same (otherwise this
  // is a problem when instantiating the class, even though they are both
  // disabled by |enable_if|).
  template<int rank_x, int rank_y, int rank_z,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Multivector<double, ToFrame, rank_x> x_from_frame,
           Multivector<double, ToFrame, rank_y> y_from_frame,
           Multivector<double, ToFrame, rank_z> z_from_frame);

  // While expressing one basis in another is unambiguous to define passive
  // rotations, rotations expressed from an axis and an angle are more
  // confusing, and Euler angles are a constant trap.  We therefore require a
  // tag that specifies which frame is being defined by the given angle and
  // axis.
  // These constructors come in pairs (with either value of DefinesFrame), like
  // the matrix constructors above.  For each pair, one of the constructors has
  // an additional |typename = void|, see above.

  template<typename Scalar,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Angle const& angle,
           Bivector<Scalar, FromFrame> const& axis,
           DefinesFrame<ToFrame> tag);

  template<typename Scalar,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Angle const& angle,
           Bivector<Scalar, ToFrame> const& axis,
           DefinesFrame<FromFrame> tag);

  // Constructors from Euler angles.
  // Example: if |Orbit| is the frame of an orbit (x towards the periapsis,
  // z the positive normal to the orbit plane), and Ω, i, and ω are the elements
  // in some |Reference| frame,
  //   Rotation<Reference, Orbit>(Ω, i, ω, EulerAngles::ZXZ,
  //                              DefinesFrame<Orbit>{})
  // and
  //   Rotation<Orbit, Reference>(Ω, i, ω, EulerAngles::ZXZ,
  //                              DefinesFrame<Orbit>{})
  // are the transformations between |Reference| and |Orbit|.

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           EulerAngles const axes,
           DefinesFrame<ToFrame> tag);

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           EulerAngles const axes,
           DefinesFrame<FromFrame> tag);

  // Constructors from Cardano angles.
  // Example: if |Aircraft| is the frame of an aircraft (x forward, y right,
  // z down), and |Ground| is a local-vertical, local-horizontal frame (x North,
  // y East, z Down), given the |heading|, |pitch|, and |roll| of the aircraft,
  //   Rotation<Ground, Aircraft>(heading, pitch, roll, CardanoAngles::ZYX,
  //                              DefinesFrame<Aircraft>{})
  // and
  //   Rotation<Aircraft, Ground>(heading, pitch, roll, CardanoAngles::ZYX,
  //                              DefinesFrame<Aircraft>{})
  // are the transformations between |Aircraft| and |Ground|.

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           CardanoAngles const axes,
           DefinesFrame<ToFrame> tag);

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           CardanoAngles const axes,
           DefinesFrame<FromFrame> tag);

  ~Rotation() override = default;

  Sign Determinant() const override;

  Rotation<ToFrame, FromFrame> Inverse() const;

  template<typename Scalar>
  Vector<Scalar, ToFrame> operator()(
      Vector<Scalar, FromFrame> const& vector) const;

  template<typename Scalar>
  Bivector<Scalar, ToFrame> operator()(
      Bivector<Scalar, FromFrame> const& bivector) const;

  template<typename Scalar>
  Trivector<Scalar, ToFrame> operator()(
      Trivector<Scalar, FromFrame> const& trivector) const;

  template<typename T>
  typename base::Mappable<Rotation, T>::type operator()(T const& t) const;

  OrthogonalMap<FromFrame, ToFrame> Forget() const;

  static Rotation Identity();

  Quaternion const& quaternion() const;

  void WriteToMessage(not_null<serialization::LinearMap*> const message) const;
  static Rotation ReadFromMessage(serialization::LinearMap const& message);

  void WriteToMessage(not_null<serialization::Rotation*> const message) const;
  static Rotation ReadFromMessage(serialization::Rotation const& message);

 private:
  template<typename Scalar>
  R3Element<Scalar> operator()(R3Element<Scalar> const& r3_element) const;

  Quaternion quaternion_;

  // For constructing a rotation using a quaternion.
  template<typename From, typename To>
  friend class Permutation;

  template<typename From, typename Through, typename To>
  friend Rotation<From, To> operator*(Rotation<Through, To> const& left,
                                      Rotation<From, Through> const& right);

  friend std::ostream& operator<<<>(std::ostream& out,  // NOLINT
                                    Rotation const& rotation);
};

template<typename FromFrame, typename ThroughFrame, typename ToFrame>
Rotation<FromFrame, ToFrame> operator*(
    Rotation<ThroughFrame, ToFrame> const& left,
    Rotation<FromFrame, ThroughFrame> const& right);

}  // namespace geometry
}  // namespace principia

#include "geometry/rotation_body.hpp"
<commit_msg>parentheses<commit_after>
#pragma once

#include "base/mappable.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/linear_map.hpp"
#include "geometry/quaternion.hpp"
#include "geometry/r3_element.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "geometry/sign.hpp"
#include "serialization/geometry.pb.h"

namespace principia {
namespace geometry {

template<typename FromFrame, typename ToFrame>
class OrthogonalMap;

template<typename FromFrame, typename ToFrame>
std::ostream& operator<<(std::ostream& out,
                         Rotation<FromFrame, ToFrame> const& rotation);

// |EulerAngles| and |CardanoAngles| have values in binary-coded ternary
// representing the sequence of rotation axes.

// |AxisConvention| concatenates ternary digits.  Implementation here so it is
// defined by the time we use it as a constant expression.
constexpr int AxisConvention(int const first_axis,
                             int const second_axis,
                             int const third_axis) {
  return ((((first_axis << 2) + second_axis) << 2) + third_axis);
}

constexpr int X = 0;
constexpr int Y = 1;
constexpr int Z = 2;

enum class EulerAngles {
  // |ZXZ| is The most common convention, e.g. orbital elements (Ω, i, ω),
  // rotational elements (90˚ + α₀, 90˚ - δ₀, W).
  ZXZ = AxisConvention(Z, X, Z),
  XYX = AxisConvention(X, Y, X),
  YZY = AxisConvention(Y, Z, Y),
  ZYZ = AxisConvention(Z, Y, Z),
  XZX = AxisConvention(X, Z, X),
  YXY = AxisConvention(Y, X, Y),
};

enum class CardanoAngles {
  XYZ = AxisConvention(X, Y, Z),
  YZX = AxisConvention(Y, Z, X),
  ZXY = AxisConvention(Z, X, Y),
  XZY = AxisConvention(X, Z, Y),
  ZYX = AxisConvention(Z, Y, X),  // Yaw, Pitch, Roll.
  YXZ = AxisConvention(Y, X, Z),
};

template<typename Frame>
struct DefinesFrame {};

// An orientation-preserving orthogonal map between the inner product spaces
// |FromFrame| and |ToFrame|, as well as the induced maps on the exterior
// algebra.
template<typename FromFrame, typename ToFrame>
class Rotation : public LinearMap<FromFrame, ToFrame> {
 public:
  explicit Rotation(Quaternion const& quaternion);

  // A rotation of |angle| around |axis|; no coordinate change is involved, this
  // is an active rotation.
  template<typename Scalar,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<std::is_same<F, T>::value>>
  Rotation(Angle const& angle, Bivector<Scalar, FromFrame> const& axis);

  // The constructors below define passive rotations (changes of coordinates
  // between orthonormal bases sharing the same orientation, rather than
  // physical rotations).  As a consequence, they require that |FromFrame| be
  // distinct from |ToFrame|.

  // Construct a rotation from the axes of |ToFrame|, expressed in |FromFrame|.
  template<int rank_x, int rank_y, int rank_z,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Multivector<double, FromFrame, rank_x> x_to_frame,
           Multivector<double, FromFrame, rank_y> y_to_frame,
           Multivector<double, FromFrame, rank_z> z_to_frame);
  // Construct a rotation from the axes of |FromFrame|, expressed in |ToFrame|.
  // The |typename = void| template parameter gives it a different signature
  // from the above when |FromFrame| and |ToFrame| are the same (otherwise this
  // is a problem when instantiating the class, even though they are both
  // disabled by |enable_if|).
  template<int rank_x, int rank_y, int rank_z,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Multivector<double, ToFrame, rank_x> x_from_frame,
           Multivector<double, ToFrame, rank_y> y_from_frame,
           Multivector<double, ToFrame, rank_z> z_from_frame);

  // While expressing one basis in another is unambiguous to define passive
  // rotations, rotations expressed from an axis and an angle are more
  // confusing, and Euler angles are a constant trap.  We therefore require a
  // tag that specifies which frame is being defined by the given angle and
  // axis.
  // These constructors come in pairs (with either value of DefinesFrame), like
  // the matrix constructors above.  For each pair, one of the constructors has
  // an additional |typename = void|, see above.

  template<typename Scalar,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Angle const& angle,
           Bivector<Scalar, FromFrame> const& axis,
           DefinesFrame<ToFrame> tag);

  template<typename Scalar,
           typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Angle const& angle,
           Bivector<Scalar, ToFrame> const& axis,
           DefinesFrame<FromFrame> tag);

  // Constructors from Euler angles.
  // Example: if |Orbit| is the frame of an orbit (x towards the periapsis,
  // z the positive normal to the orbit plane), and Ω, i, and ω are the elements
  // in some |Reference| frame,
  //   Rotation<Reference, Orbit>(Ω, i, ω, EulerAngles::ZXZ,
  //                              DefinesFrame<Orbit>{})
  // and
  //   Rotation<Orbit, Reference>(Ω, i, ω, EulerAngles::ZXZ,
  //                              DefinesFrame<Orbit>{})
  // are the transformations between |Reference| and |Orbit|.

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           EulerAngles const axes,
           DefinesFrame<ToFrame> tag);

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           EulerAngles const axes,
           DefinesFrame<FromFrame> tag);

  // Constructors from Cardano angles.
  // Example: if |Aircraft| is the frame of an aircraft (x forward, y right,
  // z down), and |Ground| is a local-vertical, local-horizontal frame (x North,
  // y East, z Down), given the |heading|, |pitch|, and |roll| of the aircraft,
  //   Rotation<Ground, Aircraft>(heading, pitch, roll, CardanoAngles::ZYX,
  //                              DefinesFrame<Aircraft>{})
  // and
  //   Rotation<Aircraft, Ground>(heading, pitch, roll, CardanoAngles::ZYX,
  //                              DefinesFrame<Aircraft>{})
  // are the transformations between |Aircraft| and |Ground|.

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           CardanoAngles const axes,
           DefinesFrame<ToFrame> tag);

  template<typename F = FromFrame,
           typename T = ToFrame,
           typename = std::enable_if_t<!std::is_same<F, T>::value>,
           typename = void>
  Rotation(Angle const& α,
           Angle const& β,
           Angle const& γ,
           CardanoAngles const axes,
           DefinesFrame<FromFrame> tag);

  ~Rotation() override = default;

  Sign Determinant() const override;

  Rotation<ToFrame, FromFrame> Inverse() const;

  template<typename Scalar>
  Vector<Scalar, ToFrame> operator()(
      Vector<Scalar, FromFrame> const& vector) const;

  template<typename Scalar>
  Bivector<Scalar, ToFrame> operator()(
      Bivector<Scalar, FromFrame> const& bivector) const;

  template<typename Scalar>
  Trivector<Scalar, ToFrame> operator()(
      Trivector<Scalar, FromFrame> const& trivector) const;

  template<typename T>
  typename base::Mappable<Rotation, T>::type operator()(T const& t) const;

  OrthogonalMap<FromFrame, ToFrame> Forget() const;

  static Rotation Identity();

  Quaternion const& quaternion() const;

  void WriteToMessage(not_null<serialization::LinearMap*> const message) const;
  static Rotation ReadFromMessage(serialization::LinearMap const& message);

  void WriteToMessage(not_null<serialization::Rotation*> const message) const;
  static Rotation ReadFromMessage(serialization::Rotation const& message);

 private:
  template<typename Scalar>
  R3Element<Scalar> operator()(R3Element<Scalar> const& r3_element) const;

  Quaternion quaternion_;

  // For constructing a rotation using a quaternion.
  template<typename From, typename To>
  friend class Permutation;

  template<typename From, typename Through, typename To>
  friend Rotation<From, To> operator*(Rotation<Through, To> const& left,
                                      Rotation<From, Through> const& right);

  friend std::ostream& operator<<<>(std::ostream& out,  // NOLINT
                                    Rotation const& rotation);
};

template<typename FromFrame, typename ThroughFrame, typename ToFrame>
Rotation<FromFrame, ToFrame> operator*(
    Rotation<ThroughFrame, ToFrame> const& left,
    Rotation<FromFrame, ThroughFrame> const& right);

}  // namespace geometry
}  // namespace principia

#include "geometry/rotation_body.hpp"
<|endoftext|>