<commit_before>#ifndef HASKELL_TRAITS_DETAIL_FUNC_HPP
#define HASKELL_TRAITS_DETAIL_FUNC_HPP

#include <haskell_traits/detail/meta.hpp>

HASKELL_TRAITS_DETAIL_BEGIN
    // modified from cppreference on aug 3, 2017:
    // http://en.cppreference.com/w/cpp/utility/functional/invoke
    template<typename T>
    constexpr bool is_reference_wrapper_v = instantiation_of<std::reference_wrapper, T>;

    template<typename T, typename Type, typename T1, typename... Args>
    constexpr result_t<Type T::*, T1&&, Args&&...>
    INVOKE(Type T::*f, T1 && t1, Args && ... args) noexcept(
        noexcept_callable<Type T::*, T1&&, Args&&...>)
    {
        if
            constexpr(std::is_member_function_pointer_v<decltype(f)>)
            {
                if
                    constexpr(std::is_base_of_v<T, std::decay_t<T1>>) return (
                        std::forward<T1>(t1).*f)(std::forward<Args>(args)...);
                else if
                    constexpr(is_reference_wrapper_v<std::decay_t<T1>>) return (t1.get().*f)(
                        std::forward<Args>(args)...);
                else
                    return ((*std::forward<T1>(t1)).*f)(std::forward<Args>(args)...);
            }
        else {
            static_assert(std::is_member_object_pointer_v<decltype(f)>);
            static_assert(sizeof...(args) == 0);
            if
                constexpr(std::is_base_of_v<T, std::decay_t<T1>>) return std::forward<T1>(t1).*f;
            else if
                constexpr(is_reference_wrapper_v<std::decay_t<T1>>) return t1.get().*f;
            else
                return (*std::forward<T1>(t1)).*f;
        }
    }

    template<typename F, typename... Args>
    constexpr result_t<F&&, Args&&...> INVOKE(F && f, Args && ... args) noexcept(
        noexcept_callable<F&&, Args&&...>)
    {
        return ((F &&) f)((Args &&) args...);
    }
HASKELL_TRAITS_DETAIL_END

HASKELL_TRAITS_BEGIN
    template<typename F, typename... Args, REQUIRES(callable<F&&, Args&&...>)>
    constexpr result_t<F&&, Args&&...> invoke(F && f, Args && ... args) noexcept(
        noexcept_callable<F&&, Args&&...>)
    {
        return detail::INVOKE((F &&) f, (Args &&) args...);
    }
HASKELL_TRAITS_END

HASKELL_TRAITS_DETAIL_BEGIN
    template<typename F, typename = void>
    struct func_impl : private F
    {
        template<typename... Args, REQUIRES(std::is_constructible_v<F, Args&&...>)>
        constexpr func_impl(Args&&... args) noexcept(std::is_nothrow_constructible_v<F, Args&&...>)
            : F((Args &&) args...)
        {
        }

        using F::operator();
    };

    template<typename F>
    struct func_impl<F, REQUIRES_(!std::is_class_v<F> || std::is_final_v<F>)>
    {
    private:
        F f;

    public:
        template<typename... Args, REQUIRES(std::is_constructible_v<F, Args&&...>)>
        constexpr func_impl(Args&&... args) noexcept(std::is_nothrow_constructible_v<F, Args&&...>)
            : f((Args &&) args...)
        {
        }

#define HASKELL_TRAITS_CALL_OP(cvref)                                                              \
    template<typename... Args, REQUIRES(callable<F cvref, Args...>)>                               \
    constexpr result_t<F cvref, Args&&...> operator()(Args&&... args)                              \
        cvref noexcept(noexcept_callable<F cvref, Args&&...>)                                      \
    {                                                                                \
        return haskell_traits::invoke(static_cast<F cvref>(f), (Args &&) args...);                 \
    }                                                                                \
        /**/

        HASKELL_TRAITS_CALL_OP(&)
        HASKELL_TRAITS_CALL_OP(&&)
        HASKELL_TRAITS_CALL_OP(const&)
        HASKELL_TRAITS_CALL_OP(const&&)
#undef HASKELL_TRAITS_CALL_OP
    };
HASKELL_TRAITS_DETAIL_END

HASKELL_TRAITS_BEGIN
    template<typename F>
    struct func : private detail::func_impl<F>
    {
        static_assert(!std::is_reference_v<F>);
        static_assert(!instantiation_of<func, F>);

        using underlying_t = F;

        using detail::func_impl<F>::func_impl;
        using detail::func_impl<F>::operator();
    };

    template<typename F>
    inline constexpr auto is_func = instantiation_of<func, F>;

    template<typename F, REQUIRES(!is_func<F>)>
    func(F && f)->func<uncvref<F>>;
    template<typename F, REQUIRES(is_func<F>)>
    func(F && f)->func<typename uncvref<F>::underlying_t>;

    template<typename F>
    using func_t = decltype(func(std::declval<F>()));

    template<typename... Fs>
    struct merged : private Fs...
    {
        static_assert((is_func<Fs> && ...));

        template<typename... Fs_In, REQUIRES((std::is_constructible_v<Fs, Fs_In&&> && ...))>
        constexpr merged(Fs_In&&... fs) noexcept(
            (std::is_nothrow_constructible_v<Fs, Fs_In&&> && ...))
            : Fs((Fs_In)fs)...
        {
        }

        using Fs::operator()...;
    };

    template<typename... Fs>
    merged(Fs && ...)->merged<func_t<Fs>...>;

    template<typename T>
    struct expected_result
    {
    };
HASKELL_TRAITS_END

HASKELL_TRAITS_DETAIL_BEGIN
    template<typename Expected, typename Func, typename... Args>
    inline constexpr auto callable_returns = std::bool_constant<
        callable<
            Func,
            Args...> && std::is_convertible_v<detected_or<nonesuch, result_t, Func, Args...>, Expected>>{};

    template<typename F>
    struct overload_return_member : private F
    {
        static_assert(is_func<F>);

        using F::F;

#define HASKELL_TRAITS_CALL_OP(cvref)                                                              \
    template<typename Expected,                                                                    \
             typename... Args,                                                                     \
             REQUIRES(callable_returns<Expected, F cvref, Args&&...>)>                             \
    constexpr result_t<F cvref, Args&&...> operator()(expected_result<Expected>, Args&&... args)   \
        cvref noexcept(noexcept(Expected(static_cast<F cvref>(*this)((Args &&) args...))))         \
    {                                                                                \
        return static_cast<F cvref>(*this)((Args &&) args...);                                     \
    }                                                                                \
        /**/

        HASKELL_TRAITS_CALL_OP(&)
        HASKELL_TRAITS_CALL_OP(&&)
        HASKELL_TRAITS_CALL_OP(const&)
        HASKELL_TRAITS_CALL_OP(const&&)
#undef HASKELL_TRAITS_CALL_OP

        using F::operator();
    };
HASKELL_TRAITS_DETAIL_END

HASKELL_TRAITS_BEGIN
    template<typename... Funcs>
    struct overload_return : private detail::overload_return_member<Funcs>...
    {
        template<typename... Funcs_In,
                 REQUIRES((std::is_constructible_v<Funcs, Funcs_In&&> && ...))>
        constexpr overload_return(Funcs_In&&... fs) noexcept(
            (std::is_nothrow_constructible_v<Funcs, Funcs_In&&> && ...))
            : detail::overload_return_member<Funcs>((Funcs_In &&) fs)...
        {
        }

        using detail::overload_return_member<Funcs>::operator()...;
    };

    template<typename... Fs>
    overload_return(Fs && ... fs)->overload_return<func_t<uncvref<Fs>>...>;

    template<typename... Fs>
    using overload_return_t = decltype(overload_return(std::declval<Fs>()...));
HASKELL_TRAITS_END

#endif /* HASKELL_TRAITS_DETAIL_FUNC_HPP */<commit_msg>fix a noexcept, and add a typedef<commit_after>#ifndef HASKELL_TRAITS_DETAIL_FUNC_HPP
#define HASKELL_TRAITS_DETAIL_FUNC_HPP

#include <haskell_traits/detail/meta.hpp>

HASKELL_TRAITS_DETAIL_BEGIN
    // modified from cppreference on aug 3, 2017:
    // http://en.cppreference.com/w/cpp/utility/functional/invoke
    template<typename T>
    constexpr bool is_reference_wrapper_v = instantiation_of<std::reference_wrapper, T>;

    template<typename T, typename Type, typename T1, typename... Args>
    constexpr result_t<Type T::*, T1&&, Args&&...>
    INVOKE(Type T::*f, T1 && t1, Args && ... args) noexcept(
        noexcept_callable<Type T::*, T1&&, Args&&...>)
    {
        if
            constexpr(std::is_member_function_pointer_v<decltype(f)>)
            {
                if
                    constexpr(std::is_base_of_v<T, std::decay_t<T1>>) return (
                        std::forward<T1>(t1).*f)(std::forward<Args>(args)...);
                else if
                    constexpr(is_reference_wrapper_v<std::decay_t<T1>>) return (t1.get().*f)(
                        std::forward<Args>(args)...);
                else
                    return ((*std::forward<T1>(t1)).*f)(std::forward<Args>(args)...);
            }
        else {
            static_assert(std::is_member_object_pointer_v<decltype(f)>);
            static_assert(sizeof...(args) == 0);
            if
                constexpr(std::is_base_of_v<T, std::decay_t<T1>>) return std::forward<T1>(t1).*f;
            else if
                constexpr(is_reference_wrapper_v<std::decay_t<T1>>) return t1.get().*f;
            else
                return (*std::forward<T1>(t1)).*f;
        }
    }

    template<typename F, typename... Args>
    constexpr result_t<F&&, Args&&...> INVOKE(F && f, Args && ... args) noexcept(
        noexcept_callable<F&&, Args&&...>)
    {
        return ((F &&) f)((Args &&) args...);
    }
HASKELL_TRAITS_DETAIL_END

HASKELL_TRAITS_BEGIN
    template<typename F, typename... Args, REQUIRES(callable<F&&, Args&&...>)>
    constexpr result_t<F&&, Args&&...> invoke(F && f, Args && ... args) noexcept(
        noexcept_callable<F&&, Args&&...>)
    {
        return detail::INVOKE((F &&) f, (Args &&) args...);
    }
HASKELL_TRAITS_END

