xref: /trunk/main/xmloff/source/core/unoatrcn.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 #include <tools/debug.hxx>
31 #include <com/sun/star/xml/AttributeData.hpp>
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/uuid.h>
34 #include <rtl/memory.h>
35 
36 #include <xmloff/xmlcnimp.hxx>
37 
38 #include "xmloff/unoatrcn.hxx"
39 
40 using ::rtl::OUString;
41 using ::rtl::OUStringBuffer;
42 
43 using namespace ::com::sun::star;
44 
45 // --------------------------------------------------------------------
46 // Interface implementation
47 // --------------------------------------------------------------------
48 
49 #define IMPL    ((AttrContainerImpl*)mpData)
50 
51 uno::Reference< uno::XInterface >  SvUnoAttributeContainer_CreateInstance()
52 {
53     return *(new SvUnoAttributeContainer);
54 }
55 
56 SvUnoAttributeContainer::SvUnoAttributeContainer( SvXMLAttrContainerData* pContainer)
57 : mpContainer( pContainer )
58 {
59     if( mpContainer == NULL )
60         mpContainer = new SvXMLAttrContainerData;
61 }
62 
63 SvUnoAttributeContainer::~SvUnoAttributeContainer()
64 {
65     delete mpContainer;
66 }
67 
68 // container::XElementAccess
69 uno::Type SAL_CALL SvUnoAttributeContainer::getElementType(void)
70     throw( uno::RuntimeException )
71 {
72     return ::getCppuType((const xml::AttributeData*)0);
73 }
74 
75 sal_Bool SAL_CALL SvUnoAttributeContainer::hasElements(void)
76     throw( uno::RuntimeException )
77 {
78     return mpContainer->GetAttrCount() != 0;
79 }
80 
81 sal_uInt16 SvUnoAttributeContainer::getIndexByName(const OUString& aName ) const
82 {
83     const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
84 
85     sal_Int32 nPos = aName.indexOf( sal_Unicode(':') );
86     if( nPos == -1L )
87     {
88         for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
89         {
90             if( mpContainer->GetAttrLName(nAttr) == aName &&
91                 mpContainer->GetAttrPrefix(nAttr).getLength() == 0L )
92                 return nAttr;
93         }
94     }
95     else
96     {
97         const OUString aPrefix( aName.copy( 0L, nPos ) );
98         const OUString aLName( aName.copy( nPos+1L ) );
99 
100         for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
101         {
102             if( mpContainer->GetAttrLName(nAttr) == aLName &&
103                 mpContainer->GetAttrPrefix(nAttr) == aPrefix )
104                 return nAttr;
105         }
106     }
107 
108     return USHRT_MAX;
109 }
110 
111 const ::com::sun::star::uno::Sequence< sal_Int8 > & SvUnoAttributeContainer::getUnoTunnelId() throw()
112 {
113     static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
114     if( !pSeq )
115     {
116         ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
117         if( !pSeq )
118         {
119             static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
120             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
121             pSeq = &aSeq;
122         }
123     }
124     return *pSeq;
125 }
126 
127 SvUnoAttributeContainer* SvUnoAttributeContainer::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
128 {
129     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xInt, ::com::sun::star::uno::UNO_QUERY );
130     if( xUT.is() )
131     {
132         return
133             reinterpret_cast<SvUnoAttributeContainer*>(
134                 sal::static_int_cast<sal_IntPtr>(
135                     xUT->getSomething( SvUnoAttributeContainer::getUnoTunnelId())));
136     }
137     else
138         return NULL;
139 }
140 
141 sal_Int64 SAL_CALL SvUnoAttributeContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException)
142 {
143     if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
144                                                          rId.getConstArray(), 16 ) )
145     {
146         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
147     }
148     return 0;
149 }
150 
151 // container::XNameAccess
152 uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName)
153     throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
154 {
155     sal_uInt16 nAttr = getIndexByName(aName );
156 
157     if( nAttr == USHRT_MAX )
158         throw container::NoSuchElementException();
159 
160     xml::AttributeData aData;
161     aData.Namespace = mpContainer->GetAttrNamespace(nAttr);
162     aData.Type = OUString::createFromAscii("CDATA");
163     aData.Value = mpContainer->GetAttrValue(nAttr);
164 
165     uno::Any aAny;
166     aAny <<= aData;
167     return aAny;
168 }
169 
170 uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames(void) throw( uno::RuntimeException )
171 {
172     const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
173 
174     uno::Sequence< OUString > aElementNames( (sal_Int32)nAttrCount );
175     OUString *pNames = aElementNames.getArray();
176 
177     for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
178     {
179         OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) );
180         if( sBuffer.getLength() != 0L )
181             sBuffer.append( (sal_Unicode)':' );
182         sBuffer.append( mpContainer->GetAttrLName(nAttr) );
183         *pNames++ = sBuffer.makeStringAndClear();
184     }
185 
186     return aElementNames;
187 }
188 
189 sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName) throw( uno::RuntimeException )
190 {
191     return getIndexByName(aName ) != USHRT_MAX;
192 }
193 
194 // container::XNameReplace
195 void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement)
196     throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
197 {
198     if( aElement.hasValue() && aElement.getValueType() == ::getCppuType((const xml::AttributeData*)0) )
199     {
200         sal_uInt16 nAttr = getIndexByName(aName );
201         if( nAttr == USHRT_MAX )
202             throw container::NoSuchElementException();
203 
204         xml::AttributeData* pData = (xml::AttributeData*)aElement.getValue();
205 
206         sal_Int32 nPos = aName.indexOf( sal_Unicode(':') );
207         if( nPos != -1L )
208         {
209             const OUString aPrefix( aName.copy( 0L, nPos ));
210             const OUString aLName( aName.copy( nPos+1L ));
211 
212             if( pData->Namespace.getLength() == 0L )
213             {
214                 if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) )
215                     return;
216             }
217             else
218             {
219                 if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) )
220                     return;
221             }
222         }
223         else
224         {
225             if( pData->Namespace.getLength() == 0L )
226             {
227                 if( mpContainer->SetAt( nAttr, aName, pData->Value ) )
228                     return;
229             }
230         }
231     }
232 
233     throw lang::IllegalArgumentException();
234 }
235 
236 // container::XNameContainer
237 void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement)
238 throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
239 {
240     if( !aElement.hasValue() || aElement.getValueType() != ::getCppuType((const xml::AttributeData*)0) )
241         throw lang::IllegalArgumentException();
242 
243     sal_uInt16 nAttr = getIndexByName(aName );
244     if( nAttr != USHRT_MAX )
245         throw container::ElementExistException();
246 
247     xml::AttributeData* pData = (xml::AttributeData*)aElement.getValue();
248 
249     sal_Int32 nPos = aName.indexOf( sal_Unicode(':') );
250     if( nPos != -1L )
251     {
252         const OUString aPrefix( aName.copy( 0L, nPos ));
253         const OUString aLName( aName.copy( nPos+1L ));
254 
255         if( pData->Namespace.getLength() == 0L )
256         {
257             if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) )
258                 return;
259         }
260         else
261         {
262             if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) )
263                 return;
264         }
265     }
266     else
267     {
268         if( pData->Namespace.getLength() == 0L )
269         {
270             if( mpContainer->AddAttr( aName, pData->Value ) )
271                 return;
272         }
273     }
274 }
275 
276 void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name)
277     throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
278 {
279     sal_uInt16 nAttr = getIndexByName(Name);
280     if( nAttr == USHRT_MAX )
281         throw container::NoSuchElementException();
282 
283     mpContainer->Remove( nAttr );
284 }
285 
286 //XServiceInfo
287 OUString SAL_CALL SvUnoAttributeContainer::getImplementationName(void) throw( uno::RuntimeException )
288 {
289     return OUString::createFromAscii( "SvUnoAttributeContainer" );
290 }
291 
292 uno::Sequence< OUString > SvUnoAttributeContainer::getSupportedServiceNames(void)
293     throw( uno::RuntimeException )
294 {
295     OUString aSN( OUString::createFromAscii( "com.sun.star.xml.AttributeContainer" ) );
296     uno::Sequence< OUString > aNS( &aSN, 1L );
297     return aNS;
298 }
299 
300 sal_Bool SvUnoAttributeContainer::supportsService(const OUString& ServiceName)
301     throw( uno::RuntimeException )
302 {
303     const uno::Sequence < OUString > aServiceNames( getSupportedServiceNames() );
304     const OUString* pNames = aServiceNames.getConstArray();
305     sal_Int32 nCount = aServiceNames.getLength();
306     while( nCount-- )
307     {
308         if( *pNames++ == ServiceName )
309             return sal_True;
310     }
311 
312     return sal_False;
313 }
314 
315 
316