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 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_desktop.hxx"
31 #include "cfgfilter.hxx"
32 
33 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <unotools/textsearch.hxx>
35 
36 using namespace rtl;
37 using namespace com::sun::star;
38 using namespace com::sun::star::uno;
39 using namespace com::sun::star::lang;
40 using namespace com::sun::star::beans;
41 using namespace com::sun::star::configuration::backend;
42 
43 namespace desktop {
44 
45 CConfigFilter::CConfigFilter(const strings_v* include,  const strings_v* exclude)
46     : m_pvInclude(include)
47     , m_pvExclude(exclude)
48 {
49 }
50 
51 void SAL_CALL CConfigFilter::initialize(const Sequence< Any >& seqArgs)
52         throw (Exception)
53 {
54     NamedValue nv;
55     for (sal_Int32 i=0; i < seqArgs.getLength(); i++)
56     {
57         if (seqArgs[i] >>= nv)
58         {
59             if (nv.Name.equalsAscii("Source"))
60                 nv.Value >>= m_xSourceLayer;
61             if (nv.Name.equalsAscii("ComponentName"))
62                 nv.Value >>= m_aCurrentComponent;
63         }
64     }
65     if (m_aCurrentComponent.getLength() == 0)
66         m_aCurrentComponent = OUString::createFromAscii("unknown.component");
67 
68     if (!m_xSourceLayer.is()) {
69         throw Exception();
70     }
71 
72 }
73 
74 
75 void CConfigFilter::pushElement(rtl::OUString aName, sal_Bool bUse)
76 {
77     OUString aPath;
78     if (!m_elementStack.empty()) {
79         aPath = m_elementStack.top().path; // or use base path
80         aPath += OUString::createFromAscii("/");
81     }
82     aPath += aName;
83 
84     // create element
85     element elem;
86     elem.name = aName;
87     elem.path = aPath;
88     elem.use = bUse;
89     m_elementStack.push(elem);
90 }
91 
92 sal_Bool CConfigFilter::checkCurrentElement()
93 {
94     return m_elementStack.top().use;
95 }
96 
97 sal_Bool CConfigFilter::checkElement(rtl::OUString aName)
98 {
99 
100     sal_Bool bResult = sal_False;
101 
102     // get full pathname for element
103     OUString aFullPath;
104     if (!m_elementStack.empty())
105         aFullPath = m_elementStack.top().path + OUString::createFromAscii("/");
106 
107     aFullPath += aName;
108 
109     // check whether any include patterns patch this path
110     for (strings_v::const_iterator i_in = m_pvInclude->begin();
111         i_in != m_pvInclude->end(); i_in++)
112     {
113         // pattern is beginning of path
114         // or path is a begiing for pattern
115         if (i_in->match(aFullPath.copy(0, i_in->getLength()>aFullPath.getLength()
116             ? aFullPath.getLength() : i_in->getLength()), 0))
117         {
118             bResult = sal_True;
119             break; // one match is enough
120         }
121     }
122     // if match is found, check for exclusion
123     if (bResult)
124     {
125         for (strings_v::const_iterator i_ex = m_pvExclude->begin();
126             i_ex != m_pvExclude->end(); i_ex++)
127         {
128             if (aFullPath.match(*i_ex, 0)) // pattern is beginning of path
129             {
130                 bResult = sal_False;
131                 break; // one is enough...
132             }
133         }
134     }
135     return bResult;
136 }
137 
138 void CConfigFilter::popElement()
139 {
140     m_elementStack.pop();
141 }
142 
143 
144 void SAL_CALL CConfigFilter::readData(
145         const Reference< configuration::backend::XLayerHandler >& layerHandler)
146     throw (
147         com::sun::star::lang::NullPointerException, lang::WrappedTargetException,
148         com::sun::star::configuration::backend::MalformedDataException)
149 {
150     // when readData is called, the submitted handler will be stored
151     // in m_xLayerHandler. we will then submit ourself as a handler to
152     // the SourceLayer in m_xSourceLayer.
153     // when the source calls our handler functions we will use the patterns that
154     // where given in the ctor to decide whther they should be relaied to the caller
155 
156     if (m_xSourceLayer.is() && layerHandler.is())
157     {
158         m_xLayerHandler = layerHandler;
159         m_xSourceLayer->readData(Reference<XLayerHandler>(static_cast< XLayerHandler* >(this)));
160     } else
161     {
162         throw NullPointerException();
163     }
164 }
165 
166 // XLayerHandler
167 void SAL_CALL CConfigFilter::startLayer()
168     throw(::com::sun::star::lang::WrappedTargetException)
169 {
170     m_xLayerHandler->startLayer();
171 }
172 
173 void SAL_CALL CConfigFilter::endLayer()
174     throw(
175         ::com::sun::star::configuration::backend::MalformedDataException,
176         ::com::sun::star::lang::WrappedTargetException )
177 {
178     m_xLayerHandler->endLayer();
179 }
180 
181 void SAL_CALL CConfigFilter::overrideNode(
182         const OUString& aName,
183         sal_Int16 aAttributes,
184         sal_Bool bClear)
185     throw(
186         ::com::sun::star::configuration::backend::MalformedDataException,
187         ::com::sun::star::lang::WrappedTargetException )
188 {
189     if (checkElement(aName))
190     {
191         m_xLayerHandler->overrideNode(aName, aAttributes, bClear);
192         pushElement(aName);
193     }
194     else
195         pushElement(aName, sal_False);
196 }
197 
198 void SAL_CALL CConfigFilter::addOrReplaceNode(
199         const OUString& aName,
200         sal_Int16 aAttributes)
201     throw(
202         ::com::sun::star::configuration::backend::MalformedDataException,
203         ::com::sun::star::lang::WrappedTargetException )
204 {
205     if (checkElement(aName))
206     {
207         m_xLayerHandler->addOrReplaceNode(aName, aAttributes);
208         pushElement(aName);
209     }
210     else
211         pushElement(aName, sal_False);
212 }
213 
214 void SAL_CALL  CConfigFilter::addOrReplaceNodeFromTemplate(
215         const OUString& aName,
216         const com::sun::star::configuration::backend::TemplateIdentifier& aTemplate,
217         sal_Int16 aAttributes )
218     throw(
219         ::com::sun::star::configuration::backend::MalformedDataException,
220         ::com::sun::star::lang::WrappedTargetException )
221 {
222     if (checkElement(aName))
223     {
224         m_xLayerHandler->addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
225         pushElement(aName);
226     }
227     else
228         pushElement(aName, sal_False);
229 }
230 
231 void SAL_CALL  CConfigFilter::endNode()
232     throw(
233         ::com::sun::star::configuration::backend::MalformedDataException,
234         ::com::sun::star::lang::WrappedTargetException )
235 {
236     if (checkCurrentElement())
237     {
238         m_xLayerHandler->endNode();
239     }
240     popElement();
241 }
242 
243 void SAL_CALL  CConfigFilter::dropNode(
244         const OUString& aName )
245     throw(
246         ::com::sun::star::configuration::backend::MalformedDataException,
247         ::com::sun::star::lang::WrappedTargetException )
248 {
249     // does not get pushed
250     if (checkElement(aName))
251     {
252         m_xLayerHandler->dropNode(aName);
253     }
254 }
255 
256 void SAL_CALL  CConfigFilter::overrideProperty(
257         const OUString& aName,
258         sal_Int16 aAttributes,
259         const Type& aType,
260         sal_Bool bClear )
261     throw(
262         ::com::sun::star::configuration::backend::MalformedDataException,
263         ::com::sun::star::lang::WrappedTargetException )
264 {
265     if (checkElement(aName)){
266         m_xLayerHandler->overrideProperty(aName, aAttributes, aType, bClear);
267         pushElement(aName);
268     }
269     else
270         pushElement(aName, sal_False);
271 }
272 
273 void SAL_CALL  CConfigFilter::setPropertyValue(
274         const Any& aValue )
275     throw(
276         ::com::sun::star::configuration::backend::MalformedDataException,
277         ::com::sun::star::lang::WrappedTargetException )
278 {
279     if (checkCurrentElement())
280         m_xLayerHandler->setPropertyValue(aValue);
281 }
282 
283 void SAL_CALL CConfigFilter::setPropertyValueForLocale(
284         const Any& aValue,
285         const OUString& aLocale )
286     throw(
287         ::com::sun::star::configuration::backend::MalformedDataException,
288         ::com::sun::star::lang::WrappedTargetException )
289 {
290     if (checkCurrentElement())
291         m_xLayerHandler->setPropertyValueForLocale(aValue, aLocale);
292 }
293 
294 void SAL_CALL  CConfigFilter::endProperty()
295     throw(
296         ::com::sun::star::configuration::backend::MalformedDataException,
297         ::com::sun::star::lang::WrappedTargetException )
298 {
299     if (checkCurrentElement())
300     {
301         m_xLayerHandler->endProperty();
302     }
303     popElement();
304 
305 }
306 
307 void SAL_CALL  CConfigFilter::addProperty(
308         const rtl::OUString& aName,
309         sal_Int16 aAttributes,
310         const Type& aType )
311     throw(
312         ::com::sun::star::configuration::backend::MalformedDataException,
313         ::com::sun::star::lang::WrappedTargetException )
314 {
315     if (checkElement(aName))
316         m_xLayerHandler->addProperty(aName, aAttributes, aType);
317 }
318 
319 void SAL_CALL  CConfigFilter::addPropertyWithValue(
320         const rtl::OUString& aName,
321         sal_Int16 aAttributes,
322         const Any& aValue )
323     throw(
324         ::com::sun::star::configuration::backend::MalformedDataException,
325         ::com::sun::star::lang::WrappedTargetException )
326 {
327     // add property with value doesn't push the property
328     if (checkElement(aName))
329         m_xLayerHandler->addPropertyWithValue(aName, aAttributes, aValue);
330 
331 }
332 
333 } // namespace desktop
334