HASKELL_TRAITS_DETAIL_BEGIN
    template<typename F, typename = void>
    struct func_impl : private F
    {
        template<typename... Args, REQUIRES(std::is_constructible_v<F, Args&&...>)>
        constexpr func_impl(Args&&... args) noexcept(std::is_nothrow_constructible_v<F, Args&&...>)
            : F((Args &&) args...)
        {
        }

        using F::operator();
    };

    template<typename F>
    struct func_impl<F, REQUIRES_(!std::is_class_v<F> || std::is_final_v<F>)>
    {
    private:
        F f;

    public:
        template<typename... Args, REQUIRES(std::is_constructible_v<F, Args&&...>)>
        constexpr func_impl(Args&&... args) noexcept(std::is_nothrow_constructible_v<F, Args&&...>)
            : f((Args &&) args...)
        {
        }

#define HASKELL_TRAITS_CALL_OP(cvref)                                                              \
    template<typename... Args, REQUIRES(callable<F cvref, Args...>)>                               \
    constexpr result_t<F cvref, Args&&...> operator()(Args&&... args)                              \
        cvref noexcept(noexcept_callable<F cvref, Args&&...>)                                      \
    {                                                                                \
        return haskell_traits::invoke(static_cast<F cvref>(f), (Args &&) args...);                 \
    }                                                                                \
        /**/

        HASKELL_TRAITS_CALL_OP(&)
        HASKELL_TRAITS_CALL_OP(&&)
        HASKELL_TRAITS_CALL_OP(const&)
        HASKELL_TRAITS_CALL_OP(const&&)
#undef HASKELL_TRAITS_CALL_OP
    };
HASKELL_TRAITS_DETAIL_END

HASKELL_TRAITS_BEGIN
    template<typename F>
    struct func : private detail::func_impl<F>
    {
        static_assert(!std::is_reference_v<F>);
        static_assert(!instantiation_of<func, F>);

        using underlying_t = F;

        using detail::func_impl<F>::func_impl;
        using detail::func_impl<F>::operator();
    };

    template<typename F>
    inline constexpr auto is_func = instantiation_of<func, F>;

    template<typename F, REQUIRES(!is_func<F>)>
    func(F && f)->func<uncvref<F>>;
    template<typename F, REQUIRES(is_func<F>)>
    func(F && f)->func<typename uncvref<F>::underlying_t>;

    template<typename F>
    using func_t = decltype(func(std::declval<F>()));

    template<typename... Fs>
    struct merged : private Fs...
    {
        static_assert((is_func<Fs> && ...));

        template<typename... Fs_In, REQUIRES((std::is_constructible_v<Fs, Fs_In&&> && ...))>
        constexpr merged(Fs_In&&... fs) noexcept(
            (std::is_nothrow_constructible_v<Fs, Fs_In&&> && ...))
            : Fs((Fs_In)fs)...
        {
        }

        using Fs::operator()...;
    };

    template<typename... Fs>
    merged(Fs && ...)->merged<func_t<Fs>...>;

    template<typename... Fs>
    using merged_t = decltype(merged(std::declval<Fs>()...));

    template<typename T>
    struct expected_result
    {
    };
HASKELL_TRAITS_END

HASKELL_TRAITS_DETAIL_BEGIN
    template<typename Expected, typename Func, typename... Args>
    inline constexpr auto callable_returns = std::bool_constant<
        callable<
            Func,
            Args...> && std::is_convertible_v<detected_or<nonesuch, result_t, Func, Args...>, Expected>>{};

    template<typename F>
    struct overload_return_member : private F
    {
        static_assert(is_func<F>);

        using F::F;

#define HASKELL_TRAITS_CALL_OP(cvref)                                                              \
    template<typename Expected,                                                                    \
             typename... Args,                                                                     \
             REQUIRES(callable_returns<Expected, F cvref, Args&&...>)>                             \
    constexpr result_t<F cvref, Args&&...> operator()(expected_result<Expected>, Args&&... args)   \
        cvref noexcept(noexcept(static_cast<F cvref>(*this)((Args &&) args...)))                   \
    {                                                                                \
        return static_cast<F cvref>(*this)((Args &&) args...);                                     \
    }                                                                                \
        /**/

        HASKELL_TRAITS_CALL_OP(&)
        HASKELL_TRAITS_CALL_OP(&&)
        HASKELL_TRAITS_CALL_OP(const&)
        HASKELL_TRAITS_CALL_OP(const&&)
#undef HASKELL_TRAITS_CALL_OP

        using F::operator();
    };
HASKELL_TRAITS_DETAIL_END

HASKELL_TRAITS_BEGIN
    template<typename... Funcs>
    struct overload_return : private detail::overload_return_member<Funcs>...
    {
        template<typename... Funcs_In,
                 REQUIRES((std::is_constructible_v<Funcs, Funcs_In&&> && ...))>
        constexpr overload_return(Funcs_In&&... fs) noexcept(
            (std::is_nothrow_constructible_v<Funcs, Funcs_In&&> && ...))
            : detail::overload_return_member<Funcs>((Funcs_In &&) fs)...
        {
        }

        using detail::overload_return_member<Funcs>::operator()...;
    };

    template<typename... Fs>
    overload_return(Fs && ... fs)->overload_return<func_t<uncvref<Fs>>...>;

    template<typename... Fs>
    using overload_return_t = decltype(overload_return(std::declval<Fs>()...));
HASKELL_TRAITS_END

#endif /* HASKELL_TRAITS_DETAIL_FUNC_HPP */<|endoftext|>


<commit_before>#include "GapConductance.h"

template<>
InputParameters validParams<GapConductance>()
{
  MooseEnum orders("FIRST, SECOND, THIRD, FOURTH", "FIRST");

  InputParameters params = validParams<Material>();

  // Node based
  params.addCoupledVar("gap_distance", "Distance across the gap");
  params.addCoupledVar("gap_temp", "Temperature on the other side of the gap");
  params.addParam<Real>("gap_conductivity", 1.0, "The thermal conductivity of the gap material");

  // Quadrature based
  params.addCoupledVar("temp", "The temperature variable");
  params.addParam<bool>("quadrature", false, "Whether or not to do Quadrature point based gap heat transfer.  If this is true then gap_distance and gap_temp shoul NOT be provided (and will be ignored) however paired_boundary IS then required and so is 'temp'.");
  params.addParam<BoundaryName>("paired_boundary", "The boundary to be penetrated");
  params.addParam<MooseEnum>("order", orders, "The finite element order");
  params.addParam<bool>("warnings", false, "Whether to output warning messages concerning nodes not being found");

  // Common
  params.addParam<Real>("min_gap", 1.0e-6, "A minimum gap size");
  params.addParam<Real>("max_gap", 1.0e6, "A maximum gap size");
  return params;
}

