LibreOffice Module xmloff (master)  1
property_meta_data.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "property_description.hxx"
21 #include "property_meta_data.hxx"
23 #include "strings.hxx"
24 #include <xmloff/xmlimp.hxx>
25 #include <xmloff/xmltoken.hxx>
26 #include <xmloff/xmlnamespace.hxx>
27 
28 #include <boost/functional/hash.hpp>
29 #include <tools/debug.hxx>
30 #include <osl/diagnose.h>
31 #include <sal/log.hxx>
32 
33 #include <unordered_map>
34 
36 {
37 
38  using namespace ::xmloff::token;
39 
40 #define FORM_SINGLE_PROPERTY( id, att ) \
41  PropertyDescription( PROPERTY_##id, XML_NAMESPACE_FORM, att, &FormHandlerFactory::getFormPropertyHandler, PID_##id )
42 
43  //= property meta data
44  namespace
45  {
46  const PropertyDescription* lcl_getPropertyMetaData()
47  {
48  static const PropertyDescription s_propertyMetaData[] =
49  {
52  FORM_SINGLE_PROPERTY( DEFAULT_DATE, XML_VALUE ),
56  FORM_SINGLE_PROPERTY( DEFAULT_TIME, XML_VALUE ),
58 
59  PropertyDescription()
60  };
61  return s_propertyMetaData;
62  }
63  }
64 
65  namespace
66  {
67  // TODO: instead of having all of the below static, it should be some per-instance data. This way, the
68  // approach used here would scale much better.
69  // That is, if you have multiple "meta data instances", which manage a small, but closed set of properties,
70  // then looking through those multiple instances would probably be faster than searching within
71  // one big instance, since in this case, every instance can quickly decide whether it is responsible
72  // for some attribute or property, and otherwise delegate to the next instance.
73 
74  typedef std::unordered_map< OUString, const PropertyDescription* > DescriptionsByName;
75 
76  const DescriptionsByName& lcl_getPropertyDescriptions()
77  {
79  static DescriptionsByName s_propertyDescriptionsByName;
80  if ( s_propertyDescriptionsByName.empty() )
81  {
82  const PropertyDescription* desc = lcl_getPropertyMetaData();
83  while ( !desc->propertyName.isEmpty() )
84  {
85  s_propertyDescriptionsByName[ desc->propertyName ] = desc;
86  ++desc;
87  }
88  }
89  return s_propertyDescriptionsByName;
90  }
91 
92  typedef std::unordered_map< OUString, XMLTokenEnum > ReverseTokenLookup;
93 
94  struct AttributeHash
95  {
96  size_t operator()( const AttributeDescription& i_attribute ) const
97  {
98  std::size_t seed = 0;
99  boost::hash_combine(seed, i_attribute.attributeToken);
100  boost::hash_combine(seed, i_attribute.namespacePrefix);
101  return seed;
102  }
103  };
104 
105  typedef std::unordered_map< AttributeDescription, PropertyGroups, AttributeHash > AttributesWithoutGroup;
106 
107  const AttributesWithoutGroup& lcl_getAttributesWithoutGroups()
108  {
110  static AttributesWithoutGroup s_attributesWithoutGroup;
111  if ( s_attributesWithoutGroup.empty() )
112  {
113  const PropertyDescription* desc = lcl_getPropertyMetaData();
114  while ( !desc->propertyName.isEmpty() )
115  {
116  PropertyDescriptionList singleElementList;
117  singleElementList.push_back( desc );
118 
119  s_attributesWithoutGroup[ desc->attribute ].push_back( singleElementList );
120  ++desc;
121  }
122  }
123  return s_attributesWithoutGroup;
124  }
125  }
126 
127  const PropertyDescription* getPropertyDescription( const OUString& i_propertyName )
128  {
129  const DescriptionsByName& rAllDescriptions( lcl_getPropertyDescriptions() );
130  DescriptionsByName::const_iterator pos = rAllDescriptions.find( i_propertyName );
131  if ( pos != rAllDescriptions.end() )
132  return pos->second;
133  return nullptr;
134  }
135 
136  void getPropertyGroupList( const AttributeDescription& i_attribute, PropertyGroups& o_propertyGroups )
137  {
138  // the attribute is not used for any non-trivial group, which means it is mapped directly to
139  // a single property
140  const AttributesWithoutGroup& attributesWithoutGroups( lcl_getAttributesWithoutGroups() );
141  const AttributesWithoutGroup::const_iterator pos = attributesWithoutGroups.find( i_attribute );
142  if ( pos != attributesWithoutGroups.end() )
143  o_propertyGroups = pos->second;
144  }
145 
146  AttributeDescription getAttributeDescription( sal_Int32 nAttributeToken )
147  {
149  attribute.namespacePrefix = (nAttributeToken >> NMSP_SHIFT) - 1;
150  attribute.attributeToken = static_cast<XMLTokenEnum>(nAttributeToken & TOKEN_MASK);
151  return attribute;
152  }
153 
154 } // namespace xmloff::metadata
155 
156 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::vector< PropertyDescriptionList > PropertyGroups
::std::vector< const PropertyDescription * > PropertyDescriptionList
DATE
size_t pos
AttributeDescription getAttributeDescription(sal_Int32 nAttributeToken)
retrieves the attribute descriptor for the attribute given by namespace prefix and attribute name ...
void getPropertyGroupList(const AttributeDescription &i_attribute, PropertyGroups &o_propertyGroups)
retrieves all known property groups which are mapped to the given attribute
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:49
::xmloff::token::XMLTokenEnum attributeToken
constexpr size_t NMSP_SHIFT
Definition: xmlimp.hxx:92
sal_Int32 attribute
Handling of tokens in XML:
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:93
#define DBG_TESTSOLARMUTEX()
#define FORM_SINGLE_PROPERTY(id, att)
const PropertyDescription * getPropertyDescription(const OUString &i_propertyName)