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 <com/sun/star/beans/XPropertyState.hpp>
31 #include "PropertySetMerger.hxx"
32 
33 using ::rtl::OUString;
34 
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::beans;
38 using namespace ::com::sun::star::lang;
39 
40 #ifndef _CPPUHELPER_IMPLBASE1_HXX_
41 #include <cppuhelper/implbase3.hxx>
42 #endif
43 
44 class SvXMLAttrContainerItem_Impl;
45 
46 class PropertySetMergerImpl : public ::cppu::WeakAggImplHelper3< XPropertySet, XPropertyState, XPropertySetInfo >
47 {
48 private:
49 	Reference< XPropertySet > mxPropSet1;
50 	Reference< XPropertyState > mxPropSet1State;
51 	Reference< XPropertySetInfo > mxPropSet1Info;
52 
53 	Reference< XPropertySet > mxPropSet2;
54 	Reference< XPropertyState > mxPropSet2State;
55 	Reference< XPropertySetInfo > mxPropSet2Info;
56 
57 public:
58 	PropertySetMergerImpl( const Reference< XPropertySet > rPropSet1, const Reference< XPropertySet > rPropSet2 );
59 	virtual ~PropertySetMergerImpl();
60 
61     // XPropertySet
62     virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(RuntimeException);
63     virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
64     virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
65     virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
66     virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
67     virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
68     virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
69 
70     // XPropertyState
71     virtual PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException);
72     virtual Sequence< PropertyState > SAL_CALL getPropertyStates( const Sequence< OUString >& aPropertyName ) throw(UnknownPropertyException, RuntimeException);
73     virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException);
74     virtual Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
75 
76     // XPropertySetInfo
77     virtual Sequence< Property > SAL_CALL getProperties(  ) throw(RuntimeException);
78     virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw(UnknownPropertyException, RuntimeException);
79     virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw(RuntimeException);
80 };
81 
82 // --------------------------------------------------------------------
83 // Interface implementation
84 // --------------------------------------------------------------------
85 
86 PropertySetMergerImpl::PropertySetMergerImpl( Reference< XPropertySet > rPropSet1, Reference< XPropertySet > rPropSet2 )
87 : mxPropSet1( rPropSet1 )
88 , mxPropSet1State( rPropSet1, UNO_QUERY )
89 , mxPropSet1Info( rPropSet1->getPropertySetInfo() )
90 , mxPropSet2( rPropSet2 )
91 , mxPropSet2State( rPropSet2, UNO_QUERY )
92 , mxPropSet2Info( rPropSet2->getPropertySetInfo() )
93 {
94 }
95 
96 PropertySetMergerImpl::~PropertySetMergerImpl()
97 {
98 }
99 
100 // XPropertySet
101 Reference< XPropertySetInfo > SAL_CALL PropertySetMergerImpl::getPropertySetInfo(  ) throw(RuntimeException)
102 {
103 	return this;
104 }
105 
106 void SAL_CALL PropertySetMergerImpl::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
107 {
108 	if( mxPropSet1Info->hasPropertyByName( aPropertyName ) )
109 	{
110 		mxPropSet1->setPropertyValue( aPropertyName, aValue );
111 	}
112 	else
113 	{
114 		mxPropSet2->setPropertyValue( aPropertyName, aValue );
115 	}
116 }
117 
118 Any SAL_CALL PropertySetMergerImpl::getPropertyValue( const OUString& PropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
119 {
120 	if( mxPropSet1Info->hasPropertyByName( PropertyName ) )
121 	{
122 		return mxPropSet1->getPropertyValue( PropertyName );
123 	}
124 	else
125 	{
126 		return mxPropSet2->getPropertyValue( PropertyName );
127 	}
128 }
129 
130 void SAL_CALL PropertySetMergerImpl::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
131 {
132 }
133 
134 void SAL_CALL PropertySetMergerImpl::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
135 {
136 }
137 
138 void SAL_CALL PropertySetMergerImpl::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
139 {
140 }
141 
142 void SAL_CALL PropertySetMergerImpl::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
143 {
144 }
145 
146 // XPropertyState
147 PropertyState SAL_CALL PropertySetMergerImpl::getPropertyState( const OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException)
148 {
149 	if( mxPropSet1Info->hasPropertyByName( PropertyName ) )
150 	{
151 		if( mxPropSet1State.is() )
152 		{
153 			return mxPropSet1State->getPropertyState( PropertyName );
154 		}
155 		else
156 		{
157 			return PropertyState_DIRECT_VALUE;
158 		}
159 	}
160 	else
161 	{
162 		if( mxPropSet2State.is() )
163 		{
164 			return mxPropSet2State->getPropertyState( PropertyName );
165 		}
166 		else
167 		{
168 			return PropertyState_DIRECT_VALUE;
169 		}
170 	}
171 }
172 
173 Sequence< PropertyState > SAL_CALL PropertySetMergerImpl::getPropertyStates( const Sequence< OUString >& aPropertyName ) throw(UnknownPropertyException, RuntimeException)
174 {
175 	const sal_Int32 nCount = aPropertyName.getLength();
176 	Sequence< PropertyState > aPropStates( nCount );
177 	PropertyState* pPropStates = aPropStates.getArray();
178 	const OUString* pPropNames = aPropertyName.getConstArray();
179 
180 	sal_Int32 nIndex;
181 	for( nIndex = 0; nIndex < nCount; nIndex++ )
182 		*pPropStates++ = getPropertyState( *pPropNames++ );
183 
184 	return aPropStates;
185 }
186 
187 void SAL_CALL PropertySetMergerImpl::setPropertyToDefault( const OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException)
188 {
189 	if( mxPropSet1State.is() && mxPropSet1Info->hasPropertyByName( PropertyName ) )
190 	{
191 		mxPropSet1State->setPropertyToDefault( PropertyName );
192 	}
193 	else
194 	{
195 		if( mxPropSet2State.is() )
196 		{
197 			mxPropSet2State->setPropertyToDefault( PropertyName );
198 		}
199 	}
200 }
201 
202 Any SAL_CALL PropertySetMergerImpl::getPropertyDefault( const OUString& aPropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
203 {
204 	if( mxPropSet1State.is() && mxPropSet1Info->hasPropertyByName( aPropertyName ) )
205 	{
206 		return mxPropSet1State->getPropertyDefault( aPropertyName );
207 	}
208 	else
209 	{
210 		if( mxPropSet2State.is() )
211 		{
212 			return mxPropSet2State->getPropertyDefault( aPropertyName );
213 		}
214 		else
215 		{
216 			Any aAny;
217 			return aAny;
218 		}
219 	}
220 }
221 
222 // XPropertySetInfo
223 Sequence< Property > SAL_CALL PropertySetMergerImpl::getProperties() throw(RuntimeException)
224 {
225 	Sequence< Property > aProps1( mxPropSet1Info->getProperties() );
226 	const Property* pProps1 = aProps1.getArray();
227 	const sal_Int32 nCount1 = aProps1.getLength();
228 
229 	Sequence< Property > aProps2( mxPropSet1Info->getProperties() );
230 	const Property* pProps2 = aProps2.getArray();
231 	const sal_Int32 nCount2 = aProps2.getLength();
232 
233 	Sequence< Property > aProperties( nCount1 + nCount2 );
234 
235 	sal_Int32 nIndex;
236 
237 	Property* pProperties = aProperties.getArray();
238 
239 	for( nIndex = 0; nIndex < nCount1; nIndex++ )
240 		*pProperties++ = *pProps1++;
241 
242 	for( nIndex = 0; nIndex < nCount2; nIndex++ )
243 		*pProperties++ = *pProps2++;
244 
245 	return aProperties;
246 }
247 
248 Property SAL_CALL PropertySetMergerImpl::getPropertyByName( const OUString& aName ) throw(UnknownPropertyException, RuntimeException)
249 {
250 	if( mxPropSet1Info->hasPropertyByName( aName ) )
251 		return mxPropSet1Info->getPropertyByName( aName );
252 
253 	return mxPropSet2Info->getPropertyByName( aName );
254 }
255 
256 sal_Bool SAL_CALL PropertySetMergerImpl::hasPropertyByName( const OUString& Name ) throw(RuntimeException)
257 {
258 	if(mxPropSet1Info->hasPropertyByName( Name ) )
259 		return sal_True;
260 
261 	return mxPropSet2Info->hasPropertyByName( Name );
262 }
263 
264 Reference< XPropertySet > PropertySetMerger_CreateInstance( Reference< XPropertySet > rPropSet1, Reference< XPropertySet > rPropSet2 ) throw()
265 {
266 	return new PropertySetMergerImpl( rPropSet1, rPropSet2 );
267 }
268