GapConductance::GapConductance(const std::string & name, InputParameters parameters)
  :Material(name, parameters),
   _quadrature(getParam<bool>("quadrature")),
   _gap_temp(0),
   _gap_distance(88888),
   _has_info(false),
   _gap_distance_value(_quadrature ? _zero : coupledValue("gap_distance")),
   _gap_temp_value(_quadrature ? _zero : coupledValue("gap_temp")),
   _gap_conductance(declareProperty<Real>("gap_conductance")),
   _gap_conductance_dT(declareProperty<Real>("gap_conductance_dT")),
   _gap_conductivity(getParam<Real>("gap_conductivity")),
   _min_gap(getParam<Real>("min_gap")),
   _max_gap(getParam<Real>("max_gap")),
   _temp_var(_quadrature ? getVar("temp",0) : NULL),
   _penetration_locator(NULL),
   _current_mesh(NULL),
   _serialized_solution(_quadrature ? &_temp_var->sys().currentSolution() : NULL),
   _dof_map(_quadrature ? &_temp_var->sys().dofMap() : NULL),
   _warnings(getParam<bool>("warnings"))
{
  if(_quadrature)
  {
    if(!parameters.isParamValid("paired_boundary"))
      mooseError(std::string("No 'paired_boundary' provided for ") + _name);

    if(!isCoupled("temp"))
      mooseError(std::string("No 'temp' provided for ") + _name);
  }
  else
  {
    if(!isCoupled("gap_distance"))
      mooseError(std::string("No 'gap_distance' provided for ") + _name);

    if(!isCoupled("gap_temp"))
      mooseError(std::string("No 'gap_temp' provided for ") + _name);
  }

  if(_quadrature)
  {
    if(_displaced_subproblem)
    {
      _penetration_locator = &_displaced_subproblem->geomSearchData().getQuadraturePenetrationLocator(parameters.get<BoundaryName>("paired_boundary"),
                                                                                getParam<std::vector<BoundaryName> >("boundary")[0],
                                                                                Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")));
      _current_mesh = &_displaced_subproblem->mesh();
    }
    else
    {
      _penetration_locator = &_subproblem.geomSearchData().getQuadraturePenetrationLocator(parameters.get<BoundaryName>("paired_boundary"),
                                                                                getParam<std::vector<BoundaryName> >("boundary")[0],
                                                                                Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")));
      _current_mesh = &_subproblem.mesh();
    }
  }
}

void
GapConductance::computeQpProperties()
{
  computeGapTempAndDistance();
  computeQpConductance();
}

void
GapConductance::computeQpConductance()
{
  _gap_conductance[_qp] = h_conduction();
  _gap_conductance_dT[_qp] = dh_conduction();
}

Real
GapConductance::h_conduction()
{
  return gapK()/gapLength(-(_gap_distance), _min_gap, _max_gap);
}

Real
GapConductance::dh_conduction()
{
  return 0;
}

Real
GapConductance::gapLength(Real distance, Real min_gap, Real max_gap)
{
  Real gap_L = distance;

  if(gap_L > max_gap)
  {
    gap_L = max_gap;
  }

  gap_L = std::max(min_gap, gap_L);

  return gap_L;
}

Real
GapConductance::gapK()
{
  return _gap_conductivity;
}

void
GapConductance::computeGapTempAndDistance()
{
  if(!_quadrature)
  {
    _has_info = true;
    _gap_temp = _gap_temp_value[_qp];
    _gap_distance = _gap_distance_value[_qp];
    return;
  }

  Node * qnode = _current_mesh->getQuadratureNode(_current_elem, _current_side, _qp);

  PenetrationLocator::PenetrationInfo * pinfo = _penetration_locator->_penetration_info[qnode->id()];

  _gap_temp = 0.0;
  _gap_distance = 88888;
  _has_info = false;

  if (pinfo)
  {
    _gap_distance = pinfo->_distance;
    _has_info = true;

    Elem * slave_side = pinfo->_side;
    std::vector<std::vector<Real> > & slave_side_phi = pinfo->_side_phi;
    std::vector<unsigned int> slave_side_dof_indices;

    _dof_map->dof_indices(slave_side, slave_side_dof_indices, _temp_var->number());

    for(unsigned int i=0; i<slave_side_dof_indices.size(); ++i)
    {
      //The zero index is because we only have one point that the phis are evaluated at
      _gap_temp += slave_side_phi[i][0] * (*(*_serialized_solution))(slave_side_dof_indices[i]);
    }
  }
  else
  {
    if (_warnings)
    {
      std::stringstream msg;
      msg << "No gap value information found for node ";
      msg << qnode->id();
      msg << " on processor ";
      msg << libMesh::processor_id();
      mooseWarning( msg.str() );
    }
  }
}
<commit_msg>fix missing includes ref #1464<commit_after>#include "GapConductance.h"

// Moose Includes
#include "PenetrationLocator.h"

// libMesh Includes
#include "string_to_enum.h"

template<>
InputParameters validParams<GapConductance>()
{
  MooseEnum orders("FIRST, SECOND, THIRD, FOURTH", "FIRST");

  InputParameters params = validParams<Material>();

  // Node based
  params.addCoupledVar("gap_distance", "Distance across the gap");
  params.addCoupledVar("gap_temp", "Temperature on the other side of the gap");
  params.addParam<Real>("gap_conductivity", 1.0, "The thermal conductivity of the gap material");

  // Quadrature based
  params.addCoupledVar("temp", "The temperature variable");
  params.addParam<bool>("quadrature", false, "Whether or not to do Quadrature point based gap heat transfer.  If this is true then gap_distance and gap_temp shoul NOT be provided (and will be ignored) however paired_boundary IS then required and so is 'temp'.");
  params.addParam<BoundaryName>("paired_boundary", "The boundary to be penetrated");
  params.addParam<MooseEnum>("order", orders, "The finite element order");
  params.addParam<bool>("warnings", false, "Whether to output warning messages concerning nodes not being found");

  // Common
  params.addParam<Real>("min_gap", 1.0e-6, "A minimum gap size");
  params.addParam<Real>("max_gap", 1.0e6, "A maximum gap size");
  return params;
}

GapConductance::GapConductance(const std::string & name, InputParameters parameters)
  :Material(name, parameters),
   _quadrature(getParam<bool>("quadrature")),
   _gap_temp(0),
   _gap_distance(88888),
   _has_info(false),
   _gap_distance_value(_quadrature ? _zero : coupledValue("gap_distance")),
   _gap_temp_value(_quadrature ? _zero : coupledValue("gap_temp")),
   _gap_conductance(declareProperty<Real>("gap_conductance")),
   _gap_conductance_dT(declareProperty<Real>("gap_conductance_dT")),
   _gap_conductivity(getParam<Real>("gap_conductivity")),
   _min_gap(getParam<Real>("min_gap")),
   _max_gap(getParam<Real>("max_gap")),
   _temp_var(_quadrature ? getVar("temp",0) : NULL),
   _penetration_locator(NULL),
   _current_mesh(NULL),
   _serialized_solution(_quadrature ? &_temp_var->sys().currentSolution() : NULL),
   _dof_map(_quadrature ? &_temp_var->sys().dofMap() : NULL),
   _warnings(getParam<bool>("warnings"))
{
  if(_quadrature)
  {
    if(!parameters.isParamValid("paired_boundary"))
      mooseError(std::string("No 'paired_boundary' provided for ") + _name);

    if(!isCoupled("temp"))
      mooseError(std::string("No 'temp' provided for ") + _name);
  }
  else
  {
    if(!isCoupled("gap_distance"))
      mooseError(std::string("No 'gap_distance' provided for ") + _name);

    if(!isCoupled("gap_temp"))
      mooseError(std::string("No 'gap_temp' provided for ") + _name);
  }

  if(_quadrature)
  {
    if(_displaced_subproblem)
    {
      _penetration_locator = &_displaced_subproblem->geomSearchData().getQuadraturePenetrationLocator(parameters.get<BoundaryName>("paired_boundary"),
                                                                                getParam<std::vector<BoundaryName> >("boundary")[0],
                                                                                Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")));
      _current_mesh = &_displaced_subproblem->mesh();
    }
    else
    {
      _penetration_locator = &_subproblem.geomSearchData().getQuadraturePenetrationLocator(parameters.get<BoundaryName>("paired_boundary"),
                                                                                getParam<std::vector<BoundaryName> >("boundary")[0],
                                                                                Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")));
      _current_mesh = &_subproblem.mesh();
    }
  }
}

void
GapConductance::computeQpProperties()
{
  computeGapTempAndDistance();
  computeQpConductance();
}

void
GapConductance::computeQpConductance()
{
  _gap_conductance[_qp] = h_conduction();
  _gap_conductance_dT[_qp] = dh_conduction();
}

Real
GapConductance::h_conduction()
{
  return gapK()/gapLength(-(_gap_distance), _min_gap, _max_gap);
}

Real
GapConductance::dh_conduction()
{
  return 0;
}

Real
GapConductance::gapLength(Real distance, Real min_gap, Real max_gap)
{
  Real gap_L = distance;

  if(gap_L > max_gap)
  {
    gap_L = max_gap;
  }

  gap_L = std::max(min_gap, gap_L);

  return gap_L;
}

Real
GapConductance::gapK()
{
  return _gap_conductivity;
}

void
GapConductance::computeGapTempAndDistance()
{
  if(!_quadrature)
  {
    _has_info = true;
    _gap_temp = _gap_temp_value[_qp];
    _gap_distance = _gap_distance_value[_qp];
    return;
  }

  Node * qnode = _current_mesh->getQuadratureNode(_current_elem, _current_side, _qp);

  PenetrationLocator::PenetrationInfo * pinfo = _penetration_locator->_penetration_info[qnode->id()];

  _gap_temp = 0.0;
  _gap_distance = 88888;
  _has_info = false;

  if (pinfo)
  {
    _gap_distance = pinfo->_distance;
    _has_info = true;

    Elem * slave_side = pinfo->_side;
    std::vector<std::vector<Real> > & slave_side_phi = pinfo->_side_phi;
    std::vector<unsigned int> slave_side_dof_indices;

    _dof_map->dof_indices(slave_side, slave_side_dof_indices, _temp_var->number());

    for(unsigned int i=0; i<slave_side_dof_indices.size(); ++i)
    {
      //The zero index is because we only have one point that the phis are evaluated at
      _gap_temp += slave_side_phi[i][0] * (*(*_serialized_solution))(slave_side_dof_indices[i]);
    }
  }
  else
  {
    if (_warnings)
    {
      std::stringstream msg;
      msg << "No gap value information found for node ";
      msg << qnode->id();
      msg << " on processor ";
      msg << libMesh::processor_id();
      mooseWarning( msg.str() );
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "webkit/chromeos/fileapi/cros_mount_point_provider.h"

#include "base/chromeos/chromeos_version.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/utf_string_conversions.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "webkit/chromeos/fileapi/file_access_permissions.h"
#include "webkit/chromeos/fileapi/remote_file_stream_writer.h"
#include "webkit/chromeos/fileapi/remote_file_system_operation.h"
#include "webkit/fileapi/async_file_util_adapter.h"
#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/external_mount_points.h"
#include "webkit/fileapi/file_system_file_stream_reader.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_url.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/isolated_context.h"
#include "webkit/fileapi/isolated_file_util.h"
#include "webkit/fileapi/local_file_stream_writer.h"
#include "webkit/fileapi/local_file_system_operation.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const char kChromeUIScheme[] = "chrome";

}  // namespace

namespace chromeos {

// static
bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
  if (!url.is_valid())
    return false;
  return url.type() == fileapi::kFileSystemTypeNativeLocal ||
         url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal ||
         url.type() == fileapi::kFileSystemTypeDrive;
}

CrosMountPointProvider::CrosMountPointProvider(
    scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
    scoped_refptr<fileapi::ExternalMountPoints> mount_points,
    fileapi::ExternalMountPoints* system_mount_points)
    : special_storage_policy_(special_storage_policy),
      file_access_permissions_(new FileAccessPermissions()),
      local_file_util_(new fileapi::AsyncFileUtilAdapter(
          new fileapi::IsolatedFileUtil())),
      mount_points_(mount_points),
      system_mount_points_(system_mount_points) {
  // Add default system mount points.
  system_mount_points_->RegisterFileSystem(
      "archive",
      fileapi::kFileSystemTypeNativeLocal,
      chromeos::CrosDisksClient::GetArchiveMountPoint());
  system_mount_points_->RegisterFileSystem(
      "removable",
      fileapi::kFileSystemTypeNativeLocal,
      chromeos::CrosDisksClient::GetRemovableDiskMountPoint());
  system_mount_points_->RegisterFileSystem(
      "oem",
      fileapi::kFileSystemTypeRestrictedNativeLocal,
      base::FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
}

CrosMountPointProvider::~CrosMountPointProvider() {
}

bool CrosMountPointProvider::CanHandleType(fileapi::FileSystemType type) const {
  switch (type) {
    case fileapi::kFileSystemTypeExternal:
    case fileapi::kFileSystemTypeDrive:
    case fileapi::kFileSystemTypeRestrictedNativeLocal:
    case fileapi::kFileSystemTypeNativeLocal:
    case fileapi::kFileSystemTypeNativeForPlatformApp:
      return true;
    default:
      return false;
  }
}

void CrosMountPointProvider::ValidateFileSystemRoot(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    bool create,
    const ValidateFileSystemCallback& callback) {
  DCHECK(fileapi::IsolatedContext::IsIsolatedType(type));
  // Nothing to validate for external filesystem.
  callback.Run(base::PLATFORM_FILE_OK);
}

base::FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
    const fileapi::FileSystemURL& url,
    bool create) {
  DCHECK(fileapi::IsolatedContext::IsIsolatedType(url.mount_type()));
  if (!url.is_valid())
    return base::FilePath();

  base::FilePath root_path;
  std::string mount_name = url.filesystem_id();
  if (!mount_points_->GetRegisteredPath(mount_name, &root_path) &&
      !system_mount_points_->GetRegisteredPath(mount_name, &root_path)) {
    return base::FilePath();
  }

  return root_path.DirName();
}

fileapi::FileSystemQuotaUtil* CrosMountPointProvider::GetQuotaUtil() {
  // No quota support.
  return NULL;
}

void CrosMountPointProvider::DeleteFileSystem(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    fileapi::FileSystemContext* context,
    const DeleteFileSystemCallback& callback) {
  NOTREACHED();
  callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
}

bool CrosMountPointProvider::IsAccessAllowed(
    const fileapi::FileSystemURL& url) const {
  if (!url.is_valid())
    return false;

  // Permit access to mount points from internal WebUI.
  const GURL& origin_url = url.origin();
  if (origin_url.SchemeIs(kChromeUIScheme))
    return true;

  // No extra check is needed for isolated file systems.
  if (url.mount_type() == fileapi::kFileSystemTypeIsolated)
    return true;

  if (!CanHandleURL(url))
    return false;

  std::string extension_id = origin_url.host();
  // Check first to make sure this extension has fileBrowserHander permissions.
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return false;

  return file_access_permissions_->HasAccessPermission(extension_id,
                                                       url.virtual_path());
}

void CrosMountPointProvider::GrantFullAccessToExtension(
    const std::string& extension_id) {
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;

  std::vector<fileapi::MountPoints::MountPointInfo> files;
  mount_points_->AddMountPointInfosTo(&files);
  system_mount_points_->AddMountPointInfosTo(&files);

  for (size_t i = 0; i < files.size(); ++i) {
    file_access_permissions_->GrantAccessPermission(
        extension_id,
        base::FilePath::FromUTF8Unsafe(files[i].name));
  }
}

void CrosMountPointProvider::GrantFileAccessToExtension(
    const std::string& extension_id, const base::FilePath& virtual_path) {
  // All we care about here is access from extensions for now.
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;

  std::string id;
  fileapi::FileSystemType type;
  base::FilePath path;
  if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &path) &&
      !system_mount_points_->CrackVirtualPath(virtual_path,
                                              &id, &type, &path)) {
    return;
  }

  if (type == fileapi::kFileSystemTypeRestrictedNativeLocal) {
    LOG(ERROR) << "Can't grant access for restricted mount point";
    return;
  }

  file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
}

void CrosMountPointProvider::RevokeAccessForExtension(
      const std::string& extension_id) {
  file_access_permissions_->RevokePermissions(extension_id);
}

std::vector<base::FilePath> CrosMountPointProvider::GetRootDirectories() const {
  std::vector<fileapi::MountPoints::MountPointInfo> mount_points;
  mount_points_->AddMountPointInfosTo(&mount_points);
  system_mount_points_->AddMountPointInfosTo(&mount_points);

  std::vector<base::FilePath> root_dirs;
  for (size_t i = 0; i < mount_points.size(); ++i)
    root_dirs.push_back(mount_points[i].path);
  return root_dirs;
}

fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
    fileapi::FileSystemType type) {
  DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
         type == fileapi::kFileSystemTypeRestrictedNativeLocal);
  return local_file_util_->sync_file_util();
}

fileapi::AsyncFileUtil* CrosMountPointProvider::GetAsyncFileUtil(
    fileapi::FileSystemType type) {
  DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
         type == fileapi::kFileSystemTypeRestrictedNativeLocal);
  return local_file_util_.get();
}

fileapi::CopyOrMoveFileValidatorFactory*
CrosMountPointProvider::GetCopyOrMoveFileValidatorFactory(
    fileapi::FileSystemType type, base::PlatformFileError* error_code) {
  DCHECK(error_code);
  *error_code = base::PLATFORM_FILE_OK;
  return NULL;
}

void CrosMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
    fileapi::FileSystemType type,
    scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
  DCHECK(!factory);
}

