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