xref: /trunk/main/xmloff/source/core/unoatrcn.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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