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