fileapi::FilePermissionPolicy CrosMountPointProvider::GetPermissionPolicy(
    const fileapi::FileSystemURL& url, int permissions) const {
  if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal &&
      (permissions & ~fileapi::kReadFilePermissions)) {
    // Restricted file system is read-only.
    return fileapi::FILE_PERMISSION_ALWAYS_DENY;
  }

  if (!IsAccessAllowed(url))
    return fileapi::FILE_PERMISSION_ALWAYS_DENY;

  // Permit access to mount points from internal WebUI.
  const GURL& origin_url = url.origin();
  if (origin_url.SchemeIs(kChromeUIScheme))
    return fileapi::FILE_PERMISSION_ALWAYS_ALLOW;

  if (url.mount_type() == fileapi::kFileSystemTypeIsolated) {
    // Permissions in isolated filesystems should be examined with
    // FileSystem permission.
    return fileapi::FILE_PERMISSION_USE_FILESYSTEM_PERMISSION;
  }

  // Also apply system's file permission by default.
  return fileapi::FILE_PERMISSION_USE_FILE_PERMISSION;
}

fileapi::FileSystemOperation* CrosMountPointProvider::CreateFileSystemOperation(
    const fileapi::FileSystemURL& url,
    fileapi::FileSystemContext* context,
    base::PlatformFileError* error_code) const {
  DCHECK(url.is_valid());

  if (url.type() == fileapi::kFileSystemTypeDrive) {
    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
        GetRemoteProxy(url.filesystem_id());
    if (!remote_proxy) {
      *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND;
      return NULL;
    }
    return new chromeos::RemoteFileSystemOperation(remote_proxy);
  }

  DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal ||
         url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal);
  scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
      new fileapi::FileSystemOperationContext(context));
  return new fileapi::LocalFileSystemOperation(context,
                                               operation_context.Pass());
}

scoped_ptr<webkit_blob::FileStreamReader>
CrosMountPointProvider::CreateFileStreamReader(
    const fileapi::FileSystemURL& url,
    int64 offset,
    const base::Time& expected_modification_time,
    fileapi::FileSystemContext* context) const {
  // For now we return a generic Reader implementation which utilizes
  // CreateSnapshotFile internally (i.e. will download everything first).
  // TODO(satorux,zel): implement more efficient reader for remote cases.
  return scoped_ptr<webkit_blob::FileStreamReader>(
      new fileapi::FileSystemFileStreamReader(
          context, url, offset, expected_modification_time));
}

scoped_ptr<fileapi::FileStreamWriter>
CrosMountPointProvider::CreateFileStreamWriter(
    const fileapi::FileSystemURL& url,
    int64 offset,
    fileapi::FileSystemContext* context) const {
  DCHECK(url.is_valid());

  if (url.type() == fileapi::kFileSystemTypeDrive) {
    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
        GetRemoteProxy(url.filesystem_id());
    if (!remote_proxy)
      return scoped_ptr<fileapi::FileStreamWriter>();
    return scoped_ptr<fileapi::FileStreamWriter>(
        new fileapi::RemoteFileStreamWriter(remote_proxy, url, offset));
  }

  if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal)
    return scoped_ptr<fileapi::FileStreamWriter>();

  DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
  return scoped_ptr<fileapi::FileStreamWriter>(
      new fileapi::LocalFileStreamWriter(url.path(), offset));
}

bool CrosMountPointProvider::GetVirtualPath(
    const base::FilePath& filesystem_path,
    base::FilePath* virtual_path) {
  return mount_points_->GetVirtualPath(filesystem_path, virtual_path) ||
         system_mount_points_->GetVirtualPath(filesystem_path, virtual_path);
}

fileapi::RemoteFileSystemProxyInterface* CrosMountPointProvider::GetRemoteProxy(
    const std::string& mount_name) const {
  fileapi::RemoteFileSystemProxyInterface* proxy =
      mount_points_->GetRemoteFileSystemProxy(mount_name);
  if (proxy)
    return proxy;
  return system_mount_points_->GetRemoteFileSystemProxy(mount_name);
}

}  // namespace chromeos
<commit_msg>Switch to drive::internal::WebkitFileStreamReaderImpl for the FileStreamReader implementation for drive files in fileapi.<commit_after>// Copyright (c) 2012 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 "webkit/chromeos/fileapi/cros_mount_point_provider.h"

#include "base/chromeos/chromeos_version.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/utf_string_conversions.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "webkit/chromeos/fileapi/file_access_permissions.h"
#include "webkit/chromeos/fileapi/remote_file_stream_writer.h"
#include "webkit/chromeos/fileapi/remote_file_system_operation.h"
#include "webkit/fileapi/async_file_util_adapter.h"
#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/external_mount_points.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_stream_reader.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_task_runners.h"
#include "webkit/fileapi/file_system_url.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/isolated_context.h"
#include "webkit/fileapi/isolated_file_util.h"
#include "webkit/fileapi/local_file_stream_writer.h"
#include "webkit/fileapi/local_file_system_operation.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const char kChromeUIScheme[] = "chrome";

}  // namespace

namespace chromeos {

// static
bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
  if (!url.is_valid())
    return false;
  return url.type() == fileapi::kFileSystemTypeNativeLocal ||
         url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal ||
         url.type() == fileapi::kFileSystemTypeDrive;
}

CrosMountPointProvider::CrosMountPointProvider(
    scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
    scoped_refptr<fileapi::ExternalMountPoints> mount_points,
    fileapi::ExternalMountPoints* system_mount_points)
    : special_storage_policy_(special_storage_policy),
      file_access_permissions_(new FileAccessPermissions()),
      local_file_util_(new fileapi::AsyncFileUtilAdapter(
          new fileapi::IsolatedFileUtil())),
      mount_points_(mount_points),
      system_mount_points_(system_mount_points) {
  // Add default system mount points.
  system_mount_points_->RegisterFileSystem(
      "archive",
      fileapi::kFileSystemTypeNativeLocal,
      chromeos::CrosDisksClient::GetArchiveMountPoint());
  system_mount_points_->RegisterFileSystem(
      "removable",
      fileapi::kFileSystemTypeNativeLocal,
      chromeos::CrosDisksClient::GetRemovableDiskMountPoint());
  system_mount_points_->RegisterFileSystem(
      "oem",
      fileapi::kFileSystemTypeRestrictedNativeLocal,
      base::FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
}

CrosMountPointProvider::~CrosMountPointProvider() {
}

bool CrosMountPointProvider::CanHandleType(fileapi::FileSystemType type) const {
  switch (type) {
    case fileapi::kFileSystemTypeExternal:
    case fileapi::kFileSystemTypeDrive:
    case fileapi::kFileSystemTypeRestrictedNativeLocal:
    case fileapi::kFileSystemTypeNativeLocal:
    case fileapi::kFileSystemTypeNativeForPlatformApp:
      return true;
    default:
      return false;
  }
}

void CrosMountPointProvider::ValidateFileSystemRoot(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    bool create,
    const ValidateFileSystemCallback& callback) {
  DCHECK(fileapi::IsolatedContext::IsIsolatedType(type));
  // Nothing to validate for external filesystem.
  callback.Run(base::PLATFORM_FILE_OK);
}

base::FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
    const fileapi::FileSystemURL& url,
    bool create) {
  DCHECK(fileapi::IsolatedContext::IsIsolatedType(url.mount_type()));
  if (!url.is_valid())
    return base::FilePath();

  base::FilePath root_path;
  std::string mount_name = url.filesystem_id();
  if (!mount_points_->GetRegisteredPath(mount_name, &root_path) &&
      !system_mount_points_->GetRegisteredPath(mount_name, &root_path)) {
    return base::FilePath();
  }

  return root_path.DirName();
}

fileapi::FileSystemQuotaUtil* CrosMountPointProvider::GetQuotaUtil() {
  // No quota support.
  return NULL;
}

void CrosMountPointProvider::DeleteFileSystem(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    fileapi::FileSystemContext* context,
    const DeleteFileSystemCallback& callback) {
  NOTREACHED();
  callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
}

bool CrosMountPointProvider::IsAccessAllowed(
    const fileapi::FileSystemURL& url) const {
  if (!url.is_valid())
    return false;

  // Permit access to mount points from internal WebUI.
  const GURL& origin_url = url.origin();
  if (origin_url.SchemeIs(kChromeUIScheme))
    return true;

  // No extra check is needed for isolated file systems.
  if (url.mount_type() == fileapi::kFileSystemTypeIsolated)
    return true;

  if (!CanHandleURL(url))
    return false;

  std::string extension_id = origin_url.host();
  // Check first to make sure this extension has fileBrowserHander permissions.
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return false;

  return file_access_permissions_->HasAccessPermission(extension_id,
                                                       url.virtual_path());
}

