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 #include <tools/debug.hxx>
27 #include <com/sun/star/xml/AttributeData.hpp>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/uuid.h>
30 #include <rtl/memory.h>
31
32 #include <xmloff/xmlcnimp.hxx>
33
34 #include "xmloff/unoatrcn.hxx"
35
36 using ::rtl::OUString;
37 using ::rtl::OUStringBuffer;
38
39 using namespace ::com::sun::star;
40
41 // --------------------------------------------------------------------
42 // Interface implementation
43 // --------------------------------------------------------------------
44
45 #define IMPL ((AttrContainerImpl*)mpData)
46
SvUnoAttributeContainer_CreateInstance()47 uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
48 {
49 return *(new SvUnoAttributeContainer);
50 }
51
SvUnoAttributeContainer(SvXMLAttrContainerData * pContainer)52 SvUnoAttributeContainer::SvUnoAttributeContainer( SvXMLAttrContainerData* pContainer)
53 : mpContainer( pContainer )
54 {
55 if( mpContainer == NULL )
56 mpContainer = new SvXMLAttrContainerData;
57 }
58
~SvUnoAttributeContainer()59 SvUnoAttributeContainer::~SvUnoAttributeContainer()
60 {
61 delete mpContainer;
62 }
63
64 // container::XElementAccess
getElementType(void)65 uno::Type SAL_CALL SvUnoAttributeContainer::getElementType(void)
66 {
67 return ::getCppuType((const xml::AttributeData*)0);
68 }
69
hasElements(void)70 sal_Bool SAL_CALL SvUnoAttributeContainer::hasElements(void)
71 {
72 return mpContainer->GetAttrCount() != 0;
73 }
74
getIndexByName(const OUString & aName) const75 sal_uInt16 SvUnoAttributeContainer::getIndexByName(const OUString& aName ) const
76 {
77 const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
78
79 sal_Int32 nPos = aName.indexOf( sal_Unicode(':') );
80 if( nPos == -1L )
81 {
82 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
83 {
84 if( mpContainer->GetAttrLName(nAttr) == aName &&
85 mpContainer->GetAttrPrefix(nAttr).getLength() == 0L )
86 return nAttr;
87 }
88 }
89 else
90 {
91 const OUString aPrefix( aName.copy( 0L, nPos ) );
92 const OUString aLName( aName.copy( nPos+1L ) );
93
94 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
95 {
96 if( mpContainer->GetAttrLName(nAttr) == aLName &&
97 mpContainer->GetAttrPrefix(nAttr) == aPrefix )
98 return nAttr;
99 }
100 }
101
102 return USHRT_MAX;
103 }
104
getUnoTunnelId()105 const ::com::sun::star::uno::Sequence< sal_Int8 > & SvUnoAttributeContainer::getUnoTunnelId() throw()
106 {
107 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
108 if( !pSeq )
109 {
110 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
111 if( !pSeq )
112 {
113 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
114 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
115 pSeq = &aSeq;
116 }
117 }
118 return *pSeq;
119 }
120
getImplementation(uno::Reference<uno::XInterface> xInt)121 SvUnoAttributeContainer* SvUnoAttributeContainer::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
122 {
123 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xInt, ::com::sun::star::uno::UNO_QUERY );
124 if( xUT.is() )
125 {
126 return
127 reinterpret_cast<SvUnoAttributeContainer*>(
128 sal::static_int_cast<sal_IntPtr>(
129 xUT->getSomething( SvUnoAttributeContainer::getUnoTunnelId())));
130 }
131 else
132 return NULL;
133 }
134
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & rId)135 sal_Int64 SAL_CALL SvUnoAttributeContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId )
136 {
137 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
138 rId.getConstArray(), 16 ) )
139 {
140 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
141 }
142 return 0;
143 }
144
145 // container::XNameAccess
getByName(const OUString & aName)146 uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName)
147 {
148 sal_uInt16 nAttr = getIndexByName(aName );
149
150 if( nAttr == USHRT_MAX )
151 throw container::NoSuchElementException();
152
153 xml::AttributeData aData;
154 aData.Namespace = mpContainer->GetAttrNamespace(nAttr);
155 aData.Type = OUString::createFromAscii("CDATA");
156 aData.Value = mpContainer->GetAttrValue(nAttr);
157
158 uno::Any aAny;
159 aAny <<= aData;
160 return aAny;
161 }
162
getElementNames(void)163 uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames(void)
164 {
165 const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
166
167 uno::Sequence< OUString > aElementNames( (sal_Int32)nAttrCount );
168 OUString *pNames = aElementNames.getArray();
169
170 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
171 {
172 OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) );
173 if( sBuffer.getLength() != 0L )
174 sBuffer.append( (sal_Unicode)':' );
175 sBuffer.append( mpContainer->GetAttrLName(nAttr) );
176 *pNames++ = sBuffer.makeStringAndClear();
177 }
178
179 return aElementNames;
180 }
181
hasByName(const OUString & aName)182 sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName)
183 {
184 return getIndexByName(aName ) != USHRT_MAX;
185 }
186
187 // container::XNameReplace
replaceByName(const OUString & aName,const uno::Any & aElement)188 void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement)
189 {
190 if( aElement.hasValue() && aElement.getValueType() == ::getCppuType((const xml::AttributeData*)0) )
191 {
192 sal_uInt16 nAttr = getIndexByName(aName );
193 if( nAttr == USHRT_MAX )
194 throw container::NoSuchElementException();
195
196 xml::AttributeData* pData = (xml::AttributeData*)aElement.getValue();
197
198 sal_Int32 nPos = aName.indexOf( sal_Unicode(':') );
199 if( nPos != -1L )
200 {
201 const OUString aPrefix( aName.copy( 0L, nPos ));
202 const OUString aLName( aName.copy( nPos+1L ));
203
204 if( pData->Namespace.getLength() == 0L )
205 {
206 if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) )
207 return;
208 }
209 else
210 {
211 if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) )
212 return;
213 }
214 }
215 else
216 {
217 if( pData->Namespace.getLength() == 0L )
218 {
219 if( mpContainer->SetAt( nAttr, aName, pData->Value ) )
220 return;
221 }
222 }
223 }
224
225 throw lang::IllegalArgumentException();
226 }
227
228 // container::XNameContainer
insertByName(const OUString & aName,const uno::Any & aElement)229 void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement)
230 {
231 if( !aElement.hasValue() || aElement.getValueType() != ::getCppuType((const xml::AttributeData*)0) )
232 throw lang::IllegalArgumentException();
233
234 sal_uInt16 nAttr = getIndexByName(aName );
235 if( nAttr != USHRT_MAX )
236 throw container::ElementExistException();
237
238 xml::AttributeData* pData = (xml::AttributeData*)aElement.getValue();
239
240 sal_Int32 nPos = aName.indexOf( sal_Unicode(':') );
241 if( nPos != -1L )
242 {
243 const OUString aPrefix( aName.copy( 0L, nPos ));
244 const OUString aLName( aName.copy( nPos+1L ));
245
246 if( pData->Namespace.getLength() == 0L )
247 {
248 if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) )
249 return;
250 }
251 else
252 {
253 if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) )
254 return;
255 }
256 }
257 else
258 {
259 if( pData->Namespace.getLength() == 0L )
260 {
261 if( mpContainer->AddAttr( aName, pData->Value ) )
262 return;
263 }
264 }
265 }
266
removeByName(const OUString & Name)267 void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name)
268 {
269 sal_uInt16 nAttr = getIndexByName(Name);
270 if( nAttr == USHRT_MAX )
271 throw container::NoSuchElementException();
272
273 mpContainer->Remove( nAttr );
274 }
275
276 //XServiceInfo
getImplementationName(void)277 OUString SAL_CALL SvUnoAttributeContainer::getImplementationName(void)
278 {
279 return OUString::createFromAscii( "SvUnoAttributeContainer" );
280 }
281
getSupportedServiceNames(void)282 uno::Sequence< OUString > SvUnoAttributeContainer::getSupportedServiceNames(void)
283 {
284 OUString aSN( OUString::createFromAscii( "com.sun.star.xml.AttributeContainer" ) );
285 uno::Sequence< OUString > aNS( &aSN, 1L );
286 return aNS;
287 }
288
supportsService(const OUString & ServiceName)289 sal_Bool SvUnoAttributeContainer::supportsService(const OUString& ServiceName)
290 {
291 const uno::Sequence < OUString > aServiceNames( getSupportedServiceNames() );
292 const OUString* pNames = aServiceNames.getConstArray();
293 sal_Int32 nCount = aServiceNames.getLength();
294 while( nCount-- )
295 {
296 if( *pNames++ == ServiceName )
297 return sal_True;
298 }
299
300 return sal_False;
301 }
302