Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_FORMS_SOURCE_XFORMS_BINDING_HXX
21 : #define INCLUDED_FORMS_SOURCE_XFORMS_BINDING_HXX
22 :
23 : #include <com/sun/star/uno/Reference.hxx>
24 :
25 : // forward declaractions
26 : namespace xforms
27 : {
28 : class Model;
29 : class EvaluationContext;
30 : }
31 : namespace com { namespace sun { namespace star {
32 : namespace xml {
33 : namespace xpath { class XXPathAPI; }
34 : namespace dom
35 : {
36 : class XNode;
37 : class XNodeList;
38 : }
39 : }
40 : namespace container { class XNameContainer; }
41 : namespace xforms { class XModel; }
42 : namespace xsd { class XDataType; }
43 : } } }
44 :
45 : #include <cppuhelper/implbase8.hxx>
46 : #include <propertysetbase.hxx>
47 : #include <com/sun/star/form/binding/XValueBinding.hpp>
48 : #include <com/sun/star/form/binding/XListEntrySource.hpp>
49 : #include <com/sun/star/form/validation/XValidator.hpp>
50 : #include <com/sun/star/util/XModifyBroadcaster.hpp>
51 : #include <com/sun/star/container/XNamed.hpp>
52 : #include <com/sun/star/xml/dom/events/XEventListener.hpp>
53 : #include <com/sun/star/lang/XUnoTunnel.hpp>
54 : #include <com/sun/star/util/XCloneable.hpp>
55 :
56 : #include "pathexpression.hxx"
57 : #include "boolexpression.hxx"
58 : #include "mip.hxx"
59 : #include <rtl/ustring.hxx>
60 : #include <vector>
61 :
62 :
63 :
64 : namespace xforms
65 : {
66 :
67 : /** An XForms Binding. Contains:
68 : * # a connection to its model
69 : * # an ID
70 : * # an binding expression
71 : * # model item properties
72 : * # (NOT YET IMPLEMENTED) child bindings (sequence of)
73 : *
74 : * See http://www.w3.org/TR/xforms/ for more information.
75 : */
76 :
77 : typedef cppu::ImplInheritanceHelper8<
78 : PropertySetBase,
79 : com::sun::star::form::binding::XValueBinding,
80 : com::sun::star::form::binding::XListEntrySource,
81 : com::sun::star::form::validation::XValidator,
82 : com::sun::star::util::XModifyBroadcaster,
83 : com::sun::star::container::XNamed,
84 : com::sun::star::xml::dom::events::XEventListener,
85 : com::sun::star::lang::XUnoTunnel,
86 : com::sun::star::util::XCloneable
87 : > Binding_t;
88 :
89 : class Binding : public Binding_t
90 : {
91 : public:
92 : typedef com::sun::star::uno::Reference<com::sun::star::xforms::XModel> Model_t;
93 : typedef com::sun::star::uno::Reference<com::sun::star::util::XModifyListener> XModifyListener_t;
94 : typedef std::vector<XModifyListener_t> ModifyListeners_t;
95 : typedef com::sun::star::uno::Reference<com::sun::star::form::validation::XValidityConstraintListener> XValidityConstraintListener_t;
96 : typedef std::vector<XValidityConstraintListener_t> XValidityConstraintListeners_t;
97 : typedef com::sun::star::uno::Reference<com::sun::star::form::binding::XListEntryListener> XListEntryListener_t;
98 : typedef std::vector<XListEntryListener_t> XListEntryListeners_t;
99 : typedef com::sun::star::uno::Reference<com::sun::star::container::XNameContainer> XNameContainer_t;
100 : typedef com::sun::star::uno::Reference<com::sun::star::xml::dom::XNode> XNode_t;
101 : typedef com::sun::star::uno::Reference<com::sun::star::xml::dom::XNodeList> XNodeList_t;
102 : typedef com::sun::star::uno::Reference<com::sun::star::util::XCloneable> XCloneable_t;
103 : typedef com::sun::star::uno::Sequence<sal_Int8> IntSequence_t;
104 : typedef com::sun::star::uno::Sequence<OUString> StringSequence_t;
105 : typedef std::vector<MIP> MIPs_t;
106 : typedef std::vector<XNode_t> XNodes_t;
107 :
108 :
109 :
110 : private:
111 :
112 : /// the Model to which this Binding belongs; may be NULL
113 : Model_t mxModel;
114 :
115 : /// binding-ID. A document-wide unique ID for this binding element.
116 : OUString msBindingID;
117 :
118 : /// an XPath-expression to be instantiated on the data instance
119 : PathExpression maBindingExpression;
120 :
121 : /// an XPath-expression to determine read-only status
122 : BoolExpression maReadonly;
123 :
124 : /// an XPath-expression to determine relevance
125 : BoolExpression maRelevant;
126 :
127 : /// an XPath-expression to determine if item is required
128 : BoolExpression maRequired;
129 :
130 : /// an XPath-expression to determine if item is valid
131 : BoolExpression maConstraint;
132 :
133 : /// user-readable explanation of the constraint
134 : OUString msExplainConstraint;
135 :
136 : /// an XPath-expression to calculate values
137 : ComputedExpression maCalculate;
138 :
139 : /// the XML namespaces used for XML names/XPath-expressions in this binding
140 : XNameContainer_t mxNamespaces;
141 :
142 : /// a type name
143 : OUString msTypeName;
144 :
145 : /// modify listeners
146 : ModifyListeners_t maModifyListeners;
147 :
148 : /// list entry listener
149 : XListEntryListeners_t maListEntryListeners;
150 :
151 : /// validity listeners;
152 : XValidityConstraintListeners_t maValidityListeners;
153 :
154 : /// nodes on which we are listening for events
155 : XNodes_t maEventNodes;
156 :
157 : /// the current MIP object for the first node we are bound to
158 : MIP maMIP;
159 :
160 : /// flag to detect recursions in calculate
161 : bool mbInCalculate;
162 :
163 : // flags to manage deferred notifications:
164 : /// if >0, valueModified() and bindingModified() will only set flags
165 : sal_Int32 mnDeferModifyNotifications;
166 : bool mbValueModified; /// if true, valueModified needs to be called
167 : bool mbBindingModified; /// if true, bindingModified needs to be called
168 :
169 :
170 : void initializePropertySet();
171 :
172 :
173 : public:
174 : Binding();
175 : virtual ~Binding();
176 :
177 :
178 : // property methods: get/set value
179 :
180 :
181 0 : Model_t getModel() const { return mxModel;} /// get XForms model
182 : void _setModel( const Model_t& ); /// set XForms model (only called by Model)
183 :
184 :
185 : OUString getModelID() const; /// get ID of XForms model
186 :
187 0 : OUString getBindingID() const { return msBindingID;} /// get ID for this binding
188 : void setBindingID( const OUString& ); /// set ID for this binding
189 :
190 : OUString getBindingExpression() const; /// get binding expression
191 : void setBindingExpression( const OUString& ); /// set binding exp.
192 :
193 : // MIPs (model item properties)
194 :
195 : OUString getReadonlyExpression() const; /// get read-only MIP
196 : void setReadonlyExpression( const OUString& ); /// set read-only MIP
197 :
198 : OUString getRelevantExpression() const; /// get relevant MIP
199 : void setRelevantExpression( const OUString& ); /// set relevant MIP
200 :
201 : OUString getRequiredExpression() const; /// get required MIP
202 : void setRequiredExpression( const OUString& ); /// set required MIP
203 :
204 : OUString getConstraintExpression() const; /// get constraint MIP
205 : void setConstraintExpression( const OUString& );/// set constraint MIP
206 :
207 : OUString getCalculateExpression() const; /// get calculate MIP
208 : void setCalculateExpression( const OUString& ); /// set calculate MIP
209 :
210 0 : OUString getType() const { return msTypeName;} /// get type name MIP (static)
211 : void setType( const OUString& ); /// set type name MIP (static)
212 :
213 : // a binding expression can only be interpreted with respect to
214 : // suitable namespace declarations. We collect those in the model and in a binding.
215 :
216 : // access to a binding's namespace
217 : // (set-method only changes local namespaces (but may add to model))
218 0 : XNameContainer_t getBindingNamespaces() const { return mxNamespaces; }
219 : void setBindingNamespaces( const XNameContainer_t& ); /// get binding nmsp.
220 :
221 : // access to the model's namespaces
222 : // (set-method changes model's namespaces (unless a local one is present))
223 : XNameContainer_t getModelNamespaces() const; /// set model namespaces
224 : void setModelNamespaces( const XNameContainer_t& ); /// get model nmsp.
225 :
226 :
227 : // read-only properties that map MIPs to control data source properties
228 : bool getReadOnly() const; // MIP readonly
229 : bool getRelevant() const; // MIP relevant
230 : bool getExternalData() const; // mapped from model's ExternalData property
231 :
232 :
233 : // missing binding properties:
234 : // - type (static; default: xsd:string)
235 : // - minOccurs/maxOccurs (computed XPath; default: 0/inf)
236 : // - p3ptype (static; no default)
237 :
238 :
239 :
240 :
241 : /// get this binding's context node
242 : xforms::EvaluationContext getEvaluationContext() const;
243 :
244 : /// get evalation contexts for this binding's MIPs
245 : std::vector<xforms::EvaluationContext> getMIPEvaluationContexts();
246 :
247 : /// get nodeset the bind is bound to
248 : XNodeList_t getXNodeList();
249 :
250 : /// heuristically determine whether this binding is simple binding
251 : /// (here: simple binding == does not depend on other parts of the
252 : /// instance, it's not a 'dynamic' binding)
253 : bool isSimpleBinding() const;
254 :
255 : /// heuristically determine whether this binding's binding
256 : /// expression is simple
257 : bool isSimpleBindingExpression() const;
258 :
259 : /// update this binding (e.g. called by model for refresh )
260 : void update();
261 :
262 : /// prevent change notifications being sent to controls
263 : void deferNotifications( bool );
264 :
265 : /// is this binding valid? (are constraint, type and required MIPs ok?)
266 : bool isValid();
267 :
268 : /// determine whether this binding currently performs a useful
269 : /// function, r whether is may be discarded
270 : bool isUseful();
271 :
272 : /// explain why binding is invalid
273 : OUString explainInvalid();
274 :
275 :
276 : // the ID for XUnoTunnel calls
277 : static IntSequence_t getUnoTunnelID();
278 : static Binding* getBinding( const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& );
279 :
280 :
281 : // class-scoped typedef for easy-to-read UNO interfaces
282 :
283 :
284 : // basic types
285 : typedef com::sun::star::uno::Any Any_t;
286 : typedef com::sun::star::uno::Sequence<com::sun::star::uno::Type> Sequence_Type_t;
287 : typedef com::sun::star::uno::Type Type_t;
288 :
289 : // reference types
290 : typedef com::sun::star::uno::Reference<com::sun::star::beans::XPropertyChangeListener> XPropertyChangeListener_t;
291 : typedef com::sun::star::uno::Reference<com::sun::star::beans::XPropertySetInfo> XPropertySetInfo_t;
292 : typedef com::sun::star::uno::Reference<com::sun::star::beans::XVetoableChangeListener> XVetoableChangeListener_t;
293 : typedef com::sun::star::uno::Reference<com::sun::star::xml::xpath::XXPathAPI> XXPathAPI_t;
294 : typedef com::sun::star::uno::Reference<com::sun::star::xml::dom::events::XEvent> XEvent_t;
295 : typedef com::sun::star::uno::Reference<com::sun::star::xsd::XDataType> XDataType_t;
296 :
297 : // exceptions
298 : typedef com::sun::star::beans::PropertyVetoException PropertyVetoException_t;
299 : typedef com::sun::star::beans::UnknownPropertyException UnknownPropertyException_t;
300 : typedef com::sun::star::lang::IllegalArgumentException IllegalArgumentException_t;
301 : typedef com::sun::star::lang::NoSupportException NoSupportException_t;
302 : typedef com::sun::star::lang::WrappedTargetException WrappedTargetException_t;
303 : typedef com::sun::star::uno::RuntimeException RuntimeException_t;
304 : typedef com::sun::star::form::binding::IncompatibleTypesException IncompatibleTypesException_t;
305 : typedef com::sun::star::form::binding::InvalidBindingStateException InvalidBindingStateException_t;
306 : typedef com::sun::star::lang::NullPointerException NullPointerException_t;
307 : typedef com::sun::star::lang::IndexOutOfBoundsException IndexOutOfBoundsException_t;
308 :
309 :
310 :
311 : private:
312 : /// check whether object is live, and throw suitable exception if not
313 : /// (to be used be API methods before acting on the object)
314 : void checkLive() throw( RuntimeException_t );
315 :
316 : /// check whether binding has a model, and throw exception if not
317 : /// (to be used be API methods before acting on the object)
318 : void checkModel() throw( RuntimeException_t );
319 :
320 : /// determine whether object is live
321 : /// live: has model, and model has been initialized
322 : bool isLive() const;
323 :
324 : /// get the model implementation
325 : xforms::Model* getModelImpl() const;
326 : xforms::Model* getModelImpl( const Model_t& xModel ) const;
327 :
328 : /// get MIP evaluation contexts
329 : /// (only valid if control has already been bound)
330 : std::vector<xforms::EvaluationContext> _getMIPEvaluationContexts() const;
331 :
332 : /// bind this binding, and pre-compute the affected nodes
333 : void bind( bool bForceRebind = false );
334 :
335 : /// the binding value has been changed:
336 : /// trigger a modified event on all modified listeners
337 : void valueModified();
338 :
339 : /// the binding itself has changed:
340 : /// force rebind, then call valueModified()
341 : void bindingModified();
342 :
343 :
344 : /// register the event listeners for
345 : void registerListeners();
346 :
347 : /// set MIPs defined by this binding on MIP item
348 : MIP getLocalMIP() const;
349 :
350 : /// get the data type that applies to this binding
351 : XDataType_t getDataType();
352 :
353 : /// determine whether binding is valid according to the given data type
354 : bool isValid_DataType();
355 :
356 : /// explain validity of binding with respect to the given data type
357 : OUString explainInvalid_DataType();
358 :
359 : /// 'clear' this binding - remove all listeners, etc.
360 : void clear();
361 :
362 : /// distribute MIPs from current node recursively to children
363 : void distributeMIP( const XNode_t &rxNode );
364 :
365 : /// implement get*Namespaces()
366 : XNameContainer_t _getNamespaces() const;
367 :
368 : /// implement set*Namespaces()
369 : void _setNamespaces( const XNameContainer_t&, bool bBinding );
370 :
371 : /// set a useful default binding ID (if none is set)
372 : void _checkBindingID();
373 :
374 : public:
375 : /// for debugging purposes only: get the MIPs defined by this binding
376 : const MIP* _getMIP();
377 :
378 :
379 :
380 :
381 :
382 :
383 : // XValueBinding:
384 :
385 :
386 : public:
387 :
388 : virtual Sequence_Type_t SAL_CALL getSupportedValueTypes()
389 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
390 :
391 : virtual sal_Bool SAL_CALL supportsType( const Type_t& aType )
392 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
393 :
394 : virtual Any_t SAL_CALL getValue( const Type_t& aType )
395 : throw( IncompatibleTypesException_t,
396 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
397 :
398 : virtual void SAL_CALL setValue( const Any_t& aValue )
399 : throw( IncompatibleTypesException_t,
400 : InvalidBindingStateException_t,
401 : NoSupportException_t,
402 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
403 :
404 :
405 :
406 :
407 : // XListEntry Source
408 :
409 :
410 : virtual sal_Int32 SAL_CALL getListEntryCount()
411 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
412 :
413 : virtual OUString SAL_CALL getListEntry( sal_Int32 nPosition )
414 : throw( IndexOutOfBoundsException_t,
415 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
416 :
417 : virtual StringSequence_t SAL_CALL getAllListEntries()
418 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
419 :
420 : virtual void SAL_CALL addListEntryListener( const XListEntryListener_t& )
421 : throw( NullPointerException_t,
422 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
423 :
424 : virtual void SAL_CALL removeListEntryListener( const XListEntryListener_t&)
425 : throw( NullPointerException_t,
426 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
427 :
428 :
429 :
430 :
431 : // XValidator:
432 :
433 :
434 : virtual sal_Bool SAL_CALL isValid(
435 : const Any_t& )
436 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
437 :
438 : virtual OUString SAL_CALL explainInvalid(
439 : const Any_t& )
440 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
441 :
442 : virtual void SAL_CALL addValidityConstraintListener(
443 : const XValidityConstraintListener_t& xListener )
444 : throw( NullPointerException_t,
445 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
446 :
447 : virtual void SAL_CALL removeValidityConstraintListener(
448 : const XValidityConstraintListener_t& xListener )
449 : throw( NullPointerException_t,
450 : RuntimeException_t, std::exception ) SAL_OVERRIDE;
451 :
452 :
453 :
454 : // XModifyBroadcaster & friends:
455 : // inform listeners about changes in our values
456 :
457 :
458 : public:
459 :
460 : virtual void SAL_CALL addModifyListener(
461 : const XModifyListener_t& xListener )
462 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
463 :
464 : virtual void SAL_CALL removeModifyListener(
465 : const XModifyListener_t& xListener )
466 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
467 :
468 :
469 :
470 :
471 :
472 : // XNamed:
473 : // get/set name
474 :
475 :
476 : public:
477 :
478 : virtual OUString SAL_CALL getName()
479 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
480 :
481 : virtual void SAL_CALL setName( const OUString& )
482 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
483 :
484 :
485 :
486 :
487 : // xml::dom::event::XEventListener
488 : // receive an event if our node changed
489 :
490 :
491 : virtual void SAL_CALL handleEvent(
492 : const XEvent_t& xEvent )
493 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
494 :
495 :
496 :
497 :
498 : // XUnoTunnel
499 :
500 :
501 : virtual sal_Int64 SAL_CALL getSomething( const IntSequence_t& )
502 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
503 :
504 :
505 :
506 : // XCloneable
507 :
508 :
509 : virtual XCloneable_t SAL_CALL createClone()
510 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE;
511 : };
512 :
513 :
514 : } // namespace xforms
515 :
516 : #endif
517 :
518 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|