void CrosMountPointProvider::GrantFullAccessToExtension(
    const std::string& extension_id) {
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;

  std::vector<fileapi::MountPoints::MountPointInfo> files;
  mount_points_->AddMountPointInfosTo(&files);
  system_mount_points_->AddMountPointInfosTo(&files);

  for (size_t i = 0; i < files.size(); ++i) {
    file_access_permissions_->GrantAccessPermission(
        extension_id,
        base::FilePath::FromUTF8Unsafe(files[i].name));
  }
}

void CrosMountPointProvider::GrantFileAccessToExtension(
    const std::string& extension_id, const base::FilePath& virtual_path) {
  // All we care about here is access from extensions for now.
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;

  std::string id;
  fileapi::FileSystemType type;
  base::FilePath path;
  if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &path) &&
      !system_mount_points_->CrackVirtualPath(virtual_path,
                                              &id, &type, &path)) {
    return;
  }

  if (type == fileapi::kFileSystemTypeRestrictedNativeLocal) {
    LOG(ERROR) << "Can't grant access for restricted mount point";
    return;
  }

  file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
}

void CrosMountPointProvider::RevokeAccessForExtension(
      const std::string& extension_id) {
  file_access_permissions_->RevokePermissions(extension_id);
}

std::vector<base::FilePath> CrosMountPointProvider::GetRootDirectories() const {
  std::vector<fileapi::MountPoints::MountPointInfo> mount_points;
  mount_points_->AddMountPointInfosTo(&mount_points);
  system_mount_points_->AddMountPointInfosTo(&mount_points);

  std::vector<base::FilePath> root_dirs;
  for (size_t i = 0; i < mount_points.size(); ++i)
    root_dirs.push_back(mount_points[i].path);
  return root_dirs;
}

fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
    fileapi::FileSystemType type) {
  DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
         type == fileapi::kFileSystemTypeRestrictedNativeLocal);
  return local_file_util_->sync_file_util();
}

fileapi::AsyncFileUtil* CrosMountPointProvider::GetAsyncFileUtil(
    fileapi::FileSystemType type) {
  DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
         type == fileapi::kFileSystemTypeRestrictedNativeLocal);
  return local_file_util_.get();
}

fileapi::CopyOrMoveFileValidatorFactory*
CrosMountPointProvider::GetCopyOrMoveFileValidatorFactory(
    fileapi::FileSystemType type, base::PlatformFileError* error_code) {
  DCHECK(error_code);
  *error_code = base::PLATFORM_FILE_OK;
  return NULL;
}

void CrosMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
    fileapi::FileSystemType type,
    scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
  DCHECK(!factory);
}

fileapi::FilePermissionPolicy CrosMountPointProvider::GetPermissionPolicy(
    const fileapi::FileSystemURL& url, int permissions) const {
  if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal &&
      (permissions & ~fileapi::kReadFilePermissions)) {
    // Restricted file system is read-only.
    return fileapi::FILE_PERMISSION_ALWAYS_DENY;
  }

  if (!IsAccessAllowed(url))
    return fileapi::FILE_PERMISSION_ALWAYS_DENY;

  // Permit access to mount points from internal WebUI.
  const GURL& origin_url = url.origin();
  if (origin_url.SchemeIs(kChromeUIScheme))
    return fileapi::FILE_PERMISSION_ALWAYS_ALLOW;

  if (url.mount_type() == fileapi::kFileSystemTypeIsolated) {
    // Permissions in isolated filesystems should be examined with
    // FileSystem permission.
    return fileapi::FILE_PERMISSION_USE_FILESYSTEM_PERMISSION;
  }

  // Also apply system's file permission by default.
  return fileapi::FILE_PERMISSION_USE_FILE_PERMISSION;
}

fileapi::FileSystemOperation* CrosMountPointProvider::CreateFileSystemOperation(
    const fileapi::FileSystemURL& url,
    fileapi::FileSystemContext* context,
    base::PlatformFileError* error_code) const {
  DCHECK(url.is_valid());

  if (url.type() == fileapi::kFileSystemTypeDrive) {
    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
        GetRemoteProxy(url.filesystem_id());
    if (!remote_proxy) {
      *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND;
      return NULL;
    }
    return new chromeos::RemoteFileSystemOperation(remote_proxy);
  }

  DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal ||
         url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal);
  scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
      new fileapi::FileSystemOperationContext(context));
  return new fileapi::LocalFileSystemOperation(context,
                                               operation_context.Pass());
}

scoped_ptr<webkit_blob::FileStreamReader>
CrosMountPointProvider::CreateFileStreamReader(
    const fileapi::FileSystemURL& url,
    int64 offset,
    const base::Time& expected_modification_time,
    fileapi::FileSystemContext* context) const {
  DCHECK(url.is_valid());

  if (url.type() == fileapi::kFileSystemTypeDrive) {
    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
        GetRemoteProxy(url.filesystem_id());
    if (!remote_proxy)
      return scoped_ptr<webkit_blob::FileStreamReader>();
    return remote_proxy->CreateFileStreamReader(
        context->task_runners()->file_task_runner(),
        url, offset, expected_modification_time);
  }

  return scoped_ptr<webkit_blob::FileStreamReader>(
      new fileapi::FileSystemFileStreamReader(
          context, url, offset, expected_modification_time));
}

scoped_ptr<fileapi::FileStreamWriter>
CrosMountPointProvider::CreateFileStreamWriter(
    const fileapi::FileSystemURL& url,
    int64 offset,
    fileapi::FileSystemContext* context) const {
  DCHECK(url.is_valid());

  if (url.type() == fileapi::kFileSystemTypeDrive) {
    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
        GetRemoteProxy(url.filesystem_id());
    if (!remote_proxy)
      return scoped_ptr<fileapi::FileStreamWriter>();
    return scoped_ptr<fileapi::FileStreamWriter>(
        new fileapi::RemoteFileStreamWriter(remote_proxy, url, offset));
  }

  if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal)
    return scoped_ptr<fileapi::FileStreamWriter>();

  DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
  return scoped_ptr<fileapi::FileStreamWriter>(
      new fileapi::LocalFileStreamWriter(url.path(), offset));
}

bool CrosMountPointProvider::GetVirtualPath(
    const base::FilePath& filesystem_path,
    base::FilePath* virtual_path) {
  return mount_points_->GetVirtualPath(filesystem_path, virtual_path) ||
         system_mount_points_->GetVirtualPath(filesystem_path, virtual_path);
}

fileapi::RemoteFileSystemProxyInterface* CrosMountPointProvider::GetRemoteProxy(
    const std::string& mount_name) const {
  fileapi::RemoteFileSystemProxyInterface* proxy =
      mount_points_->GetRemoteFileSystemProxy(mount_name);
  if (proxy)
    return proxy;
  return system_mount_points_->GetRemoteFileSystemProxy(mount_name);
}

}  // namespace chromeos
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "webkit/chromeos/fileapi/cros_mount_point_provider.h"

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/utf_string_conversions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFileSystem.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "webkit/chromeos/fileapi/file_access_permissions.h"
#include "webkit/chromeos/fileapi/remote_file_system_operation.h"
#include "webkit/fileapi/file_system_operation.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/native_file_util.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const char kChromeUIScheme[] = "chrome";

// Top level file system elements exposed in FileAPI in ChromeOS:
// TODO(zelidrag): Move fixed mount path initialization out of webkit layer.
struct LocalMountPointInfo {
  const char* const web_root_path;
  const char* const local_root_path;
  chromeos::CrosMountPointProvider::FileSystemLocation location;
};

const LocalMountPointInfo kFixedExposedPaths[] = {
    {"Downloads",
     "/home/chronos/user/",
     chromeos::CrosMountPointProvider::LOCAL},
    {"archive",
     "/media",
     chromeos::CrosMountPointProvider::LOCAL},
    {"removable",
      "/media",
      chromeos::CrosMountPointProvider::LOCAL},
};

}

namespace chromeos {

CrosMountPointProvider::MountPoint::MountPoint(
    const FilePath& in_web_root_path,
    const FilePath& in_local_root_path,
    FileSystemLocation in_location,
    fileapi::RemoteFileSystemProxyInterface* in_proxy)
        : web_root_path(in_web_root_path), local_root_path(in_local_root_path),
          location(in_location), remote_proxy(in_proxy) {
}

CrosMountPointProvider::MountPoint::~MountPoint() {
}

CrosMountPointProvider::CrosMountPointProvider(
    scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy)
    : special_storage_policy_(special_storage_policy),
      file_access_permissions_(new FileAccessPermissions()),
      local_file_util_(
          new fileapi::LocalFileUtil(new fileapi::NativeFileUtil())) {
  for (size_t i = 0; i < arraysize(kFixedExposedPaths); i++) {
    mount_point_map_.insert(std::make_pair(
        std::string(kFixedExposedPaths[i].web_root_path),
        MountPoint(
            FilePath(std::string(kFixedExposedPaths[i].web_root_path)),
            FilePath(std::string(kFixedExposedPaths[i].local_root_path)),
            kFixedExposedPaths[i].location,
            NULL)));
  }
}

CrosMountPointProvider::~CrosMountPointProvider() {
}

bool CrosMountPointProvider::GetRootForVirtualPath(
    const FilePath& virtual_path, FilePath* root_path) {
  const MountPoint* mount_point = GetMountPoint(virtual_path);
  if (!mount_point)
    return false;

  DCHECK(root_path);
  *root_path = mount_point->local_root_path;
  return true;
}

void CrosMountPointProvider::ValidateFileSystemRoot(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    bool create,
    const ValidateFileSystemCallback& callback) {
  // Nothing to validate for external filesystem.
  DCHECK(type == fileapi::kFileSystemTypeExternal);
  callback.Run(base::PLATFORM_FILE_OK);
}

FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    const FilePath& virtual_path,
    bool create) {
  DCHECK(type == fileapi::kFileSystemTypeExternal);
  FilePath root_path;
  if (!GetRootForVirtualPath(virtual_path, &root_path))
    return FilePath();

  return root_path;
}

bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url,
                                             fileapi::FileSystemType type,
                                             const FilePath& virtual_path) {
  if (type != fileapi::kFileSystemTypeExternal)
    return false;

  // Permit access to mount points from internal WebUI.
  if (origin_url.SchemeIs(kChromeUIScheme))
    return true;

  std::string extension_id = origin_url.host();
  // Check first to make sure this extension has fileBrowserHander permissions.
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return false;

  return file_access_permissions_->HasAccessPermission(extension_id,
                                                       virtual_path);
}

// TODO(zelidrag): Share this code with SandboxMountPointProvider impl.
bool CrosMountPointProvider::IsRestrictedFileName(const FilePath& path) const {
  return false;
}

bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) {
  base::AutoLock locker(mount_point_map_lock_);
  MountPointMap::const_iterator iter = mount_point_map_.find(
      mount_point.BaseName().value());
  DCHECK(iter == mount_point_map_.end() ||
         iter->second.local_root_path == mount_point.DirName());
  return iter != mount_point_map_.end();
}

void CrosMountPointProvider::AddLocalMountPoint(const FilePath& mount_point) {
  base::AutoLock locker(mount_point_map_lock_);
  mount_point_map_.erase(mount_point.BaseName().value());
  mount_point_map_.insert(std::make_pair(
      mount_point.BaseName().value(),
      MountPoint(mount_point.BaseName(),
                 mount_point.DirName(),
                 LOCAL,
                 NULL)));
}

void CrosMountPointProvider::AddRemoteMountPoint(
    const FilePath& mount_point,
    fileapi::RemoteFileSystemProxyInterface* remote_proxy) {
  DCHECK(remote_proxy);
  base::AutoLock locker(mount_point_map_lock_);
  mount_point_map_.erase(mount_point.BaseName().value());
  mount_point_map_.insert(std::make_pair(
      mount_point.BaseName().value(),
      MountPoint(mount_point.BaseName(),
                 mount_point.DirName(),
                 REMOTE,
                 remote_proxy)));
}

void CrosMountPointProvider::RemoveMountPoint(const FilePath& mount_point) {
  base::AutoLock locker(mount_point_map_lock_);
  mount_point_map_.erase(mount_point.BaseName().value());
}

void CrosMountPointProvider::GrantFullAccessToExtension(
    const std::string& extension_id) {
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;
  for (MountPointMap::const_iterator iter = mount_point_map_.begin();
       iter != mount_point_map_.end();
       ++iter) {
    GrantFileAccessToExtension(extension_id, FilePath(iter->first));
  }
}

void CrosMountPointProvider::GrantFileAccessToExtension(
    const std::string& extension_id, const FilePath& virtual_path) {
  // All we care about here is access from extensions for now.
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;
  file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
}

void CrosMountPointProvider::RevokeAccessForExtension(
      const std::string& extension_id) {
  file_access_permissions_->RevokePermissions(extension_id);
}

std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const {
  std::vector<FilePath> root_dirs;
  for (MountPointMap::const_iterator iter = mount_point_map_.begin();
       iter != mount_point_map_.end();
       ++iter) {
    root_dirs.push_back(iter->second.local_root_path.Append(iter->first));
  }
  return root_dirs;
}

fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil() {
  return local_file_util_.get();
}

FilePath CrosMountPointProvider::GetPathForPermissionsCheck(
    const FilePath& virtual_path) const {
  const MountPoint* mount_point = GetMountPoint(virtual_path);
  if (!mount_point)
    return FilePath();

  FilePath root_path = mount_point->local_root_path;

  return root_path.Append(virtual_path);
}

const CrosMountPointProvider::MountPoint*
CrosMountPointProvider::GetMountPoint(const FilePath& virtual_path) const {
  std::vector<FilePath::StringType> components;
  virtual_path.GetComponents(&components);
  if (components.empty())
    return NULL;

  base::AutoLock locker(
      const_cast<CrosMountPointProvider*>(this)->mount_point_map_lock_);
  // Check if this root mount point is exposed by this provider.
  MountPointMap::const_iterator iter = mount_point_map_.find(components[0]);
  if (iter == mount_point_map_.end())
    return NULL;

  return &(iter->second);
}

fileapi::FileSystemOperationInterface*
CrosMountPointProvider::CreateFileSystemOperation(
    const GURL& origin_url,
    fileapi::FileSystemType file_system_type,
    const FilePath& virtual_path,
    base::MessageLoopProxy* file_proxy,
    fileapi::FileSystemContext* context) const {
  const MountPoint* mount_point = GetMountPoint(virtual_path);
  if (mount_point && mount_point->location == REMOTE)
    return new chromeos::RemoteFileSystemOperation(mount_point->remote_proxy);

  return new fileapi::FileSystemOperation(file_proxy, context);
}

bool CrosMountPointProvider::GetVirtualPath(const FilePath& filesystem_path,
                                           FilePath* virtual_path) {
  for (MountPointMap::const_iterator iter = mount_point_map_.begin();
       iter != mount_point_map_.end();
       ++iter) {
    FilePath mount_prefix = iter->second.local_root_path.Append(iter->first);
    *virtual_path = FilePath(iter->first);
    if (mount_prefix == filesystem_path) {
      return true;
    } else if (mount_prefix.AppendRelativePath(filesystem_path, virtual_path)) {
      return true;
    }
  }
  return false;
}

}  // namespace chromeos
<commit_msg>chromeos: Do not peek at /home/chronos/user/Downloads<commit_after>// Copyright (c) 2012 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 "webkit/chromeos/fileapi/cros_mount_point_provider.h"

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/utf_string_conversions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFileSystem.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "webkit/chromeos/fileapi/file_access_permissions.h"
#include "webkit/chromeos/fileapi/remote_file_system_operation.h"
#include "webkit/fileapi/file_system_operation.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/native_file_util.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const char kChromeUIScheme[] = "chrome";

// Copied from chrome/browser/chromeos/system/runtime_environment.h
// TODO(satorux): oshima is now moving the function to 'base/chromeos'.
// Use the one in 'base/chromeos' once it's done.
bool IsRunningOnChromeOS() {
  // Check if the user name is chronos. Note that we don't go with
  // getuid() + getpwuid_r() as it may end up reading /etc/passwd, which
  // can be expensive.
  const char* user = getenv("USER");
  return user && strcmp(user, "chronos") == 0;
}

// Returns the home directory path, or an empty string if the home directory
// is not found.
std::string GetHomeDirectory() {
  if (IsRunningOnChromeOS())
    return "/home/chronos/user";

  const char* home = getenv("HOME");
  if (home)
    return home;
  return "";
}

}  // namespace

namespace chromeos {

CrosMountPointProvider::MountPoint::MountPoint(
    const FilePath& in_web_root_path,
    const FilePath& in_local_root_path,
    FileSystemLocation in_location,
    fileapi::RemoteFileSystemProxyInterface* in_proxy)
        : web_root_path(in_web_root_path), local_root_path(in_local_root_path),
          location(in_location), remote_proxy(in_proxy) {
}

CrosMountPointProvider::MountPoint::~MountPoint() {
}

CrosMountPointProvider::CrosMountPointProvider(
    scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy)
    : special_storage_policy_(special_storage_policy),
      file_access_permissions_(new FileAccessPermissions()),
      local_file_util_(
          new fileapi::LocalFileUtil(new fileapi::NativeFileUtil())) {
  const std::string home = GetHomeDirectory();
  if (!home.empty()) {
    AddLocalMountPoint(
        FilePath::FromUTF8Unsafe(home).AppendASCII("Downloads"));
  }
  AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/archive")));
  AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/removable")));
}

CrosMountPointProvider::~CrosMountPointProvider() {
}

bool CrosMountPointProvider::GetRootForVirtualPath(
    const FilePath& virtual_path, FilePath* root_path) {
  const MountPoint* mount_point = GetMountPoint(virtual_path);
  if (!mount_point)
    return false;

  DCHECK(root_path);
  *root_path = mount_point->local_root_path;
  return true;
}

void CrosMountPointProvider::ValidateFileSystemRoot(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    bool create,
    const ValidateFileSystemCallback& callback) {
  // Nothing to validate for external filesystem.
  DCHECK(type == fileapi::kFileSystemTypeExternal);
  callback.Run(base::PLATFORM_FILE_OK);
}

FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
    const GURL& origin_url,
    fileapi::FileSystemType type,
    const FilePath& virtual_path,
    bool create) {
  DCHECK(type == fileapi::kFileSystemTypeExternal);
  FilePath root_path;
  if (!GetRootForVirtualPath(virtual_path, &root_path))
    return FilePath();

  return root_path;
}

bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url,
                                             fileapi::FileSystemType type,
                                             const FilePath& virtual_path) {
  if (type != fileapi::kFileSystemTypeExternal)
    return false;

  // Permit access to mount points from internal WebUI.
  if (origin_url.SchemeIs(kChromeUIScheme))
    return true;

  std::string extension_id = origin_url.host();
  // Check first to make sure this extension has fileBrowserHander permissions.
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return false;

  return file_access_permissions_->HasAccessPermission(extension_id,
                                                       virtual_path);
}

// TODO(zelidrag): Share this code with SandboxMountPointProvider impl.
bool CrosMountPointProvider::IsRestrictedFileName(const FilePath& path) const {
  return false;
}

bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) {
  base::AutoLock locker(mount_point_map_lock_);
  MountPointMap::const_iterator iter = mount_point_map_.find(
      mount_point.BaseName().value());
  DCHECK(iter == mount_point_map_.end() ||
         iter->second.local_root_path == mount_point.DirName());
  return iter != mount_point_map_.end();
}

void CrosMountPointProvider::AddLocalMountPoint(const FilePath& mount_point) {
  base::AutoLock locker(mount_point_map_lock_);
  mount_point_map_.erase(mount_point.BaseName().value());
  mount_point_map_.insert(std::make_pair(
      mount_point.BaseName().value(),
      MountPoint(mount_point.BaseName(),
                 mount_point.DirName(),
                 LOCAL,
                 NULL)));
}

void CrosMountPointProvider::AddRemoteMountPoint(
    const FilePath& mount_point,
    fileapi::RemoteFileSystemProxyInterface* remote_proxy) {
  DCHECK(remote_proxy);
  base::AutoLock locker(mount_point_map_lock_);
  mount_point_map_.erase(mount_point.BaseName().value());
  mount_point_map_.insert(std::make_pair(
      mount_point.BaseName().value(),
      MountPoint(mount_point.BaseName(),
                 mount_point.DirName(),
                 REMOTE,
                 remote_proxy)));
}

void CrosMountPointProvider::RemoveMountPoint(const FilePath& mount_point) {
  base::AutoLock locker(mount_point_map_lock_);
  mount_point_map_.erase(mount_point.BaseName().value());
}

void CrosMountPointProvider::GrantFullAccessToExtension(
    const std::string& extension_id) {
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;
  for (MountPointMap::const_iterator iter = mount_point_map_.begin();
       iter != mount_point_map_.end();
       ++iter) {
    GrantFileAccessToExtension(extension_id, FilePath(iter->first));
  }
}

void CrosMountPointProvider::GrantFileAccessToExtension(
    const std::string& extension_id, const FilePath& virtual_path) {
  // All we care about here is access from extensions for now.
  DCHECK(special_storage_policy_->IsFileHandler(extension_id));
  if (!special_storage_policy_->IsFileHandler(extension_id))
    return;
  file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
}

void CrosMountPointProvider::RevokeAccessForExtension(
      const std::string& extension_id) {
  file_access_permissions_->RevokePermissions(extension_id);
}

