xref: /AOO41X/main/xmloff/source/core/unoatrcn.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
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