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 #include "precompiled_sd.hxx"
25
26 #include "ConfigurationClassifier.hxx"
27
28 #include "framework/FrameworkHelper.hxx"
29
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::drawing::framework;
33 using ::rtl::OUString;
34
35 #undef VERBOSE
36 //#define VERBOSE 2
37
38
39 namespace sd { namespace framework {
40
ConfigurationClassifier(const Reference<XConfiguration> & rxConfiguration1,const Reference<XConfiguration> & rxConfiguration2)41 ConfigurationClassifier::ConfigurationClassifier (
42 const Reference<XConfiguration>& rxConfiguration1,
43 const Reference<XConfiguration>& rxConfiguration2)
44 : mxConfiguration1(rxConfiguration1),
45 mxConfiguration2(rxConfiguration2),
46 maC1minusC2(),
47 maC2minusC1(),
48 maC1andC2()
49 {
50 }
51
52
53
54
Partition(void)55 bool ConfigurationClassifier::Partition (void)
56 {
57 maC1minusC2.clear();
58 maC2minusC1.clear();
59 maC1andC2.clear();
60
61 PartitionResources(
62 mxConfiguration1->getResources(NULL, OUString(), AnchorBindingMode_DIRECT),
63 mxConfiguration2->getResources(NULL, OUString(), AnchorBindingMode_DIRECT));
64
65 return !maC1minusC2.empty() || !maC2minusC1.empty();
66 }
67
68
69
70
GetC1minusC2(void) const71 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1minusC2 (void) const
72 {
73 return maC1minusC2;
74 }
75
76
77
78
GetC2minusC1(void) const79 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC2minusC1 (void) const
80 {
81 return maC2minusC1;
82 }
83
84
85
GetC1andC2(void) const86 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1andC2 (void) const
87 {
88 return maC1andC2;
89 }
90
91
PartitionResources(const::com::sun::star::uno::Sequence<Reference<XResourceId>> & rS1,const::com::sun::star::uno::Sequence<Reference<XResourceId>> & rS2)92 void ConfigurationClassifier::PartitionResources (
93 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1,
94 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2)
95 {
96 ResourceIdVector aC1minusC2;
97 ResourceIdVector aC2minusC1;
98 ResourceIdVector aC1andC2;
99
100 // Classify the resources in the configurations that are not bound to
101 // other resources.
102 ClassifyResources(
103 rS1,
104 rS2,
105 aC1minusC2,
106 aC2minusC1,
107 aC1andC2);
108
109 #if defined VERBOSE && VERBOSE >= 2
110 OSL_TRACE("copying resource ids to C1-C2\r");
111 #endif
112 CopyResources(aC1minusC2, mxConfiguration1, maC1minusC2);
113 #if defined VERBOSE && VERBOSE >= 2
114 OSL_TRACE("copying resource ids to C2-C1\r");
115 #endif
116 CopyResources(aC2minusC1, mxConfiguration2, maC2minusC1);
117
118 // Process the unique resources that belong to both configurations.
119 ResourceIdVector::const_iterator iResource;
120 for (iResource=aC1andC2.begin(); iResource!=aC1andC2.end(); ++iResource)
121 {
122 maC1andC2.push_back(*iResource);
123 PartitionResources(
124 mxConfiguration1->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT),
125 mxConfiguration2->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT));
126 }
127 }
128
129
130
131
ClassifyResources(const::com::sun::star::uno::Sequence<Reference<XResourceId>> & rS1,const::com::sun::star::uno::Sequence<Reference<XResourceId>> & rS2,ResourceIdVector & rS1minusS2,ResourceIdVector & rS2minusS1,ResourceIdVector & rS1andS2)132 void ConfigurationClassifier::ClassifyResources (
133 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1,
134 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2,
135 ResourceIdVector& rS1minusS2,
136 ResourceIdVector& rS2minusS1,
137 ResourceIdVector& rS1andS2)
138 {
139 // Get arrays from the sequences for faster iteration.
140 const Reference<XResourceId>* aA1 = rS1.getConstArray();
141 const Reference<XResourceId>* aA2 = rS2.getConstArray();
142 sal_Int32 nL1 (rS1.getLength());
143 sal_Int32 nL2 (rS2.getLength());
144
145 // Find all elements in rS1 and place them in rS1minusS2 or rS1andS2
146 // depending on whether they are in rS2 or not.
147 for (sal_Int32 i=0; i<nL1; ++i)
148 {
149 bool bFound (false);
150 for (sal_Int32 j=0; j<nL2 && !bFound; ++j)
151 if (aA1[i]->getResourceURL().equals(aA2[j]->getResourceURL()))
152 bFound = true;
153
154 if (bFound)
155 rS1andS2.push_back(aA1[i]);
156 else
157 rS1minusS2.push_back(aA1[i]);
158 }
159
160 // Find all elements in rS2 that are not in rS1. The elements that are
161 // in both rS1 and rS2 have been handled above and are therefore ignored
162 // here.
163 for (sal_Int32 j=0; j<nL2; ++j)
164 {
165 bool bFound (false);
166 for (sal_Int32 i=0; i<nL1 && !bFound; ++i)
167 if (aA2[j]->getResourceURL().equals(aA1[i]->getResourceURL()))
168 bFound = true;
169
170 if ( ! bFound)
171 rS2minusS1.push_back(aA2[j]);
172 }
173 }
174
175
176
177
CopyResources(const ResourceIdVector & rSource,const Reference<XConfiguration> & rxConfiguration,ResourceIdVector & rTarget)178 void ConfigurationClassifier::CopyResources (
179 const ResourceIdVector& rSource,
180 const Reference<XConfiguration>& rxConfiguration,
181 ResourceIdVector& rTarget)
182 {
183 // Copy all resources bound to the ones in aC1minusC2Unique to rC1minusC2.
184 ResourceIdVector::const_iterator iResource (rSource.begin());
185 ResourceIdVector::const_iterator iEnd(rSource.end());
186 for ( ; iResource!=iEnd; ++iResource)
187 {
188 const Sequence<Reference<XResourceId> > aBoundResources (
189 rxConfiguration->getResources(
190 *iResource,
191 OUString(),
192 AnchorBindingMode_INDIRECT));
193 const sal_Int32 nL (aBoundResources.getLength());
194
195 rTarget.reserve(rTarget.size() + 1 + nL);
196 rTarget.push_back(*iResource);
197
198 #if defined VERBOSE && VERBOSE >= 2
199 OSL_TRACE(" copying %s\r",
200 OUStringToOString(FrameworkHelper::ResourceIdToString(*iResource),
201 RTL_TEXTENCODING_UTF8).getStr());
202 #endif
203
204 const Reference<XResourceId>* aA = aBoundResources.getConstArray();
205 for (sal_Int32 i=0; i<nL; ++i)
206 {
207 rTarget.push_back(aA[i]);
208 #if defined VERBOSE && VERBOSE >= 2
209 OSL_TRACE(" copying %s\r",
210 OUStringToOString(FrameworkHelper::ResourceIdToString(aA[i]),
211 RTL_TEXTENCODING_UTF8).getStr());
212 #endif
213 }
214 }
215 }
216
217
TraceResourceIdVector(const sal_Char * pMessage,const ResourceIdVector & rResources) const218 void ConfigurationClassifier::TraceResourceIdVector (
219 const sal_Char* pMessage,
220 const ResourceIdVector& rResources) const
221 {
222
223 OSL_TRACE(pMessage);
224 ResourceIdVector::const_iterator iResource;
225 for (iResource=rResources.begin(); iResource!=rResources.end(); ++iResource)
226 {
227 OUString sResource (FrameworkHelper::ResourceIdToString(*iResource));
228 OSL_TRACE(" %s\r",
229 OUStringToOString(sResource, RTL_TEXTENCODING_UTF8).getStr());
230 }
231 }
232
233
234 } } // end of namespace sd::framework
235