std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const {
  std::vector<FilePath> root_dirs;
  for (MountPointMap::const_iterator iter = mount_point_map_.begin();
       iter != mount_point_map_.end();
       ++iter) {
    root_dirs.push_back(iter->second.local_root_path.Append(iter->first));
  }
  return root_dirs;
}

fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil() {
  return local_file_util_.get();
}

FilePath CrosMountPointProvider::GetPathForPermissionsCheck(
    const FilePath& virtual_path) const {
  const MountPoint* mount_point = GetMountPoint(virtual_path);
  if (!mount_point)
    return FilePath();

  FilePath root_path = mount_point->local_root_path;

  return root_path.Append(virtual_path);
}

const CrosMountPointProvider::MountPoint*
CrosMountPointProvider::GetMountPoint(const FilePath& virtual_path) const {
  std::vector<FilePath::StringType> components;
  virtual_path.GetComponents(&components);
  if (components.empty())
    return NULL;

  base::AutoLock locker(
      const_cast<CrosMountPointProvider*>(this)->mount_point_map_lock_);
  // Check if this root mount point is exposed by this provider.
  MountPointMap::const_iterator iter = mount_point_map_.find(components[0]);
  if (iter == mount_point_map_.end())
    return NULL;

  return &(iter->second);
}

fileapi::FileSystemOperationInterface*
CrosMountPointProvider::CreateFileSystemOperation(
    const GURL& origin_url,
    fileapi::FileSystemType file_system_type,
    const FilePath& virtual_path,
    base::MessageLoopProxy* file_proxy,
    fileapi::FileSystemContext* context) const {
  const MountPoint* mount_point = GetMountPoint(virtual_path);
  if (mount_point && mount_point->location == REMOTE)
    return new chromeos::RemoteFileSystemOperation(mount_point->remote_proxy);

  return new fileapi::FileSystemOperation(file_proxy, context);
}

bool CrosMountPointProvider::GetVirtualPath(const FilePath& filesystem_path,
                                           FilePath* virtual_path) {
  for (MountPointMap::const_iterator iter = mount_point_map_.begin();
       iter != mount_point_map_.end();
       ++iter) {
    FilePath mount_prefix = iter->second.local_root_path.Append(iter->first);
    *virtual_path = FilePath(iter->first);
    if (mount_prefix == filesystem_path) {
      return true;
    } else if (mount_prefix.AppendRelativePath(filesystem_path, virtual_path)) {
      return true;
    }
  }
  return false;
}

}  // namespace chromeos
<|endoftext|>


<commit_before>/*
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

    ---
    Copyright (C) 2004, Anders Lund <anders@alweb.dk>
*/

#include "katemwmodonhddialog.h"
#include "katemwmodonhddialog.moc"

#include "katedocmanager.h"

#include <KLocale>
#include <KMessageBox>
#include <kprocess.h>
#include <KRun>
#include <KTemporaryFile>
#include <KPushButton>
#include <KVBox>

#include <QLabel>
#include <QPushButton>
#include <QTextStream>

class KateDocItem : public QTreeWidgetItem
{
  public:
    KateDocItem( KTextEditor::Document *doc, const QString &status, QTreeWidget *tw )
        : QTreeWidgetItem( tw ),
        document( doc )
    {
      setText( 0, doc->url().prettyUrl() );
      setText( 1, status );
      if ( ! doc->isModified() )
        setCheckState( 0, Qt::Checked );
      else
        setCheckState( 0, Qt::Unchecked );
    }
    ~KateDocItem()
  {}

    KTextEditor::Document *document;
};

