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