1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmloff.hxx" 26 27 #ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX 28 #include "MultiPropertySetHelper.hxx" 29 #endif 30 #include <com/sun/star/beans/XPropertySetInfo.hpp> 31 #include <com/sun/star/beans/XPropertySet.hpp> 32 #include <com/sun/star/beans/XMultiPropertySet.hpp> 33 #include <com/sun/star/lang/XServiceInfo.hpp> 34 #include <comphelper/stl_types.hxx> 35 36 // STL includes 37 #include <algorithm> 38 39 40 using ::com::sun::star::beans::XMultiPropertySet; 41 using ::com::sun::star::beans::XPropertySet; 42 using ::com::sun::star::beans::XPropertySetInfo; 43 using ::com::sun::star::lang::XServiceInfo; 44 using ::com::sun::star::uno::Any; 45 using ::com::sun::star::uno::Reference; 46 using ::com::sun::star::uno::Sequence; 47 using ::com::sun::star::uno::UNO_QUERY; 48 using ::comphelper::UStringLess; 49 using ::rtl::OUString; 50 using ::std::sort; 51 52 53 MultiPropertySetHelper::MultiPropertySetHelper( 54 const sal_Char** pNames ) : 55 pPropertyNames( NULL ), 56 nLength( 0 ), 57 aPropertySequence(), 58 pSequenceIndex( NULL ), 59 aValues(), 60 pValues( NULL ) 61 { 62 // first count the elements 63 for( const sal_Char** pPtr = pNames; *pPtr != NULL; pPtr++ ) 64 nLength++; 65 66 // allocate array and create strings 67 pPropertyNames = new OUString[nLength]; 68 for( sal_Int16 i = 0; i < nLength; i++ ) 69 pPropertyNames[i] = OUString::createFromAscii( pNames[i] ); 70 } 71 72 MultiPropertySetHelper::MultiPropertySetHelper( 73 const OUString* pNames ) : 74 pPropertyNames( NULL ), 75 nLength( 0 ), 76 aPropertySequence(), 77 pSequenceIndex( NULL ), 78 aValues(), 79 pValues( NULL ) 80 { 81 // count elements 82 for( const OUString* pPtr = pNames; pPtr != NULL; pPtr++ ) 83 nLength++; 84 85 // allocate array and assign strings 86 pPropertyNames = new OUString[nLength]; 87 for( sal_Int16 i = 0; i < nLength; i++ ) 88 pPropertyNames[i] = pNames[i]; 89 } 90 91 92 MultiPropertySetHelper::~MultiPropertySetHelper() 93 { 94 pValues = NULL; // memory 'owned' by aValues 95 96 delete[] pSequenceIndex; 97 delete[] pPropertyNames; 98 } 99 100 101 102 void MultiPropertySetHelper::hasProperties( 103 const Reference<XPropertySetInfo> & rInfo ) 104 { 105 DBG_ASSERT( rInfo.is(), "I'd really like an XPropertySetInfo here." ); 106 107 // allocate sequence index 108 if ( NULL == pSequenceIndex ) 109 pSequenceIndex = new sal_Int16[nLength] ; 110 111 // construct pSequenceIndex 112 sal_Int16 nNumberOfProperties = 0; 113 sal_Int16 i; 114 115 for( i = 0; i < nLength; i++ ) 116 { 117 // ask for property 118 sal_Bool bHasProperty = 119 rInfo->hasPropertyByName( pPropertyNames[i] ); 120 121 // set index and increment (if appropriate) 122 pSequenceIndex[i]= bHasProperty ? nNumberOfProperties : -1; 123 if ( bHasProperty ) 124 nNumberOfProperties++; 125 } 126 127 // construct property sequence from index array 128 if ( aPropertySequence.getLength() != nNumberOfProperties ) 129 aPropertySequence.realloc( nNumberOfProperties ); 130 OUString* pPropertySequence = aPropertySequence.getArray(); 131 for( i = 0; i < nLength; i ++ ) 132 { 133 sal_Int16 nIndex = pSequenceIndex[i]; 134 if ( nIndex != -1 ) 135 pPropertySequence[nIndex] = pPropertyNames[i]; 136 } 137 } 138 139 sal_Bool MultiPropertySetHelper::checkedProperties() 140 { 141 return (NULL != pSequenceIndex); 142 } 143 144 145 146 void MultiPropertySetHelper::getValues( 147 const Reference<XMultiPropertySet> & rMultiPropertySet ) 148 { 149 DBG_ASSERT( rMultiPropertySet.is(), "We need an XMultiPropertySet." ); 150 151 aValues = rMultiPropertySet->getPropertyValues( aPropertySequence ); 152 pValues = aValues.getConstArray(); 153 } 154 155 void MultiPropertySetHelper::getValues( 156 const Reference<XPropertySet> & rPropertySet ) 157 { 158 DBG_ASSERT( rPropertySet.is(), "We need an XPropertySet." ); 159 160 // re-alloc aValues (if necessary) and fill with values from XPropertySet 161 sal_Int16 nSupportedPropertiesCount = 162 (sal_Int16)aPropertySequence.getLength(); 163 if ( aValues.getLength() != nSupportedPropertiesCount ) 164 aValues.realloc( nSupportedPropertiesCount ); 165 Any* pMutableArray = aValues.getArray(); 166 for( sal_Int16 i = 0; i < nSupportedPropertiesCount; i++ ) 167 { 168 pMutableArray[i] = rPropertySet->getPropertyValue( 169 pPropertyNames[ pSequenceIndex[ i ] ] ); 170 } 171 172 // re-establish pValues pointer 173 pValues = aValues.getConstArray(); 174 } 175 176 177 const Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex, 178 const Reference< XPropertySet> & rPropSet, 179 sal_Bool bTryMulti ) 180 { 181 if( !pValues ) 182 { 183 if( bTryMulti ) 184 { 185 Reference < XMultiPropertySet > xMultiPropSet( rPropSet, 186 UNO_QUERY ); 187 if( xMultiPropSet.is() ) 188 getValues( xMultiPropSet ); 189 else 190 getValues( rPropSet ); 191 } 192 else 193 { 194 getValues( rPropSet ); 195 } 196 } 197 198 return getValue( nIndex ); 199 } 200 201 const Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex, 202 const Reference< XMultiPropertySet> & rMultiPropSet ) 203 { 204 if( !pValues ) 205 getValues( rMultiPropSet ); 206 207 return getValue( nIndex ); 208 } 209 210 // inline methods defined in header: 211 // inline Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex ) 212 // inline sal_Bool MultiPropertySetHelper::hasProperty( sal_Int16 nValueNo ) 213