KateMwModOnHdDialog::KateMwModOnHdDialog( DocVector docs, QWidget *parent, const char *name )
    : KDialog( parent ),
      m_proc( 0 ),
      m_diffFile( 0 )
{
  setCaption( i18n("Documents Modified on Disk") );
  setButtons( User1 | User2 | User3 );
  setButtonGuiItem( User1, KGuiItem (i18n("&Ignore"), "window-close") );
  setButtonGuiItem( User2, KStandardGuiItem::overwrite() );
  setButtonGuiItem( User3, KGuiItem (i18n("&Reload"), "view-refresh") );

  setObjectName( name );
  setModal( true );
  setDefaultButton( KDialog::User3 );

  setButtonWhatsThis( User1, i18n(
                        "Removes the modified flag from the selected documents and closes the "
                        "dialog if there are no more unhandled documents.") );
  setButtonWhatsThis( User2, i18n(
                        "Overwrite selected documents, discarding the disk changes and closes the "
                        "dialog if there are no more unhandled documents.") );
  setButtonWhatsThis( User3, i18n(
                        "Reloads the selected documents from disk and closes the dialog if there "
                        "are no more unhandled documents.") );

  KVBox *w = new KVBox( this );
  setMainWidget( w );
  w->setSpacing( KDialog::spacingHint() );

  KHBox *lo1 = new KHBox( w );

  // dialog text
  QLabel *icon = new QLabel( lo1 );
  icon->setPixmap( DesktopIcon("dialog-warning") );

  QLabel *t = new QLabel( i18n(
                            "<qt>The documents listed below have changed on disk.
Select one "
                            "or more at the time and press an action button until the list is empty.
</qt>"), lo1 );
  lo1->setStretchFactor( t, 1000 );

  // document list
  twDocuments = new QTreeWidget( w );
  QStringList header;
  header << i18n("Filename") << i18n("Status on Disk");
  twDocuments->setHeaderLabels(header);
  twDocuments->setSelectionMode( QAbstractItemView::SingleSelection );

  QStringList l;
  l << "" << i18n("Modified") << i18n("Created") << i18n("Deleted");
  for ( uint i = 0; i < docs.size(); i++ )
  {
    new KateDocItem( docs[i], l[ (uint)KateDocManager::self()->documentInfo( docs[i] )->modifiedOnDiscReason ], twDocuments );
  }

  connect( twDocuments, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(slotSelectionChanged(QTreeWidgetItem *, QTreeWidgetItem *)) );

  // diff button
  KHBox *lo2 = new KHBox ( w );
  QWidget *d = new QWidget (lo2);
  lo2->setStretchFactor (d, 2);
  btnDiff = new KPushButton( KGuiItem (i18n("&View Difference"), "object-edit"), lo2 );

  btnDiff->setWhatsThis(i18n(
                          "Calculates the difference between the the editor contents and the disk "
                          "file for the selected document, and shows the difference with the "
                          "default application. Requires diff(1).") );
  connect( btnDiff, SIGNAL(clicked()), this, SLOT(slotDiff()) );
  connect( this, SIGNAL(user1Clicked()), this, SLOT(slotUser1()) );
  connect( this, SIGNAL(user2Clicked()), this, SLOT(slotUser2()) );
  connect( this, SIGNAL(user3Clicked()), this, SLOT(slotUser3()) );

  slotSelectionChanged(NULL, NULL);
}

KateMwModOnHdDialog::~KateMwModOnHdDialog()
{
  delete m_proc;
  m_proc = 0;
  if (m_diffFile) {
    m_diffFile->setAutoRemove(true);
    delete m_diffFile;
    m_diffFile = 0;
  }
}

void KateMwModOnHdDialog::slotUser1()
{
  handleSelected( Ignore );
}

void KateMwModOnHdDialog::slotUser2()
{
  handleSelected( Overwrite );
}

void KateMwModOnHdDialog::slotUser3()
{
  handleSelected( Reload );
}

void KateMwModOnHdDialog::handleSelected( int action )
{
  // collect all items we can remove
  QList<QTreeWidgetItem *> itemsToDelete;
  for ( QTreeWidgetItemIterator it ( twDocuments ); *it; ++it )
  {
    KateDocItem *item = (KateDocItem *) * it;
    if ( item->checkState(0) == Qt::Checked )
    {
      KTextEditor::ModificationInterface::ModifiedOnDiskReason reason = KateDocManager::self()->documentInfo( item->document )->modifiedOnDiscReason;
      bool success = true;

      if (KTextEditor::ModificationInterface *iface = qobject_cast<KTextEditor::ModificationInterface *>(item->document))
        iface->setModifiedOnDisk( KTextEditor::ModificationInterface::OnDiskUnmodified );

      switch ( action )
      {
        case Overwrite:
          success = item->document->save();
          if ( ! success )
          {
            KMessageBox::sorry( this,
                                i18n("Could not save the document \n'%1'",
                                     item->document->url().prettyUrl() ) );
          }
          break;

        case Reload:
          item->document->documentReload();
          break;

        default:
          break;
      }

      if ( success )
        itemsToDelete.append( item );
      else
      {
        if (KTextEditor::ModificationInterface *iface = qobject_cast<KTextEditor::ModificationInterface *>(item->document))
          iface->setModifiedOnDisk( reason );
      }
    }
  }

  // remove the marked items
  for (int i = 0; i < itemsToDelete.count(); ++i)
    delete itemsToDelete[i];

// any documents left unhandled?
  if ( ! twDocuments->topLevelItemCount() )
    done( Ok );
}

void KateMwModOnHdDialog::slotSelectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
{
  // set the diff button enabled
  btnDiff->setEnabled( current &&
                       KateDocManager::self()->documentInfo( ((KateDocItem*)current)->document )->modifiedOnDiscReason != KTextEditor::ModificationInterface::OnDiskDeleted );
}

// ### the code below is slightly modified from kdelibs/kate/part/katedialogs,
// class KateModOnHdPrompt.
void KateMwModOnHdDialog::slotDiff()
{
  if ( !btnDiff->isEnabled()) // diff button already pressed, proc not finished yet
    return;

  if ( ! twDocuments->currentItem() )
    return;

  KTextEditor::Document *doc = ((KateDocItem*)twDocuments->currentItem())->document;

  // don't try to diff a deleted file
  if ( KateDocManager::self()->documentInfo( doc )->modifiedOnDiscReason == KTextEditor::ModificationInterface::OnDiskDeleted )
    return;

  if (m_diffFile)
    return;

  m_diffFile = new KTemporaryFile();
  m_diffFile->open();

  // Start a KProcess that creates a diff
  m_proc = new KProcess( this );
  m_proc->setOutputChannelMode( KProcess::MergedChannels );
  *m_proc << "diff" << "-ub" << "-" << doc->url().path();
  connect( m_proc, SIGNAL(readyRead()), this, SLOT(slotDataAvailable()) );
  connect( m_proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotPDone()) );

  setCursor( Qt::WaitCursor );
  btnDiff->setEnabled(false);

  m_proc->start();

  QTextStream ts(m_proc);
  int lastln = doc->lines();
  for ( int l = 0; l < lastln; ++l )
    ts << doc->line( l ) << '\n';
  ts.flush();
  m_proc->closeWriteChannel();
}

void KateMwModOnHdDialog::slotDataAvailable()
{
  m_diffFile->write(m_proc->readAll());
}

void KateMwModOnHdDialog::slotPDone()
{
  setCursor( Qt::ArrowCursor );
  slotSelectionChanged(twDocuments->currentItem(), 0);

  const QProcess::ExitStatus es = m_proc->exitStatus();
  delete m_proc;
  m_proc = 0;

  if ( es != QProcess::NormalExit )
  {
    KMessageBox::sorry( this,
                        i18n("The diff command failed. Please make sure that "
                             "diff(1) is installed and in your PATH."),
                        i18n("Error Creating Diff") );
    delete m_diffFile;
    m_diffFile = 0;
    return;
  }

  if ( m_diffFile->size() == 0 )
  {
    KMessageBox::information( this,
                              i18n("Besides white space changes, the files are identical."),
                              i18n("Diff Output") );
    delete m_diffFile;
    m_diffFile = 0;
    return;
  }

  m_diffFile->setAutoRemove(false);
  KUrl url = KUrl::fromPath(m_diffFile->fileName());
  delete m_diffFile;
  m_diffFile = 0;

  // KRun::runUrl should delete the file, once the client exits
  KRun::runUrl( url, "text/x-patch", this, true );
}

// kate: space-indent on; indent-width 2; replace-tabs on;
<commit_msg>Icon naming spec compliance (code changes - KDE/): object-edit -> document-properties and only a few other bits.<commit_after>/*
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

    ---
    Copyright (C) 2004, Anders Lund <anders@alweb.dk>
*/

#include "katemwmodonhddialog.h"
#include "katemwmodonhddialog.moc"

#include "katedocmanager.h"

#include <KLocale>
#include <KMessageBox>
#include <kprocess.h>
#include <KRun>
#include <KTemporaryFile>
#include <KPushButton>
#include <KVBox>

#include <QLabel>
#include <QPushButton>
#include <QTextStream>

class KateDocItem : public QTreeWidgetItem
{
  public:
    KateDocItem( KTextEditor::Document *doc, const QString &status, QTreeWidget *tw )
        : QTreeWidgetItem( tw ),
        document( doc )
    {
      setText( 0, doc->url().prettyUrl() );
      setText( 1, status );
      if ( ! doc->isModified() )
        setCheckState( 0, Qt::Checked );
      else
        setCheckState( 0, Qt::Unchecked );
    }
    ~KateDocItem()
  {}

    KTextEditor::Document *document;
};

KateMwModOnHdDialog::KateMwModOnHdDialog( DocVector docs, QWidget *parent, const char *name )
    : KDialog( parent ),
      m_proc( 0 ),
      m_diffFile( 0 )
{
  setCaption( i18n("Documents Modified on Disk") );
  setButtons( User1 | User2 | User3 );
  setButtonGuiItem( User1, KGuiItem (i18n("&Ignore"), "window-close") );
  setButtonGuiItem( User2, KStandardGuiItem::overwrite() );
  setButtonGuiItem( User3, KGuiItem (i18n("&Reload"), "view-refresh") );

  setObjectName( name );
  setModal( true );
  setDefaultButton( KDialog::User3 );

  setButtonWhatsThis( User1, i18n(
                        "Removes the modified flag from the selected documents and closes the "
                        "dialog if there are no more unhandled documents.") );
  setButtonWhatsThis( User2, i18n(
                        "Overwrite selected documents, discarding the disk changes and closes the "
                        "dialog if there are no more unhandled documents.") );
  setButtonWhatsThis( User3, i18n(
                        "Reloads the selected documents from disk and closes the dialog if there "
                        "are no more unhandled documents.") );

  KVBox *w = new KVBox( this );
  setMainWidget( w );
  w->setSpacing( KDialog::spacingHint() );

  KHBox *lo1 = new KHBox( w );

  // dialog text
  QLabel *icon = new QLabel( lo1 );
  icon->setPixmap( DesktopIcon("dialog-warning") );

  QLabel *t = new QLabel( i18n(
                            "<qt>The documents listed below have changed on disk.
Select one "
                            "or more at the time and press an action button until the list is empty.
</qt>"), lo1 );
  lo1->setStretchFactor( t, 1000 );

  // document list
  twDocuments = new QTreeWidget( w );
  QStringList header;
  header << i18n("Filename") << i18n("Status on Disk");
  twDocuments->setHeaderLabels(header);
  twDocuments->setSelectionMode( QAbstractItemView::SingleSelection );

  QStringList l;
  l << "" << i18n("Modified") << i18n("Created") << i18n("Deleted");
  for ( uint i = 0; i < docs.size(); i++ )
  {
    new KateDocItem( docs[i], l[ (uint)KateDocManager::self()->documentInfo( docs[i] )->modifiedOnDiscReason ], twDocuments );
  }

  connect( twDocuments, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(slotSelectionChanged(QTreeWidgetItem *, QTreeWidgetItem *)) );

  // diff button
  KHBox *lo2 = new KHBox ( w );
  QWidget *d = new QWidget (lo2);
  lo2->setStretchFactor (d, 2);
  btnDiff = new KPushButton( KGuiItem (i18n("&View Difference"), "document-preview"), lo2 );

  btnDiff->setWhatsThis(i18n(
                          "Calculates the difference between the the editor contents and the disk "
                          "file for the selected document, and shows the difference with the "
                          "default application. Requires diff(1).") );
  connect( btnDiff, SIGNAL(clicked()), this, SLOT(slotDiff()) );
  connect( this, SIGNAL(user1Clicked()), this, SLOT(slotUser1()) );
  connect( this, SIGNAL(user2Clicked()), this, SLOT(slotUser2()) );
  connect( this, SIGNAL(user3Clicked()), this, SLOT(slotUser3()) );

  slotSelectionChanged(NULL, NULL);
}

KateMwModOnHdDialog::~KateMwModOnHdDialog()
{
  delete m_proc;
  m_proc = 0;
  if (m_diffFile) {
    m_diffFile->setAutoRemove(true);
    delete m_diffFile;
    m_diffFile = 0;
  }
}

void KateMwModOnHdDialog::slotUser1()
{
  handleSelected( Ignore );
}

void KateMwModOnHdDialog::slotUser2()
{
  handleSelected( Overwrite );
}

void KateMwModOnHdDialog::slotUser3()
{
  handleSelected( Reload );
}

void KateMwModOnHdDialog::handleSelected( int action )
{
  // collect all items we can remove
  QList<QTreeWidgetItem *> itemsToDelete;
  for ( QTreeWidgetItemIterator it ( twDocuments ); *it; ++it )
  {
    KateDocItem *item = (KateDocItem *) * it;
    if ( item->checkState(0) == Qt::Checked )
    {
      KTextEditor::ModificationInterface::ModifiedOnDiskReason reason = KateDocManager::self()->documentInfo( item->document )->modifiedOnDiscReason;
      bool success = true;

      if (KTextEditor::ModificationInterface *iface = qobject_cast<KTextEditor::ModificationInterface *>(item->document))
        iface->setModifiedOnDisk( KTextEditor::ModificationInterface::OnDiskUnmodified );

      switch ( action )
      {
        case Overwrite:
          success = item->document->save();
          if ( ! success )
          {
            KMessageBox::sorry( this,
                                i18n("Could not save the document \n'%1'",
                                     item->document->url().prettyUrl() ) );
          }
          break;

        case Reload:
          item->document->documentReload();
          break;

        default:
          break;
      }

      if ( success )
        itemsToDelete.append( item );
      else
      {
        if (KTextEditor::ModificationInterface *iface = qobject_cast<KTextEditor::ModificationInterface *>(item->document))
          iface->setModifiedOnDisk( reason );
      }
    }
  }

  // remove the marked items
  for (int i = 0; i < itemsToDelete.count(); ++i)
    delete itemsToDelete[i];

// any documents left unhandled?
  if ( ! twDocuments->topLevelItemCount() )
    done( Ok );
}

void KateMwModOnHdDialog::slotSelectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
{
  // set the diff button enabled
  btnDiff->setEnabled( current &&
                       KateDocManager::self()->documentInfo( ((KateDocItem*)current)->document )->modifiedOnDiscReason != KTextEditor::ModificationInterface::OnDiskDeleted );
}

// ### the code below is slightly modified from kdelibs/kate/part/katedialogs,
// class KateModOnHdPrompt.
void KateMwModOnHdDialog::slotDiff()
{
  if ( !btnDiff->isEnabled()) // diff button already pressed, proc not finished yet
    return;

  if ( ! twDocuments->currentItem() )
    return;

  KTextEditor::Document *doc = ((KateDocItem*)twDocuments->currentItem())->document;

  // don't try to diff a deleted file
  if ( KateDocManager::self()->documentInfo( doc )->modifiedOnDiscReason == KTextEditor::ModificationInterface::OnDiskDeleted )
    return;

  if (m_diffFile)
    return;

  m_diffFile = new KTemporaryFile();
  m_diffFile->open();

  // Start a KProcess that creates a diff
  m_proc = new KProcess( this );
  m_proc->setOutputChannelMode( KProcess::MergedChannels );
  *m_proc << "diff" << "-ub" << "-" << doc->url().path();
  connect( m_proc, SIGNAL(readyRead()), this, SLOT(slotDataAvailable()) );
  connect( m_proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotPDone()) );

  setCursor( Qt::WaitCursor );
  btnDiff->setEnabled(false);

  m_proc->start();

  QTextStream ts(m_proc);
  int lastln = doc->lines();
  for ( int l = 0; l < lastln; ++l )
    ts << doc->line( l ) << '\n';
  ts.flush();
  m_proc->closeWriteChannel();
}

void KateMwModOnHdDialog::slotDataAvailable()
{
  m_diffFile->write(m_proc->readAll());
}

void KateMwModOnHdDialog::slotPDone()
{
  setCursor( Qt::ArrowCursor );
  slotSelectionChanged(twDocuments->currentItem(), 0);

  const QProcess::ExitStatus es = m_proc->exitStatus();
  delete m_proc;
  m_proc = 0;

  if ( es != QProcess::NormalExit )
  {
    KMessageBox::sorry( this,
                        i18n("The diff command failed. Please make sure that "
                             "diff(1) is installed and in your PATH."),
                        i18n("Error Creating Diff") );
    delete m_diffFile;
    m_diffFile = 0;
    return;
  }

  if ( m_diffFile->size() == 0 )
  {
    KMessageBox::information( this,
                              i18n("Besides white space changes, the files are identical."),
                              i18n("Diff Output") );
    delete m_diffFile;
    m_diffFile = 0;
    return;
  }

  m_diffFile->setAutoRemove(false);
  KUrl url = KUrl::fromPath(m_diffFile->fileName());
  delete m_diffFile;
  m_diffFile = 0;

  // KRun::runUrl should delete the file, once the client exits
  KRun::runUrl( url, "text/x-patch", this, true );
}

// kate: space-indent on; indent-width 2; replace-tabs on;
<|endoftext|>