22#include <boost/property_tree/json_parser.hpp>
24#include <com/sun/star/beans/NamedValue.hpp>
25#include <com/sun/star/beans/PropertyValue.hpp>
26#include <com/sun/star/lang/IllegalArgumentException.hpp>
27#include <com/sun/star/reflection/XIdlField.hpp>
28#include <com/sun/star/reflection/theCoreReflection.hpp>
40uno::Any jsonToUnoAny(
const boost::property_tree::ptree& aTree)
45 uno::Reference<reflection::XIdlField> aField;
46 boost::property_tree::ptree aNodeNull, aNodeValue, aNodeField;
47 const std::string& rType = aTree.get<std::string>(
"type",
"");
48 const std::string& rValue = aTree.get<std::string>(
"value",
"");
49 uno::Sequence<uno::Reference<reflection::XIdlField>> aFields;
50 uno::Reference<reflection::XIdlClass> xIdlClass
52 ->forName(OUString::fromUtf8(rType));
55 uno::TypeClass aTypeClass = xIdlClass->getTypeClass();
56 xIdlClass->createObject(aAny);
57 aFields = xIdlClass->getFields();
58 nFields = aFields.getLength();
59 aNodeValue = aTree.get_child(
"value", aNodeNull);
60 if (nFields > 0 && aNodeValue != aNodeNull)
62 for (sal_Int32 itField = 0; itField < nFields; ++itField)
64 aField = aFields[itField];
65 aNodeField = aNodeValue.get_child(aField->getName().toUtf8().getStr(), aNodeNull);
66 if (aNodeField != aNodeNull)
68 aValue = jsonToUnoAny(aNodeField);
69 aField->set(aAny, aValue);
73 else if (!rValue.empty())
75 if (aTypeClass == uno::TypeClass_VOID)
77 else if (aTypeClass == uno::TypeClass_BYTE)
79 else if (aTypeClass == uno::TypeClass_BOOLEAN)
80 aAny <<= OString(rValue).toBoolean();
81 else if (aTypeClass == uno::TypeClass_SHORT)
83 else if (aTypeClass == uno::TypeClass_UNSIGNED_SHORT)
85 else if (aTypeClass == uno::TypeClass_LONG)
87 else if (aTypeClass == uno::TypeClass_UNSIGNED_LONG)
89 else if (aTypeClass == uno::TypeClass_FLOAT)
90 aAny <<= OString(rValue).toFloat();
91 else if (aTypeClass == uno::TypeClass_DOUBLE)
93 else if (aTypeClass == uno::TypeClass_STRING)
94 aAny <<= OUString::fromUtf8(rValue);
131 if (!aSource.hasValue())
137 css::uno::Sequence< css::beans::NamedValue > lN;
144 css::uno::Sequence< css::beans::PropertyValue > lP;
151 throw css::lang::IllegalArgumentException(
152 "Any contains wrong type.", css::uno::Reference<css::uno::XInterface>(),
159 sal_Int32 c = lSource.getLength();
165 css::beans::PropertyValue lP;
166 if (lSource[
i] >>= lP)
169 (lP.Name.isEmpty()) ||
170 (!lP.Value.hasValue())
172 throw css::lang::IllegalArgumentException(
173 "PropertyValue struct contains no useful information.",
174 css::uno::Reference<css::uno::XInterface>(), -1);
175 (*this)[lP.Name] = lP.Value;
179 css::beans::NamedValue lN;
180 if (lSource[
i] >>= lN)
183 (lN.Name.isEmpty()) ||
184 (!lN.Value.hasValue())
186 throw css::lang::IllegalArgumentException(
187 "NamedValue struct contains no useful information.",
188 css::uno::Reference<css::uno::XInterface>(), -1);
189 (*this)[lN.Name] = lN.Value;
194 if (lSource[
i].hasValue())
195 throw css::lang::IllegalArgumentException(
196 "Any contains wrong type.",
197 css::uno::Reference<css::uno::XInterface>(), -1);
205 sal_Int32 c = lSource.getLength();
206 const css::beans::PropertyValue* pSource = lSource.getConstArray();
209 for (sal_Int32
i=0;
i<c; ++
i)
210 (*
this)[pSource[
i].Name] = pSource[
i].Value;
217 sal_Int32 c = lSource.getLength();
218 const css::beans::NamedValue* pSource = lSource.getConstArray();
221 for (sal_Int32
i=0;
i<c; ++
i)
222 (*
this)[pSource[
i].Name] = pSource[
i].Value;
227 sal_Int32 c =
static_cast<sal_Int32
>(
size());
228 lDestination.realloc(c);
229 css::beans::PropertyValue* pDestination = lDestination.getArray();
236 pDestination[
i].Name = pThis->first.maString;
237 pDestination[
i].Value = pThis->second;
244 sal_Int32 c =
static_cast<sal_Int32
>(
size());
245 lDestination.realloc(c);
246 css::beans::NamedValue* pDestination = lDestination.getArray();
253 pDestination[
i].Name = pThis->first.maString;
254 pDestination[
i].Value = pThis->second;
261 css::uno::Any aDestination;
262 if (bAsPropertyValueList)
271 css::uno::Sequence< css::beans::NamedValue > lReturn;
278 css::uno::Sequence< css::beans::PropertyValue > lReturn;
285 for (
auto const& elem : rCheck)
287 const OUString& sCheckName = elem.first.maString;
288 const css::uno::Any& aCheckValue = elem.second;
294 const css::uno::Any& aFoundValue = pFound->second;
295 if (aFoundValue != aCheckValue)
305 for (
auto const& elem : rUpdate.
m_aMap)
307 m_aMap[elem.first] = elem.second;
314 boost::property_tree::ptree aTree, aNodeNull, aNodeValue;
315 std::stringstream aStream((std::string(rJson)));
316 boost::property_tree::read_json(aStream, aTree);
318 for (
const auto& rPair : aTree)
320 const std::string& rType = rPair.second.get<std::string>(
"type",
"");
321 const std::string& rValue = rPair.second.get<std::string>(
"value",
"");
323 beans::PropertyValue aValue;
324 aValue.Name = OUString::fromUtf8(rPair.first);
325 if (rType ==
"string")
326 aValue.Value <<= OUString::fromUtf8(rValue);
327 else if (rType ==
"boolean")
328 aValue.Value <<= OString(rValue).toBoolean();
329 else if (rType ==
"float")
330 aValue.Value <<= OString(rValue).toFloat();
331 else if (rType ==
"long")
333 else if (rType ==
"short")
335 else if (rType ==
"unsigned short")
337 else if (rType ==
"int64")
339 else if (rType ==
"int32")
341 else if (rType ==
"int16")
343 else if (rType ==
"uint64")
344 aValue.Value <<= OString(rValue).toUInt64();
345 else if (rType ==
"uint32")
347 else if (rType ==
"uint16")
349 else if (rType ==
"[]byte")
351 aNodeValue = rPair.second.get_child(
"value", aNodeNull);
352 if (aNodeValue != aNodeNull && aNodeValue.size() == 0)
354 uno::Sequence<sal_Int8> aSeqByte(
reinterpret_cast<const sal_Int8*
>(rValue.c_str()),
356 aValue.Value <<= aSeqByte;
359 else if (rType ==
"[]any")
361 aNodeValue = rPair.second.get_child(
"value", aNodeNull);
362 if (aNodeValue != aNodeNull && !aNodeValue.empty())
364 uno::Sequence<uno::Any>
aSeq(aNodeValue.size());
365 std::transform(aNodeValue.begin(), aNodeValue.end(),
aSeq.getArray(),
366 [](
const auto& rSeqPair) { return jsonToUnoAny(rSeqPair.second); });
367 aValue.Value <<=
aSeq;
370 else if (rType ==
"[]com.sun.star.beans.PropertyValue")
372 aNodeValue = rPair.second.get_child(
"value", aNodeNull);
374 boost::property_tree::write_json(s, aNodeValue);
378 else if (rType ==
"[][]com.sun.star.beans.PropertyValue")
380 aNodeValue = rPair.second.get_child(
"value", aNodeNull);
381 std::vector<uno::Sequence<beans::PropertyValue>> aSeqs;
382 for (
const auto& rItem : aNodeValue)
385 boost::property_tree::write_json(s, rItem.second);
392 SAL_WARN(
"comphelper",
"JsonToPropertyValues: unhandled type '" << rType <<
"'");
PropertyValueVector_t aPropertyValues
css::uno::Any getAsConstAny(bool bAsPropertyValue) const
return this map instance as an Any, which can be used in const environments only.
void operator>>(css::uno::Sequence< css::beans::PropertyValue > &lDestination) const
converts this map instance to an PropertyValue sequence.
iterator find(const OUString &rKey)
SequenceAsHashMapBase m_aMap
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
return this map instance to as a PropertyValue sequence, which can be used in const environments only...
void update(const SequenceAsHashMap &rSource)
merge all values from the given map into this one.
bool match(const SequenceAsHashMap &rCheck) const
check if all items of given map exists in these called map also.
SequenceAsHashMapBase::const_iterator const_iterator
void operator<<(const css::uno::Any &aSource)
fill this map from the given Any, which of course must contain a suitable sequence of element types "...
css::uno::Sequence< css::beans::NamedValue > getAsConstNamedValueList() const
return this map instance to as a NamedValue sequence, which can be used in const environments only.
SequenceAsHashMap()
creates an empty hash map.
Sequence< PropertyValue > aArguments
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Copy from a container into a Sequence.
std::vector< css::beans::PropertyValue > JsonToPropertyValues(const OString &rJson)
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
sal_Int64 toInt64(std::u16string_view str, sal_Int16 radix=10)
double toDouble(std::u16string_view str)
sal_uInt32 toUInt32(std::u16string_view str, sal_Int16 radix=10)