1a5b190bfSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3a5b190bfSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4a5b190bfSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5a5b190bfSAndrew Rist  * distributed with this work for additional information
6a5b190bfSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7a5b190bfSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8a5b190bfSAndrew Rist  * "License"); you may not use this file except in compliance
9a5b190bfSAndrew Rist  * with the License.  You may obtain a copy of the License at
10a5b190bfSAndrew Rist  *
11a5b190bfSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12a5b190bfSAndrew Rist  *
13a5b190bfSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14a5b190bfSAndrew Rist  * software distributed under the License is distributed on an
15a5b190bfSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16a5b190bfSAndrew Rist  * KIND, either express or implied.  See the License for the
17a5b190bfSAndrew Rist  * specific language governing permissions and limitations
18a5b190bfSAndrew Rist  * under the License.
19a5b190bfSAndrew Rist  *
20a5b190bfSAndrew Rist  *************************************************************/
21a5b190bfSAndrew Rist 
22a5b190bfSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir package com.sun.star.lib.uno.helper;
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import com.sun.star.beans.Property;
27cdf0e10cSrcweir import com.sun.star.beans.PropertyAttribute;
28cdf0e10cSrcweir import com.sun.star.beans.PropertyChangeEvent;
29cdf0e10cSrcweir import com.sun.star.beans.PropertyState;
30cdf0e10cSrcweir import com.sun.star.beans.PropertyValue;
31cdf0e10cSrcweir import com.sun.star.beans.PropertyVetoException;
32cdf0e10cSrcweir import com.sun.star.beans.UnknownPropertyException;
33cdf0e10cSrcweir import com.sun.star.beans.XPropertyChangeListener;
34cdf0e10cSrcweir import com.sun.star.beans.XPropertySetInfo;
35cdf0e10cSrcweir import com.sun.star.beans.XVetoableChangeListener;
36cdf0e10cSrcweir import com.sun.star.container.NoSuchElementException;
37cdf0e10cSrcweir import com.sun.star.container.XHierarchicalNameAccess;
38cdf0e10cSrcweir import com.sun.star.lang.DisposedException;
39cdf0e10cSrcweir import com.sun.star.lang.EventObject;
40cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetException;
41cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetRuntimeException;
42cdf0e10cSrcweir import com.sun.star.lang.XComponent;
43cdf0e10cSrcweir import com.sun.star.reflection.XCompoundTypeDescription;
44cdf0e10cSrcweir import com.sun.star.reflection.XIdlClass;
45cdf0e10cSrcweir import com.sun.star.reflection.XIdlField2;
46cdf0e10cSrcweir import com.sun.star.reflection.XIdlReflection;
47cdf0e10cSrcweir import com.sun.star.reflection.XIndirectTypeDescription;
48cdf0e10cSrcweir import com.sun.star.reflection.XInterfaceAttributeTypeDescription2;
49cdf0e10cSrcweir import com.sun.star.reflection.XInterfaceMemberTypeDescription;
50cdf0e10cSrcweir import com.sun.star.reflection.XInterfaceTypeDescription2;
51cdf0e10cSrcweir import com.sun.star.reflection.XStructTypeDescription;
52cdf0e10cSrcweir import com.sun.star.reflection.XTypeDescription;
53cdf0e10cSrcweir import com.sun.star.uno.Any;
54cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
55cdf0e10cSrcweir import com.sun.star.uno.DeploymentException;
56cdf0e10cSrcweir import com.sun.star.uno.Type;
57cdf0e10cSrcweir import com.sun.star.uno.TypeClass;
58cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
59cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
60cdf0e10cSrcweir import com.sun.star.uno.XInterface;
61cdf0e10cSrcweir import java.util.ArrayList;
62cdf0e10cSrcweir import java.util.HashMap;
63cdf0e10cSrcweir import java.util.HashSet;
64cdf0e10cSrcweir import java.util.Iterator;
65cdf0e10cSrcweir import java.util.Map;
66cdf0e10cSrcweir import java.util.Vector;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir /**
69cdf0e10cSrcweir    A helper mixin to implement certain UNO interfaces related to property set
70cdf0e10cSrcweir    handling on top of the attributes of a given UNO interface type.
71cdf0e10cSrcweir 
72cdf0e10cSrcweir    <p>A client will mix in this class by keeping a reference to an instance of
73cdf0e10cSrcweir    this class, and forwarding all methods of (a subset of the interfaces)
74cdf0e10cSrcweir    <code>com.sun.star.beans.XPropertySet</code>,
75cdf0e10cSrcweir    <code>com.sun.star.beans.XFastPropertySet</code>, and
76cdf0e10cSrcweir    <code>com.sun.star.beans.XPropertyAccess</code> to it.</p>
77cdf0e10cSrcweir 
78cdf0e10cSrcweir    <p>Client code should not use the monitors associated with instances of this
79cdf0e10cSrcweir    class, as they are used for internal purposes.</p>
80cdf0e10cSrcweir 
81cdf0e10cSrcweir    @since UDK 3.2
82cdf0e10cSrcweir */
83cdf0e10cSrcweir public final class PropertySetMixin {
84cdf0e10cSrcweir     /**
85cdf0e10cSrcweir        The constructor.
86cdf0e10cSrcweir 
87cdf0e10cSrcweir        @param context the component context used by this instance; must not be
88cdf0e10cSrcweir        null, and must supply the service
89cdf0e10cSrcweir        <code>com.sun.star.reflection.CoreReflection</code> and the singleton
90cdf0e10cSrcweir        <code>com.sun.star.reflection.theTypeDescriptionManager</code>
91cdf0e10cSrcweir 
92cdf0e10cSrcweir        @param object the client UNO object into which this instance is mixed in;
93cdf0e10cSrcweir        must not be null, and must support the given <code>type</code>
94cdf0e10cSrcweir 
95cdf0e10cSrcweir        @param type the UNO interface type whose attributes are mapped to
96cdf0e10cSrcweir        properties; must not be null, and must represent a UNO interface type
97cdf0e10cSrcweir 
98cdf0e10cSrcweir        @param absentOptional a list of optional properties that are not present,
99cdf0e10cSrcweir        and should thus not be visible via
100cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.getPropertySetInfo</code>,
101cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.addPropertyChangeListener</code>,
102cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.removePropertyChangeListener<!--
103cdf0e10cSrcweir        --></code>,
104cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.addVetoableChangeListener</code>,
105cdf0e10cSrcweir        and <code>com.sun.star.beans.XPropertySet.<!--
106cdf0e10cSrcweir        -->removeVetoableChangeListener</code>; null is treated the same as an
107cdf0e10cSrcweir        empty list; if non-null, the given array must not be modified after it is
108cdf0e10cSrcweir        passed to this constructor.  For consistency reasons, the given
109cdf0e10cSrcweir        <code>absentOptional</code> should only contain the names of attributes
110cdf0e10cSrcweir        that represent optional properties that are not present (that is, the
111cdf0e10cSrcweir        attribute getters and setters always throw a
112cdf0e10cSrcweir        <code>com.sun.star.beans.UnknownPropertyException</code>), and should
113cdf0e10cSrcweir        contain each such name only once.  If an optional property is not present
114cdf0e10cSrcweir        (that is, the corresponding attribute getter and setter always throw a
115cdf0e10cSrcweir        <code>com.sun.star.beans.UnknownPropertyException</code>) but is not
116cdf0e10cSrcweir        contained in the given <code>absentOptional</code>, then it will be
117cdf0e10cSrcweir        visible via
118cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.getPropertySetInfo</code> as a
119cdf0e10cSrcweir        <code>com.sun.star.beans.Property</code> with a set
120cdf0e10cSrcweir        <code>com.sun.star.beans.PropertyAttribute.OPTIONAL</code>.  If the given
121cdf0e10cSrcweir        <code>object</code> does not implement
122cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet</code>, then the given
123cdf0e10cSrcweir        <code>absentOptional</code> is effectively ignored and can be null or
124cdf0e10cSrcweir        empty.
125cdf0e10cSrcweir     */
PropertySetMixin( XComponentContext context, XInterface object, Type type, String[] absentOptional)126cdf0e10cSrcweir     public PropertySetMixin(
127cdf0e10cSrcweir         XComponentContext context, XInterface object, Type type,
128cdf0e10cSrcweir         String[] absentOptional)
129cdf0e10cSrcweir     {
130cdf0e10cSrcweir         // assert context != null && object != null && type != null
131cdf0e10cSrcweir         //     && type.getTypeClass() == TypeClass.INTERFACE;
132cdf0e10cSrcweir         this.context = context;
133cdf0e10cSrcweir         this.object = object;
134cdf0e10cSrcweir         this.type = type;
135cdf0e10cSrcweir         this.absentOptional = absentOptional;
136cdf0e10cSrcweir         idlClass = getReflection(type.getTypeName());
137cdf0e10cSrcweir         XTypeDescription ifc;
138cdf0e10cSrcweir         try {
139cdf0e10cSrcweir             ifc = UnoRuntime.queryInterface(
140cdf0e10cSrcweir                 XTypeDescription.class,
141cdf0e10cSrcweir                 (UnoRuntime.queryInterface(
142cdf0e10cSrcweir                     XHierarchicalNameAccess.class,
143cdf0e10cSrcweir                     context.getValueByName(
144cdf0e10cSrcweir                         "/singletons/com.sun.star.reflection."
145cdf0e10cSrcweir                         + "theTypeDescriptionManager")).
146cdf0e10cSrcweir                  getByHierarchicalName(type.getTypeName())));
147cdf0e10cSrcweir         } catch (NoSuchElementException e) {
148cdf0e10cSrcweir             throw new RuntimeException(
149cdf0e10cSrcweir                 "unexpected com.sun.star.container.NoSuchElementException: "
150cdf0e10cSrcweir                 + e.getMessage());
151cdf0e10cSrcweir         }
152cdf0e10cSrcweir         HashMap map = new HashMap();
153cdf0e10cSrcweir         ArrayList handleNames = new ArrayList();
154cdf0e10cSrcweir         initProperties(ifc, map, handleNames, new HashSet());
155cdf0e10cSrcweir         properties = map;
156cdf0e10cSrcweir         handleMap = (String[]) handleNames.toArray(
157cdf0e10cSrcweir             new String[handleNames.size()]);
158cdf0e10cSrcweir     }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir     /**
161cdf0e10cSrcweir        A method used by clients when implementing UNO interface type attribute
162cdf0e10cSrcweir        setter functions.
163cdf0e10cSrcweir 
164cdf0e10cSrcweir        <p>First, this method checks whether this instance has already been
165cdf0e10cSrcweir        disposed (see {@link #dispose}), and throws a
166cdf0e10cSrcweir        <code>com.sun.star.beans.DisposedException</code> if applicable.  For a
167cdf0e10cSrcweir        constrained attribute (whose setter can explicitly raise
168cdf0e10cSrcweir        <code>com.sun.star.beans.PropertyVetoException</code>), this method
169cdf0e10cSrcweir        notifies any <code>com.sun.star.beans.XVetoableChangeListener</code>s.
170cdf0e10cSrcweir        For a bound attribute, this method modifies the passed-in
171cdf0e10cSrcweir        <code>bound</code> so that it can afterwards be used to notify any
172cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertyChangeListener</code>s.  This method
173cdf0e10cSrcweir        should be called before storing the new attribute value, and
174cdf0e10cSrcweir        <code>bound.notifyListeners()</code> should be called exactly once after
175cdf0e10cSrcweir        storing the new attribute value (in case the attribute is bound;
176cdf0e10cSrcweir        otherwise, calling <code>bound.notifyListeners()</code> is ignored).
177cdf0e10cSrcweir        Furthermore, <code>bound.notifyListeners()</code> and this method have to
178cdf0e10cSrcweir        be called from the same thread.</p>
179cdf0e10cSrcweir 
180cdf0e10cSrcweir        @param propertyName the name of the property (which is the same as the
181cdf0e10cSrcweir        name of the attribute that is going to be set)
182cdf0e10cSrcweir 
183cdf0e10cSrcweir        @param oldValue the property value corresponding to the old attribute
184cdf0e10cSrcweir        value.  This is only used as
185cdf0e10cSrcweir        <code>com.sun.star.beans.PropertyChangeEvent.OldValue</code>, which is
186cdf0e10cSrcweir        rather useless, anyway (see &ldquo;Using the Observer Pattern&rdquo; in
187cdf0e10cSrcweir        <a href="http://tools.openoffice.org/CodingGuidelines.sxw">
188cdf0e10cSrcweir        <cite>OpenOffice.org Coding Guidelines</cite></a>).  If the attribute
189cdf0e10cSrcweir        that is going to be set is neither bound nor constrained, or if
190cdf0e10cSrcweir        <code>com.sun.star.beans.PropertyChangeEvent.OldValue</code> should not
191cdf0e10cSrcweir        be set, {@link Any#VOID} can be used instead.
192cdf0e10cSrcweir 
193cdf0e10cSrcweir        @param newValue the property value corresponding to the new
194cdf0e10cSrcweir        attribute value.  This is only used as
195cdf0e10cSrcweir        <code>com.sun.star.beans.PropertyChangeEvent.NewValue</code>, which is
196*9ad05808SDamjan Jovanovic        rather useless, anyway (see &ldquo;Using the Observer Pattern&rdquo; in
197cdf0e10cSrcweir        <a href="http://tools.openoffice.org/CodingGuidelines.sxw">
198cdf0e10cSrcweir        <cite>OpenOffice.org Coding Guidelines</cite></a>), <em>unless</em> the
199cdf0e10cSrcweir        attribute that is going to be set is constrained.  If the attribute
200cdf0e10cSrcweir        that is going to be set is neither bound nor constrained, or if it is
201cdf0e10cSrcweir        only bound but
202cdf0e10cSrcweir        <code>com.sun.star.beans.PropertyChangeEvent.NewValue</code> should not
203cdf0e10cSrcweir        be set, {@link Any#VOID} can be used instead.
204cdf0e10cSrcweir 
205cdf0e10cSrcweir        @param bound a reference to a fresh {@link BoundListeners} instance
206cdf0e10cSrcweir        (which has not been passed to this method before, and on which
207cdf0e10cSrcweir        {@link BoundListeners#notifyListeners} has not yet been called); may only
208cdf0e10cSrcweir        be null if the attribute that is going to be set is not bound
209cdf0e10cSrcweir     */
prepareSet( String propertyName, Object oldValue, Object newValue, BoundListeners bound)210cdf0e10cSrcweir     public void prepareSet(
211cdf0e10cSrcweir         String propertyName, Object oldValue, Object newValue,
212cdf0e10cSrcweir         BoundListeners bound)
213cdf0e10cSrcweir         throws PropertyVetoException
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         // assert properties.get(propertyName) != null;
216cdf0e10cSrcweir         Property p = ((PropertyData) properties.get(propertyName)).property;
217cdf0e10cSrcweir         Vector specificVeto = null;
218cdf0e10cSrcweir         Vector unspecificVeto = null;
219cdf0e10cSrcweir         synchronized (this) {
220cdf0e10cSrcweir             if (disposed) {
221cdf0e10cSrcweir                 throw new DisposedException("disposed", object);
222cdf0e10cSrcweir             }
223cdf0e10cSrcweir             if ((p.Attributes & PropertyAttribute.CONSTRAINED) != 0) {
224cdf0e10cSrcweir                 Object o = vetoListeners.get(propertyName);
225cdf0e10cSrcweir                 if (o != null) {
226cdf0e10cSrcweir                     specificVeto = (Vector) ((Vector) o).clone();
227cdf0e10cSrcweir                 }
228cdf0e10cSrcweir                 o = vetoListeners.get("");
229cdf0e10cSrcweir                 if (o != null) {
230cdf0e10cSrcweir                     unspecificVeto = (Vector) ((Vector) o).clone();
231cdf0e10cSrcweir                 }
232cdf0e10cSrcweir             }
233cdf0e10cSrcweir             if ((p.Attributes & PropertyAttribute.BOUND) != 0) {
234cdf0e10cSrcweir                 // assert bound != null;
235cdf0e10cSrcweir                 Object o = boundListeners.get(propertyName);
236cdf0e10cSrcweir                 if (o != null) {
237cdf0e10cSrcweir                     bound.specificListeners = (Vector) ((Vector) o).clone();
238cdf0e10cSrcweir                 }
239cdf0e10cSrcweir                 o = boundListeners.get("");
240cdf0e10cSrcweir                 if (o != null) {
241cdf0e10cSrcweir                     bound.unspecificListeners = (Vector) ((Vector) o).clone();
242cdf0e10cSrcweir                 }
243cdf0e10cSrcweir             }
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir         if ((p.Attributes & PropertyAttribute.CONSTRAINED) != 0) {
246cdf0e10cSrcweir             PropertyChangeEvent event = new PropertyChangeEvent(
247cdf0e10cSrcweir                 object, propertyName, false, p.Handle, oldValue, newValue);
248cdf0e10cSrcweir             if (specificVeto != null) {
249cdf0e10cSrcweir                 for (Iterator i = specificVeto.iterator(); i.hasNext();) {
250cdf0e10cSrcweir                     try {
251cdf0e10cSrcweir                         ((XVetoableChangeListener) i.next()).vetoableChange(
252cdf0e10cSrcweir                             event);
253cdf0e10cSrcweir                     } catch (DisposedException e) {}
254cdf0e10cSrcweir                 }
255cdf0e10cSrcweir             }
256cdf0e10cSrcweir             if (unspecificVeto != null) {
257cdf0e10cSrcweir                 for (Iterator i = unspecificVeto.iterator(); i.hasNext();) {
258cdf0e10cSrcweir                     try {
259cdf0e10cSrcweir                         ((XVetoableChangeListener) i.next()).vetoableChange(
260cdf0e10cSrcweir                             event);
261cdf0e10cSrcweir                     } catch (DisposedException e) {}
262cdf0e10cSrcweir                 }
263cdf0e10cSrcweir             }
264cdf0e10cSrcweir         }
265cdf0e10cSrcweir         if ((p.Attributes & PropertyAttribute.BOUND) != 0) {
266cdf0e10cSrcweir             // assert bound != null;
267cdf0e10cSrcweir             bound.event = new PropertyChangeEvent(
268cdf0e10cSrcweir                 object, propertyName, false, p.Handle, oldValue, newValue);
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir     }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     /**
273cdf0e10cSrcweir        A simplified version of {@link #prepareSet(String, Object, Object,
274cdf0e10cSrcweir        PropertySetMixin.BoundListeners)}.
275cdf0e10cSrcweir 
276cdf0e10cSrcweir        <p>This method is useful for attributes that are not constrained.</p>
277cdf0e10cSrcweir 
278cdf0e10cSrcweir        @param propertyName the name of the property (which is the same as the
279cdf0e10cSrcweir        name of the attribute that is going to be set)
280cdf0e10cSrcweir 
281cdf0e10cSrcweir        @param bound a reference to a fresh {@link BoundListeners} instance
282cdf0e10cSrcweir        (which has not been passed to this method before, and on which
283cdf0e10cSrcweir        {@link BoundListeners#notifyListeners} has not yet been called); may only
284cdf0e10cSrcweir        be null if the attribute that is going to be set is not bound
285cdf0e10cSrcweir     */
prepareSet(String propertyName, BoundListeners bound)286cdf0e10cSrcweir     public void prepareSet(String propertyName, BoundListeners bound) {
287cdf0e10cSrcweir         try {
288cdf0e10cSrcweir             prepareSet(propertyName, Any.VOID, Any.VOID, bound);
289cdf0e10cSrcweir         } catch (PropertyVetoException e) {
290cdf0e10cSrcweir             throw new RuntimeException("unexpected " + e);
291cdf0e10cSrcweir         }
292cdf0e10cSrcweir     }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir     /**
295cdf0e10cSrcweir        Marks this instance as being disposed.
296cdf0e10cSrcweir 
297cdf0e10cSrcweir        <p>See <code>com.sun.star.lang.XComponent</code> for the general concept
298cdf0e10cSrcweir        of disposing UNO objects.  On the first call to this method, all
299cdf0e10cSrcweir        registered listeners
300cdf0e10cSrcweir        (<code>com.sun.star.beans.XPropertyChangeListener</code>s and
301cdf0e10cSrcweir        <code>com.sun.star.beans.XVetoableChangeListener</code>s) are notified of
302cdf0e10cSrcweir        the disposing source.  Any subsequent calls to this method are
303cdf0e10cSrcweir        ignored.</p>
304cdf0e10cSrcweir      */
dispose()305cdf0e10cSrcweir     public void dispose() {
306cdf0e10cSrcweir         HashMap bound;
307cdf0e10cSrcweir         HashMap veto;
308cdf0e10cSrcweir         synchronized (this) {
309cdf0e10cSrcweir             bound = boundListeners;
310cdf0e10cSrcweir             boundListeners = null;
311cdf0e10cSrcweir             veto = vetoListeners;
312cdf0e10cSrcweir             vetoListeners = null;
313cdf0e10cSrcweir             disposed = true;
314cdf0e10cSrcweir         }
315cdf0e10cSrcweir         EventObject event = new EventObject(object);
316cdf0e10cSrcweir         if (bound != null) {
317cdf0e10cSrcweir             for (Iterator i = bound.values().iterator(); i.hasNext();) {
318cdf0e10cSrcweir                 for (Iterator j = ((Vector) i.next()).iterator(); j.hasNext();)
319cdf0e10cSrcweir                 {
320cdf0e10cSrcweir                     ((XPropertyChangeListener) j.next()).disposing(event);
321cdf0e10cSrcweir                 }
322cdf0e10cSrcweir             }
323cdf0e10cSrcweir         }
324cdf0e10cSrcweir         if (veto != null) {
325cdf0e10cSrcweir             for (Iterator i = veto.values().iterator(); i.hasNext();) {
326cdf0e10cSrcweir                 for (Iterator j = ((Vector) i.next()).iterator(); j.hasNext();)
327cdf0e10cSrcweir                 {
328cdf0e10cSrcweir                     ((XVetoableChangeListener) j.next()).disposing(event);
329cdf0e10cSrcweir                 }
330cdf0e10cSrcweir             }
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     /**
335cdf0e10cSrcweir        Implements
336cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.getPropertySetInfo</code>.
337cdf0e10cSrcweir     */
getPropertySetInfo()338cdf0e10cSrcweir     public XPropertySetInfo getPropertySetInfo() {
339cdf0e10cSrcweir         return new Info(properties);
340cdf0e10cSrcweir     }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     /**
343cdf0e10cSrcweir        Implements <code>com.sun.star.beans.XPropertySet.setPropertyValue</code>.
344cdf0e10cSrcweir     */
setPropertyValue(String propertyName, Object value)345cdf0e10cSrcweir     public void setPropertyValue(String propertyName, Object value)
346cdf0e10cSrcweir         throws UnknownPropertyException, PropertyVetoException,
347cdf0e10cSrcweir         com.sun.star.lang.IllegalArgumentException, WrappedTargetException
348cdf0e10cSrcweir     {
349cdf0e10cSrcweir         setProperty(propertyName, value, false, false, (short) 1);
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     /**
353cdf0e10cSrcweir        Implements <code>com.sun.star.beans.XPropertySet.getPropertyValue</code>.
354cdf0e10cSrcweir     */
getPropertyValue(String propertyName)355cdf0e10cSrcweir     public Object getPropertyValue(String propertyName)
356cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
357cdf0e10cSrcweir     {
358cdf0e10cSrcweir         return getProperty(propertyName, null);
359cdf0e10cSrcweir     }
360cdf0e10cSrcweir 
361cdf0e10cSrcweir     /**
362cdf0e10cSrcweir        Implements
363cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.addPropertyChangeListener</code>.
364cdf0e10cSrcweir 
365cdf0e10cSrcweir        <p>If a listener is added more than once, it will receive all relevant
366cdf0e10cSrcweir        notifications multiple times.</p>
367cdf0e10cSrcweir     */
addPropertyChangeListener( String propertyName, XPropertyChangeListener listener)368cdf0e10cSrcweir     public void addPropertyChangeListener(
369cdf0e10cSrcweir         String propertyName, XPropertyChangeListener listener)
370cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
371cdf0e10cSrcweir     {
372cdf0e10cSrcweir         // assert listener != null;
373cdf0e10cSrcweir         checkUnknown(propertyName);
374cdf0e10cSrcweir         boolean disp;
375cdf0e10cSrcweir         synchronized (this) {
376cdf0e10cSrcweir             disp = disposed;
377cdf0e10cSrcweir             if (!disp) {
378cdf0e10cSrcweir                 Vector v = (Vector) boundListeners.get(propertyName);
379cdf0e10cSrcweir                 if (v == null) {
380cdf0e10cSrcweir                     v = new Vector();
381cdf0e10cSrcweir                     boundListeners.put(propertyName, v);
382cdf0e10cSrcweir                 }
383cdf0e10cSrcweir                 v.add(listener);
384cdf0e10cSrcweir             }
385cdf0e10cSrcweir         }
386cdf0e10cSrcweir         if (disp) {
387cdf0e10cSrcweir             listener.disposing(new EventObject(object));
388cdf0e10cSrcweir         }
389cdf0e10cSrcweir     }
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     /**
392cdf0e10cSrcweir        Implements <code>
393cdf0e10cSrcweir        com.sun.star.beans.XPropertySet.removePropertyChangeListener</code>.
394cdf0e10cSrcweir     */
removePropertyChangeListener( String propertyName, XPropertyChangeListener listener)395cdf0e10cSrcweir     public void removePropertyChangeListener(
396cdf0e10cSrcweir         String propertyName, XPropertyChangeListener listener)
397cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         // assert listener != null;
400cdf0e10cSrcweir         checkUnknown(propertyName);
401cdf0e10cSrcweir         synchronized (this) {
402cdf0e10cSrcweir             if (boundListeners != null) {
403cdf0e10cSrcweir                 Vector v = (Vector) boundListeners.get(propertyName);
404cdf0e10cSrcweir                 if (v != null) {
405cdf0e10cSrcweir                     v.remove(listener);
406cdf0e10cSrcweir                 }
407cdf0e10cSrcweir             }
408cdf0e10cSrcweir         }
409cdf0e10cSrcweir     }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir     /**
412cdf0e10cSrcweir        Implements
413cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertySet.addVetoableChangeListener</code>.
414cdf0e10cSrcweir 
415cdf0e10cSrcweir        <p>If a listener is added more than once, it will receive all relevant
416cdf0e10cSrcweir        notifications multiple times.</p>
417cdf0e10cSrcweir     */
addVetoableChangeListener( String propertyName, XVetoableChangeListener listener)418cdf0e10cSrcweir     public void addVetoableChangeListener(
419cdf0e10cSrcweir         String propertyName, XVetoableChangeListener listener)
420cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         // assert listener != null;
423cdf0e10cSrcweir         checkUnknown(propertyName);
424cdf0e10cSrcweir         boolean disp;
425cdf0e10cSrcweir         synchronized (this) {
426cdf0e10cSrcweir             disp = disposed;
427cdf0e10cSrcweir             if (!disp) {
428cdf0e10cSrcweir                 Vector v = (Vector) vetoListeners.get(propertyName);
429cdf0e10cSrcweir                 if (v == null) {
430cdf0e10cSrcweir                     v = new Vector();
431cdf0e10cSrcweir                     vetoListeners.put(propertyName, v);
432cdf0e10cSrcweir                 }
433cdf0e10cSrcweir                 v.add(listener);
434cdf0e10cSrcweir             }
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir         if (disp) {
437cdf0e10cSrcweir             listener.disposing(new EventObject(object));
438cdf0e10cSrcweir         }
439cdf0e10cSrcweir     }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     /**
442cdf0e10cSrcweir        Implements <code>
443cdf0e10cSrcweir        com.sun.star.beans.XPropertySet.removeVetoableChangeListener</code>.
444cdf0e10cSrcweir     */
removeVetoableChangeListener( String propertyName, XVetoableChangeListener listener)445cdf0e10cSrcweir     public void removeVetoableChangeListener(
446cdf0e10cSrcweir         String propertyName, XVetoableChangeListener listener)
447cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
448cdf0e10cSrcweir     {
449cdf0e10cSrcweir         // assert listener != null;
450cdf0e10cSrcweir         checkUnknown(propertyName);
451cdf0e10cSrcweir         synchronized (this) {
452cdf0e10cSrcweir             if (vetoListeners != null) {
453cdf0e10cSrcweir                 Vector v = (Vector) vetoListeners.get(propertyName);
454cdf0e10cSrcweir                 if (v != null) {
455cdf0e10cSrcweir                     v.remove(listener);
456cdf0e10cSrcweir                 }
457cdf0e10cSrcweir             }
458cdf0e10cSrcweir         }
459cdf0e10cSrcweir     }
460cdf0e10cSrcweir 
461cdf0e10cSrcweir     /**
462cdf0e10cSrcweir        Implements
463cdf0e10cSrcweir        <code>com.sun.star.beans.XFastPropertySet.setFastPropertyValue</code>.
464cdf0e10cSrcweir     */
setFastPropertyValue(int handle, Object value)465cdf0e10cSrcweir     public void setFastPropertyValue(int handle, Object value)
466cdf0e10cSrcweir         throws UnknownPropertyException, PropertyVetoException,
467cdf0e10cSrcweir         com.sun.star.lang.IllegalArgumentException, WrappedTargetException
468cdf0e10cSrcweir     {
469cdf0e10cSrcweir         setProperty(translateHandle(handle), value, false, false, (short) 1);
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir     /**
473cdf0e10cSrcweir        Implements
474cdf0e10cSrcweir        <code>com.sun.star.beans.XFastPropertySet.getFastPropertyValue</code>.
475cdf0e10cSrcweir     */
getFastPropertyValue(int handle)476cdf0e10cSrcweir     public Object getFastPropertyValue(int handle)
477cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
478cdf0e10cSrcweir     {
479cdf0e10cSrcweir         return getProperty(translateHandle(handle), null);
480cdf0e10cSrcweir     }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir     /**
483cdf0e10cSrcweir        Implements
484cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertyAccess.getPropertyValues</code>.
485cdf0e10cSrcweir     */
getPropertyValues()486cdf0e10cSrcweir     public PropertyValue[] getPropertyValues() {
487cdf0e10cSrcweir         PropertyValue[] s = new PropertyValue[handleMap.length];
488cdf0e10cSrcweir         int n = 0;
489cdf0e10cSrcweir         for (int i = 0; i < handleMap.length; ++i) {
490cdf0e10cSrcweir             PropertyState[] state = new PropertyState[1];
491cdf0e10cSrcweir             Object value;
492cdf0e10cSrcweir             try {
493cdf0e10cSrcweir                 value = getProperty(handleMap[i], state);
494cdf0e10cSrcweir             } catch (UnknownPropertyException e) {
495cdf0e10cSrcweir                 continue;
496cdf0e10cSrcweir             } catch (WrappedTargetException e) {
497cdf0e10cSrcweir                 throw new WrappedTargetRuntimeException(
498cdf0e10cSrcweir                     e.getMessage(), object, e.TargetException);
499cdf0e10cSrcweir             }
500cdf0e10cSrcweir             s[n++] = new PropertyValue(handleMap[i], i, value, state[0]);
501cdf0e10cSrcweir         }
502cdf0e10cSrcweir         if (n < handleMap.length) {
503cdf0e10cSrcweir             PropertyValue[] s2 = new PropertyValue[n];
504cdf0e10cSrcweir             System.arraycopy(s, 0, s2, 0, n);
505cdf0e10cSrcweir             s = s2;
506cdf0e10cSrcweir         }
507cdf0e10cSrcweir         return s;
508cdf0e10cSrcweir     }
509cdf0e10cSrcweir 
510cdf0e10cSrcweir     /**
511cdf0e10cSrcweir        Implements
512cdf0e10cSrcweir        <code>com.sun.star.beans.XPropertyAccess.setPropertyValues</code>.
513cdf0e10cSrcweir     */
setPropertyValues(PropertyValue[] props)514cdf0e10cSrcweir     public void setPropertyValues(PropertyValue[] props)
515cdf0e10cSrcweir         throws UnknownPropertyException, PropertyVetoException,
516cdf0e10cSrcweir         com.sun.star.lang.IllegalArgumentException, WrappedTargetException
517cdf0e10cSrcweir     {
518cdf0e10cSrcweir         for (int i = 0; i < props.length; ++i) {
519cdf0e10cSrcweir             if (props[i].Handle != -1
520cdf0e10cSrcweir                 && !props[i].Name.equals(translateHandle(props[i].Handle)))
521cdf0e10cSrcweir             {
522cdf0e10cSrcweir                 throw new UnknownPropertyException(
523cdf0e10cSrcweir                     ("name " + props[i].Name + " does not match handle "
524cdf0e10cSrcweir                      + props[i].Handle),
525cdf0e10cSrcweir                     object);
526cdf0e10cSrcweir             }
527cdf0e10cSrcweir             setProperty(
528cdf0e10cSrcweir                 props[i].Name, props[i].Value,
529cdf0e10cSrcweir                 props[i].State == PropertyState.AMBIGUOUS_VALUE,
530cdf0e10cSrcweir                 props[i].State == PropertyState.DEFAULT_VALUE, (short) 0);
531cdf0e10cSrcweir         }
532cdf0e10cSrcweir     }
533cdf0e10cSrcweir 
534cdf0e10cSrcweir     /**
535cdf0e10cSrcweir        A class used by clients of {@link PropertySetMixin} when implementing UNO
536cdf0e10cSrcweir        interface type attribute setter functions.
537cdf0e10cSrcweir 
538cdf0e10cSrcweir        @see #prepareSet(String, Object, Object, PropertySetMixin.BoundListeners)
539cdf0e10cSrcweir     */
540cdf0e10cSrcweir     public static final class BoundListeners {
541cdf0e10cSrcweir         /**
542cdf0e10cSrcweir            The constructor.
543cdf0e10cSrcweir         */
BoundListeners()544cdf0e10cSrcweir         public BoundListeners() {}
545cdf0e10cSrcweir 
546cdf0e10cSrcweir         /**
547cdf0e10cSrcweir            Notifies any
548cdf0e10cSrcweir            <code>com.sun.star.beans.XPropertyChangeListener</code>s.
549cdf0e10cSrcweir 
550cdf0e10cSrcweir            @see #prepareSet(String, Object, Object,
551cdf0e10cSrcweir            PropertySetMixin.BoundListeners)
552cdf0e10cSrcweir         */
notifyListeners()553cdf0e10cSrcweir         public void notifyListeners() {
554cdf0e10cSrcweir             if (specificListeners != null) {
555cdf0e10cSrcweir                 for (Iterator i = specificListeners.iterator(); i.hasNext();) {
556cdf0e10cSrcweir                     try {
557cdf0e10cSrcweir                         ((XPropertyChangeListener) i.next()).propertyChange(
558cdf0e10cSrcweir                             event);
559cdf0e10cSrcweir                     } catch (DisposedException e) {}
560cdf0e10cSrcweir                 }
561cdf0e10cSrcweir             }
562cdf0e10cSrcweir             if (unspecificListeners != null) {
563cdf0e10cSrcweir                 for (Iterator i = unspecificListeners.iterator(); i.hasNext();)
564cdf0e10cSrcweir                 {
565cdf0e10cSrcweir                     try {
566cdf0e10cSrcweir                         ((XPropertyChangeListener) i.next()).propertyChange(
567cdf0e10cSrcweir                             event);
568cdf0e10cSrcweir                     } catch (DisposedException e) {}
569cdf0e10cSrcweir                 }
570cdf0e10cSrcweir             }
571cdf0e10cSrcweir         }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir         private Vector specificListeners = null;
574cdf0e10cSrcweir         private Vector unspecificListeners = null;
575cdf0e10cSrcweir         private PropertyChangeEvent event = null;
576cdf0e10cSrcweir     }
577cdf0e10cSrcweir 
getReflection(String typeName)578cdf0e10cSrcweir     private XIdlClass getReflection(String typeName) {
579cdf0e10cSrcweir         XIdlReflection refl;
580cdf0e10cSrcweir         try {
581cdf0e10cSrcweir             refl = UnoRuntime.queryInterface(
582cdf0e10cSrcweir                 XIdlReflection.class,
583cdf0e10cSrcweir                 context.getServiceManager().createInstanceWithContext(
584cdf0e10cSrcweir                     "com.sun.star.reflection.CoreReflection", context));
585cdf0e10cSrcweir         } catch (com.sun.star.uno.Exception e) {
586cdf0e10cSrcweir             throw new DeploymentException(
587cdf0e10cSrcweir                 ("component context fails to supply service"
588cdf0e10cSrcweir                  + " com.sun.star.reflection.CoreReflection: "
589cdf0e10cSrcweir                  + e.getMessage()),
590cdf0e10cSrcweir                 context);
591cdf0e10cSrcweir         }
592cdf0e10cSrcweir         try {
593cdf0e10cSrcweir             return refl.forName(typeName);
594cdf0e10cSrcweir         } finally {
595cdf0e10cSrcweir             XComponent comp = UnoRuntime.queryInterface(XComponent.class, refl);
596cdf0e10cSrcweir             if (comp != null) {
597cdf0e10cSrcweir                 comp.dispose();
598cdf0e10cSrcweir             }
599cdf0e10cSrcweir         }
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir 
initProperties( XTypeDescription type, HashMap map, ArrayList handleNames, HashSet seen)602cdf0e10cSrcweir     private void initProperties(
603cdf0e10cSrcweir         XTypeDescription type, HashMap map, ArrayList handleNames, HashSet seen)
604cdf0e10cSrcweir     {
605cdf0e10cSrcweir         XInterfaceTypeDescription2 ifc = UnoRuntime.queryInterface(
606cdf0e10cSrcweir             XInterfaceTypeDescription2.class, resolveTypedefs(type));
607cdf0e10cSrcweir         if (seen.add(ifc.getName())) {
608cdf0e10cSrcweir             XTypeDescription[] bases = ifc.getBaseTypes();
609cdf0e10cSrcweir             for (int i = 0; i < bases.length; ++i) {
610cdf0e10cSrcweir                 initProperties(bases[i], map, handleNames, seen);
611cdf0e10cSrcweir             }
612cdf0e10cSrcweir             XInterfaceMemberTypeDescription[] members = ifc.getMembers();
613cdf0e10cSrcweir             for (int i = 0; i < members.length; ++i) {
614cdf0e10cSrcweir                 if (members[i].getTypeClass() == TypeClass.INTERFACE_ATTRIBUTE)
615cdf0e10cSrcweir                 {
616cdf0e10cSrcweir                     XInterfaceAttributeTypeDescription2 attr =
617cdf0e10cSrcweir                         UnoRuntime.queryInterface(
618cdf0e10cSrcweir                             XInterfaceAttributeTypeDescription2.class,
619cdf0e10cSrcweir                             members[i]);
620cdf0e10cSrcweir                     short attrAttribs = 0;
621cdf0e10cSrcweir                     if (attr.isBound()) {
622cdf0e10cSrcweir                         attrAttribs |= PropertyAttribute.BOUND;
623cdf0e10cSrcweir                     }
624cdf0e10cSrcweir                     boolean setUnknown = false;
625cdf0e10cSrcweir                     if (attr.isReadOnly()) {
626cdf0e10cSrcweir                         attrAttribs |= PropertyAttribute.READONLY;
627cdf0e10cSrcweir                         setUnknown = true;
628cdf0e10cSrcweir                     }
629cdf0e10cSrcweir                     XCompoundTypeDescription[] excs = attr.getGetExceptions();
630cdf0e10cSrcweir                     boolean getUnknown = false;
631cdf0e10cSrcweir                     //XXX  Special interpretation of getter/setter exceptions
632cdf0e10cSrcweir                     // only works if the specified exceptions are of the exact
633cdf0e10cSrcweir                     // type, not of a supertype:
634cdf0e10cSrcweir                     for (int j = 0; j < excs.length; ++j) {
635cdf0e10cSrcweir                         if (excs[j].getName().equals(
636cdf0e10cSrcweir                                 "com.sun.star.beans.UnknownPropertyException"))
637cdf0e10cSrcweir                         {
638cdf0e10cSrcweir                             getUnknown = true;
639cdf0e10cSrcweir                             break;
640cdf0e10cSrcweir                         }
641cdf0e10cSrcweir                     }
642cdf0e10cSrcweir                     excs = attr.getSetExceptions();
643cdf0e10cSrcweir                     for (int j = 0; j < excs.length; ++j) {
644cdf0e10cSrcweir                         if (excs[j].getName().equals(
645cdf0e10cSrcweir                                 "com.sun.star.beans.UnknownPropertyException"))
646cdf0e10cSrcweir                         {
647cdf0e10cSrcweir                             setUnknown = true;
648cdf0e10cSrcweir                         } else if (excs[j].getName().equals(
649cdf0e10cSrcweir                                        "com.sun.star.beans."
650cdf0e10cSrcweir                                        + "PropertyVetoException"))
651cdf0e10cSrcweir                         {
652cdf0e10cSrcweir                             attrAttribs |= PropertyAttribute.CONSTRAINED;
653cdf0e10cSrcweir                         }
654cdf0e10cSrcweir                     }
655cdf0e10cSrcweir                     if (getUnknown && setUnknown) {
656cdf0e10cSrcweir                         attrAttribs |= PropertyAttribute.OPTIONAL;
657cdf0e10cSrcweir                     }
658cdf0e10cSrcweir                     XTypeDescription t = attr.getType();
659cdf0e10cSrcweir                     for (;;) {
660cdf0e10cSrcweir                         t = resolveTypedefs(t);
661cdf0e10cSrcweir                         short n;
662cdf0e10cSrcweir                         if (t.getName().startsWith(
663cdf0e10cSrcweir                                 "com.sun.star.beans.Ambiguous<"))
664cdf0e10cSrcweir                         {
665cdf0e10cSrcweir                             n = PropertyAttribute.MAYBEAMBIGUOUS;
666cdf0e10cSrcweir                         } else if (t.getName().startsWith(
667cdf0e10cSrcweir                                        "com.sun.star.beans.Defaulted<"))
668cdf0e10cSrcweir                         {
669cdf0e10cSrcweir                             n = PropertyAttribute.MAYBEDEFAULT;
670cdf0e10cSrcweir                         } else if (t.getName().startsWith(
671cdf0e10cSrcweir                                        "com.sun.star.beans.Optional<"))
672cdf0e10cSrcweir                         {
673cdf0e10cSrcweir                             n = PropertyAttribute.MAYBEVOID;
674cdf0e10cSrcweir                         } else {
675cdf0e10cSrcweir                             break;
676cdf0e10cSrcweir                         }
677cdf0e10cSrcweir                         attrAttribs |= n;
678cdf0e10cSrcweir                         t = (UnoRuntime.queryInterface(
679cdf0e10cSrcweir                                  XStructTypeDescription.class, t)).
680cdf0e10cSrcweir                             getTypeArguments()[0];
681cdf0e10cSrcweir                     }
682cdf0e10cSrcweir                     String name = members[i].getMemberName();
683cdf0e10cSrcweir                     boolean present = true;
684cdf0e10cSrcweir                     if (absentOptional != null) {
685cdf0e10cSrcweir                         for (int j = 0; j < absentOptional.length; ++j) {
686cdf0e10cSrcweir                             if (name.equals(absentOptional[j])) {
687cdf0e10cSrcweir                                 present = false;
688cdf0e10cSrcweir                                 break;
689cdf0e10cSrcweir                             }
690cdf0e10cSrcweir                         }
691cdf0e10cSrcweir                     }
692cdf0e10cSrcweir                     if (map.put(
693cdf0e10cSrcweir                             name,
694cdf0e10cSrcweir                             new PropertyData(
695cdf0e10cSrcweir                                 new Property(
696cdf0e10cSrcweir                                     name, handleNames.size(),
697cdf0e10cSrcweir                                     new Type(t.getName(), t.getTypeClass()),
698cdf0e10cSrcweir                                     attrAttribs),
699cdf0e10cSrcweir                                 present))
700cdf0e10cSrcweir                         != null)
701cdf0e10cSrcweir                     {
702cdf0e10cSrcweir                         throw new RuntimeException(
703cdf0e10cSrcweir                             "inconsistent UNO type registry");
704cdf0e10cSrcweir                     }
705cdf0e10cSrcweir                     handleNames.add(name);
706cdf0e10cSrcweir                 }
707cdf0e10cSrcweir             }
708cdf0e10cSrcweir         }
709cdf0e10cSrcweir     }
710cdf0e10cSrcweir 
translateHandle(int handle)711cdf0e10cSrcweir     private String translateHandle(int handle) throws UnknownPropertyException {
712cdf0e10cSrcweir         if (handle < 0 || handle >= handleMap.length) {
713cdf0e10cSrcweir             throw new UnknownPropertyException("bad handle " + handle, object);
714cdf0e10cSrcweir         }
715cdf0e10cSrcweir         return handleMap[handle];
716cdf0e10cSrcweir     }
717cdf0e10cSrcweir 
setProperty( String name, Object value, boolean isAmbiguous, boolean isDefaulted, short illegalArgumentPosition)718cdf0e10cSrcweir     private void setProperty(
719cdf0e10cSrcweir         String name, Object value, boolean isAmbiguous, boolean isDefaulted,
720cdf0e10cSrcweir         short illegalArgumentPosition)
721cdf0e10cSrcweir         throws UnknownPropertyException, PropertyVetoException,
722cdf0e10cSrcweir         com.sun.star.lang.IllegalArgumentException, WrappedTargetException
723cdf0e10cSrcweir     {
724cdf0e10cSrcweir         PropertyData p = (PropertyData) properties.get(name);
725cdf0e10cSrcweir         if (p == null) {
726cdf0e10cSrcweir             throw new UnknownPropertyException(name, object);
727cdf0e10cSrcweir         }
728cdf0e10cSrcweir         if ((isAmbiguous
729cdf0e10cSrcweir              && (p.property.Attributes & PropertyAttribute.MAYBEAMBIGUOUS) == 0)
730cdf0e10cSrcweir             || (isDefaulted
731cdf0e10cSrcweir                 && ((p.property.Attributes & PropertyAttribute.MAYBEDEFAULT)
732cdf0e10cSrcweir                     == 0)))
733cdf0e10cSrcweir         {
734cdf0e10cSrcweir             throw new com.sun.star.lang.IllegalArgumentException(
735cdf0e10cSrcweir                 ("flagging as ambiguous/defaulted non-ambiguous/defaulted"
736cdf0e10cSrcweir                  + " property " + name),
737cdf0e10cSrcweir                 object, illegalArgumentPosition);
738cdf0e10cSrcweir 
739cdf0e10cSrcweir         }
740cdf0e10cSrcweir         XIdlField2 f = UnoRuntime.queryInterface(
741cdf0e10cSrcweir             XIdlField2.class, idlClass.getField(name));
742cdf0e10cSrcweir         Object[] o = new Object[] {
743cdf0e10cSrcweir                 new Any(type, UnoRuntime.queryInterface(type, object)) };
744cdf0e10cSrcweir         Object v = wrapValue(
745cdf0e10cSrcweir             value,
746cdf0e10cSrcweir             UnoRuntime.queryInterface(
747cdf0e10cSrcweir                 XIdlField2.class, idlClass.getField(name)).getType(),
748cdf0e10cSrcweir             (p.property.Attributes & PropertyAttribute.MAYBEAMBIGUOUS) != 0,
749cdf0e10cSrcweir             isAmbiguous,
750cdf0e10cSrcweir             (p.property.Attributes & PropertyAttribute.MAYBEDEFAULT) != 0,
751cdf0e10cSrcweir             isDefaulted,
752cdf0e10cSrcweir             (p.property.Attributes & PropertyAttribute.MAYBEVOID) != 0);
753cdf0e10cSrcweir         try {
754cdf0e10cSrcweir             f.set(o, v);
755cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) {
756cdf0e10cSrcweir             if (e.ArgumentPosition == 1) {
757cdf0e10cSrcweir                 throw new com.sun.star.lang.IllegalArgumentException(
758cdf0e10cSrcweir                     e.getMessage(), object, illegalArgumentPosition);
759cdf0e10cSrcweir             } else {
760cdf0e10cSrcweir                 throw new RuntimeException(
761cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalArgumentException: "
762cdf0e10cSrcweir                     + e.getMessage());
763cdf0e10cSrcweir             }
764cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalAccessException e) {
765cdf0e10cSrcweir             //TODO  Clarify whether PropertyVetoException is the correct
766cdf0e10cSrcweir             // exception to throw when trying to set a read-only property:
767cdf0e10cSrcweir             throw new PropertyVetoException(
768cdf0e10cSrcweir                 "cannot set read-only property " + name, object);
769cdf0e10cSrcweir         } catch (WrappedTargetRuntimeException e) {
770cdf0e10cSrcweir             //FIXME  A WrappedTargetRuntimeException from XIdlField2.get is not
771cdf0e10cSrcweir             // guaranteed to originate directly within XIdlField2.get (and thus
772cdf0e10cSrcweir             // have the expected semantics); it might also be passed through
773cdf0e10cSrcweir             // from lower layers.
774cdf0e10cSrcweir             if (new Type(UnknownPropertyException.class).isSupertypeOf(
775cdf0e10cSrcweir                     AnyConverter.getType(e.TargetException))
776cdf0e10cSrcweir                 && (p.property.Attributes & PropertyAttribute.OPTIONAL) != 0)
777cdf0e10cSrcweir             {
778cdf0e10cSrcweir                 throw new UnknownPropertyException(name, object);
779cdf0e10cSrcweir             } else if (new Type(PropertyVetoException.class).isSupertypeOf(
780cdf0e10cSrcweir                            AnyConverter.getType(e.TargetException))
781cdf0e10cSrcweir                        && ((p.property.Attributes
782cdf0e10cSrcweir                             & PropertyAttribute.CONSTRAINED)
783cdf0e10cSrcweir                            != 0))
784cdf0e10cSrcweir             {
785cdf0e10cSrcweir                 throw new PropertyVetoException(name, object);
786cdf0e10cSrcweir             } else {
787cdf0e10cSrcweir                 throw new WrappedTargetException(
788cdf0e10cSrcweir                     e.getMessage(), object, e.TargetException);
789cdf0e10cSrcweir             }
790cdf0e10cSrcweir         }
791cdf0e10cSrcweir     }
792cdf0e10cSrcweir 
getProperty(String name, PropertyState[] state)793cdf0e10cSrcweir     Object getProperty(String name, PropertyState[] state)
794cdf0e10cSrcweir         throws UnknownPropertyException, WrappedTargetException
795cdf0e10cSrcweir     {
796cdf0e10cSrcweir         PropertyData p = (PropertyData) properties.get(name);
797cdf0e10cSrcweir         if (p == null) {
798cdf0e10cSrcweir             throw new UnknownPropertyException(name, object);
799cdf0e10cSrcweir         }
800cdf0e10cSrcweir         XIdlField2 field = UnoRuntime.queryInterface(
801cdf0e10cSrcweir             XIdlField2.class, idlClass.getField(name));
802cdf0e10cSrcweir         Object value;
803cdf0e10cSrcweir         try {
804cdf0e10cSrcweir             value = field.get(
805cdf0e10cSrcweir                 new Any(type, UnoRuntime.queryInterface(type, object)));
806cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) {
807cdf0e10cSrcweir             throw new RuntimeException(
808cdf0e10cSrcweir                 "unexpected com.sun.star.lang.IllegalArgumentException: "
809cdf0e10cSrcweir                 + e.getMessage());
810cdf0e10cSrcweir         } catch (WrappedTargetRuntimeException e) {
811cdf0e10cSrcweir             //FIXME  A WrappedTargetRuntimeException from XIdlField2.get is not
812cdf0e10cSrcweir             // guaranteed to originate directly within XIdlField2.get (and thus
813cdf0e10cSrcweir             // have the expected semantics); it might also be passed through
814cdf0e10cSrcweir             // from lower layers.
815cdf0e10cSrcweir             if (new Type(UnknownPropertyException.class).isSupertypeOf(
816cdf0e10cSrcweir                     AnyConverter.getType(e.TargetException))
817cdf0e10cSrcweir                 && (p.property.Attributes & PropertyAttribute.OPTIONAL) != 0)
818cdf0e10cSrcweir             {
819cdf0e10cSrcweir                 throw new UnknownPropertyException(name, object);
820cdf0e10cSrcweir             } else {
821cdf0e10cSrcweir                 throw new WrappedTargetException(
822cdf0e10cSrcweir                     e.getMessage(), object, e.TargetException);
823cdf0e10cSrcweir             }
824cdf0e10cSrcweir         }
825cdf0e10cSrcweir         boolean undoAmbiguous
826cdf0e10cSrcweir             = (p.property.Attributes & PropertyAttribute.MAYBEAMBIGUOUS) != 0;
827cdf0e10cSrcweir         boolean undoDefaulted
828cdf0e10cSrcweir             = (p.property.Attributes & PropertyAttribute.MAYBEDEFAULT) != 0;
829cdf0e10cSrcweir         boolean undoOptional
830cdf0e10cSrcweir             = (p.property.Attributes & PropertyAttribute.MAYBEVOID) != 0;
831cdf0e10cSrcweir         boolean isAmbiguous = false;
832cdf0e10cSrcweir         boolean isDefaulted = false;
833cdf0e10cSrcweir         while (undoAmbiguous || undoDefaulted || undoOptional) {
834cdf0e10cSrcweir             String typeName = AnyConverter.getType(value).getTypeName();
835cdf0e10cSrcweir             if (undoAmbiguous
836cdf0e10cSrcweir                 && typeName.startsWith("com.sun.star.beans.Ambiguous<"))
837cdf0e10cSrcweir             {
838cdf0e10cSrcweir                 XIdlClass ambiguous = getReflection(typeName);
839cdf0e10cSrcweir                 try {
840cdf0e10cSrcweir                     isAmbiguous = AnyConverter.toBoolean(
841cdf0e10cSrcweir                         UnoRuntime.queryInterface(
842cdf0e10cSrcweir                             XIdlField2.class,
843cdf0e10cSrcweir                             ambiguous.getField("IsAmbiguous")).get(value));
844cdf0e10cSrcweir                     value = UnoRuntime.queryInterface(
845cdf0e10cSrcweir                         XIdlField2.class,
846cdf0e10cSrcweir                         ambiguous.getField("Value")).get(value);
847cdf0e10cSrcweir                 } catch (com.sun.star.lang.IllegalArgumentException e) {
848cdf0e10cSrcweir                     throw new RuntimeException(
849cdf0e10cSrcweir                         "unexpected"
850cdf0e10cSrcweir                         + " com.sun.star.lang.IllegalArgumentException: "
851cdf0e10cSrcweir                         + e.getMessage());
852cdf0e10cSrcweir                 }
853cdf0e10cSrcweir                 undoAmbiguous = false;
854cdf0e10cSrcweir             } else if (undoDefaulted
855cdf0e10cSrcweir                        && typeName.startsWith("com.sun.star.beans.Defaulted<"))
856cdf0e10cSrcweir             {
857cdf0e10cSrcweir                 XIdlClass defaulted = getReflection(typeName);
858cdf0e10cSrcweir                 try {
859cdf0e10cSrcweir                     isDefaulted = AnyConverter.toBoolean(
860cdf0e10cSrcweir                         UnoRuntime.queryInterface(
861cdf0e10cSrcweir                             XIdlField2.class,
862cdf0e10cSrcweir                             defaulted.getField("IsDefaulted")).get(value));
863cdf0e10cSrcweir                     value = UnoRuntime.queryInterface(
864cdf0e10cSrcweir                         XIdlField2.class,
865cdf0e10cSrcweir                         defaulted.getField("Value")).get(value);
866cdf0e10cSrcweir                 } catch (com.sun.star.lang.IllegalArgumentException e) {
867cdf0e10cSrcweir                     throw new RuntimeException(
868cdf0e10cSrcweir                         "unexpected"
869cdf0e10cSrcweir                         + " com.sun.star.lang.IllegalArgumentException: "
870cdf0e10cSrcweir                         + e.getMessage());
871cdf0e10cSrcweir                 }
872cdf0e10cSrcweir                 undoDefaulted = false;
873cdf0e10cSrcweir             } else if (undoOptional
874cdf0e10cSrcweir                        && typeName.startsWith("com.sun.star.beans.Optional<"))
875cdf0e10cSrcweir             {
876cdf0e10cSrcweir                 XIdlClass optional = getReflection(typeName);
877cdf0e10cSrcweir                 try {
878cdf0e10cSrcweir                     boolean present = AnyConverter.toBoolean(
879cdf0e10cSrcweir                         UnoRuntime.queryInterface(
880cdf0e10cSrcweir                             XIdlField2.class,
881cdf0e10cSrcweir                             optional.getField("IsPresent")).get(value));
882cdf0e10cSrcweir                     if (!present) {
883cdf0e10cSrcweir                         value = Any.VOID;
884cdf0e10cSrcweir                         break;
885cdf0e10cSrcweir                     }
886cdf0e10cSrcweir                     value = UnoRuntime.queryInterface(
887cdf0e10cSrcweir                         XIdlField2.class,
888cdf0e10cSrcweir                         optional.getField("Value")).get(value);
889cdf0e10cSrcweir                 } catch (com.sun.star.lang.IllegalArgumentException e) {
890cdf0e10cSrcweir                     throw new RuntimeException(
891cdf0e10cSrcweir                         "unexpected"
892cdf0e10cSrcweir                         + " com.sun.star.lang.IllegalArgumentException: "
893cdf0e10cSrcweir                         + e.getMessage());
894cdf0e10cSrcweir                 }
895cdf0e10cSrcweir                 undoOptional = false;
896cdf0e10cSrcweir             } else {
897cdf0e10cSrcweir                 throw new RuntimeException(
898cdf0e10cSrcweir                     "unexpected type of attribute " + name);
899cdf0e10cSrcweir             }
900cdf0e10cSrcweir         }
901cdf0e10cSrcweir         if (state != null) {
902cdf0e10cSrcweir             //XXX  If isAmbiguous && isDefaulted, arbitrarily choose
903cdf0e10cSrcweir             // AMBIGUOUS_VALUE over DEFAULT_VALUE:
904cdf0e10cSrcweir             state[0] = isAmbiguous
905cdf0e10cSrcweir                 ? PropertyState.AMBIGUOUS_VALUE
906cdf0e10cSrcweir                 : isDefaulted
907cdf0e10cSrcweir                 ? PropertyState.DEFAULT_VALUE : PropertyState.DIRECT_VALUE;
908cdf0e10cSrcweir         }
909cdf0e10cSrcweir         return value;
910cdf0e10cSrcweir     }
911cdf0e10cSrcweir 
wrapValue( Object value, XIdlClass type, boolean wrapAmbiguous, boolean isAmbiguous, boolean wrapDefaulted, boolean isDefaulted, boolean wrapOptional)912cdf0e10cSrcweir     private Object wrapValue(
913cdf0e10cSrcweir         Object value, XIdlClass type, boolean wrapAmbiguous,
914cdf0e10cSrcweir         boolean isAmbiguous, boolean wrapDefaulted, boolean isDefaulted,
915cdf0e10cSrcweir         boolean wrapOptional)
916cdf0e10cSrcweir     {
917cdf0e10cSrcweir         // assert (wrapAmbiguous || !isAmbiguous)
918cdf0e10cSrcweir         //     && (wrapDefaulted || !isDefaulted);
919cdf0e10cSrcweir         if (wrapAmbiguous
920cdf0e10cSrcweir             && type.getName().startsWith("com.sun.star.beans.Ambiguous<"))
921cdf0e10cSrcweir         {
922cdf0e10cSrcweir             Object[] strct = new Object[1];
923cdf0e10cSrcweir             type.createObject(strct);
924cdf0e10cSrcweir             try {
925cdf0e10cSrcweir                 XIdlField2 field = UnoRuntime.queryInterface(
926cdf0e10cSrcweir                     XIdlField2.class, type.getField("Value"));
927cdf0e10cSrcweir                 field.set(
928cdf0e10cSrcweir                     strct,
929cdf0e10cSrcweir                     wrapValue(
930cdf0e10cSrcweir                         value, field.getType(), false, false, wrapDefaulted,
931cdf0e10cSrcweir                         isDefaulted, wrapOptional));
932cdf0e10cSrcweir                 UnoRuntime.queryInterface(
933cdf0e10cSrcweir                     XIdlField2.class, type.getField("IsAmbiguous")).set(
934cdf0e10cSrcweir                         strct, new Boolean(isAmbiguous));
935cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalArgumentException e) {
936cdf0e10cSrcweir                 throw new RuntimeException(
937cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalArgumentException: "
938cdf0e10cSrcweir                     + e.getMessage());
939cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalAccessException e) {
940cdf0e10cSrcweir                 throw new RuntimeException(
941cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalAccessException: "
942cdf0e10cSrcweir                     + e.getMessage());
943cdf0e10cSrcweir             }
944cdf0e10cSrcweir             return strct[0];
945cdf0e10cSrcweir         } else if (wrapDefaulted
946cdf0e10cSrcweir                    && type.getName().startsWith(
947cdf0e10cSrcweir                        "com.sun.star.beans.Defaulted<"))
948cdf0e10cSrcweir         {
949cdf0e10cSrcweir             Object[] strct = new Object[1];
950cdf0e10cSrcweir             type.createObject(strct);
951cdf0e10cSrcweir             try {
952cdf0e10cSrcweir                 XIdlField2 field = UnoRuntime.queryInterface(
953cdf0e10cSrcweir                     XIdlField2.class, type.getField("Value"));
954cdf0e10cSrcweir                 field.set(
955cdf0e10cSrcweir                     strct,
956cdf0e10cSrcweir                     wrapValue(
957cdf0e10cSrcweir                         value, field.getType(), wrapAmbiguous, isAmbiguous,
958cdf0e10cSrcweir                         false, false, wrapOptional));
959cdf0e10cSrcweir                 UnoRuntime.queryInterface(
960cdf0e10cSrcweir                     XIdlField2.class, type.getField("IsDefaulted")).set(
961cdf0e10cSrcweir                         strct, new Boolean(isDefaulted));
962cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalArgumentException e) {
963cdf0e10cSrcweir                 throw new RuntimeException(
964cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalArgumentException: "
965cdf0e10cSrcweir                     + e.getMessage());
966cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalAccessException e) {
967cdf0e10cSrcweir                 throw new RuntimeException(
968cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalAccessException: "
969cdf0e10cSrcweir                     + e.getMessage());
970cdf0e10cSrcweir             }
971cdf0e10cSrcweir             return strct[0];
972cdf0e10cSrcweir         } else if (wrapOptional
973cdf0e10cSrcweir                    && type.getName().startsWith("com.sun.star.beans.Optional<"))
974cdf0e10cSrcweir         {
975cdf0e10cSrcweir             Object[] strct = new Object[1];
976cdf0e10cSrcweir             type.createObject(strct);
977cdf0e10cSrcweir             boolean present = !AnyConverter.isVoid(value);
978cdf0e10cSrcweir             try {
979cdf0e10cSrcweir                 UnoRuntime.queryInterface(
980cdf0e10cSrcweir                     XIdlField2.class, type.getField("IsPresent")).set(
981cdf0e10cSrcweir                         strct, new Boolean(present));
982cdf0e10cSrcweir                 if (present) {
983cdf0e10cSrcweir                     XIdlField2 field = UnoRuntime.queryInterface(
984cdf0e10cSrcweir                         XIdlField2.class, type.getField("Value"));
985cdf0e10cSrcweir                     field.set(
986cdf0e10cSrcweir                         strct,
987cdf0e10cSrcweir                         wrapValue(
988cdf0e10cSrcweir                             value, field.getType(), wrapAmbiguous, isAmbiguous,
989cdf0e10cSrcweir                             wrapDefaulted, isDefaulted, false));
990cdf0e10cSrcweir                 }
991cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalArgumentException e) {
992cdf0e10cSrcweir                 throw new RuntimeException(
993cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalArgumentException: "
994cdf0e10cSrcweir                     + e.getMessage());
995cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalAccessException e) {
996cdf0e10cSrcweir                 throw new RuntimeException(
997cdf0e10cSrcweir                     "unexpected com.sun.star.lang.IllegalAccessException: "
998cdf0e10cSrcweir                     + e.getMessage());
999cdf0e10cSrcweir             }
1000cdf0e10cSrcweir             return strct[0];
1001cdf0e10cSrcweir         } else {
1002cdf0e10cSrcweir             if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
1003cdf0e10cSrcweir                 throw new RuntimeException("unexpected type of attribute");
1004cdf0e10cSrcweir             }
1005cdf0e10cSrcweir             return value;
1006cdf0e10cSrcweir         }
1007cdf0e10cSrcweir     }
1008cdf0e10cSrcweir 
resolveTypedefs(XTypeDescription type)1009cdf0e10cSrcweir     private static XTypeDescription resolveTypedefs(XTypeDescription type) {
1010cdf0e10cSrcweir         while (type.getTypeClass() == TypeClass.TYPEDEF) {
1011cdf0e10cSrcweir             type = UnoRuntime.queryInterface(
1012cdf0e10cSrcweir                 XIndirectTypeDescription.class, type).getReferencedType();
1013cdf0e10cSrcweir         }
1014cdf0e10cSrcweir         return type;
1015cdf0e10cSrcweir     }
1016cdf0e10cSrcweir 
get(Object object, String propertyName)1017cdf0e10cSrcweir     private PropertyData get(Object object, String propertyName)
1018cdf0e10cSrcweir         throws UnknownPropertyException
1019cdf0e10cSrcweir     {
1020cdf0e10cSrcweir         PropertyData p = (PropertyData) properties.get(propertyName);
1021cdf0e10cSrcweir         if (p == null || !p.present) {
1022cdf0e10cSrcweir             throw new UnknownPropertyException(propertyName, object);
1023cdf0e10cSrcweir         }
1024cdf0e10cSrcweir         return p;
1025cdf0e10cSrcweir     }
1026cdf0e10cSrcweir 
checkUnknown(String propertyName)1027cdf0e10cSrcweir     private void checkUnknown(String propertyName)
1028cdf0e10cSrcweir         throws UnknownPropertyException
1029cdf0e10cSrcweir     {
1030cdf0e10cSrcweir         if (!propertyName.equals("")) {
1031cdf0e10cSrcweir             get(this, propertyName);
1032cdf0e10cSrcweir         }
1033cdf0e10cSrcweir     }
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir     private static final class PropertyData {
PropertyData(Property property, boolean present)1036cdf0e10cSrcweir         public PropertyData(Property property, boolean present) {
1037cdf0e10cSrcweir             this.property = property;
1038cdf0e10cSrcweir             this.present = present;
1039cdf0e10cSrcweir         }
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir         public final Property property;
1042cdf0e10cSrcweir         public final boolean present;
1043cdf0e10cSrcweir     }
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir     private final class Info extends WeakBase implements XPropertySetInfo
1046cdf0e10cSrcweir     {
Info(Map properties)1047cdf0e10cSrcweir         public Info(Map properties) {
1048cdf0e10cSrcweir             this.properties = properties;
1049cdf0e10cSrcweir         }
1050cdf0e10cSrcweir 
getProperties()1051cdf0e10cSrcweir         public Property[] getProperties() {
1052cdf0e10cSrcweir             ArrayList al = new ArrayList(properties.size());
1053cdf0e10cSrcweir             for (Iterator i = properties.values().iterator(); i.hasNext();) {
1054cdf0e10cSrcweir                 PropertyData p = (PropertyData) i.next();
1055cdf0e10cSrcweir                 if (p.present) {
1056cdf0e10cSrcweir                     al.add(p.property);
1057cdf0e10cSrcweir                 }
1058cdf0e10cSrcweir             }
1059cdf0e10cSrcweir             return (Property[]) al.toArray(new Property[al.size()]);
1060cdf0e10cSrcweir         }
1061cdf0e10cSrcweir 
getPropertyByName(String name)1062cdf0e10cSrcweir         public Property getPropertyByName(String name)
1063cdf0e10cSrcweir             throws UnknownPropertyException
1064cdf0e10cSrcweir         {
1065cdf0e10cSrcweir             return get(this, name).property;
1066cdf0e10cSrcweir         }
1067cdf0e10cSrcweir 
hasPropertyByName(String name)1068cdf0e10cSrcweir         public boolean hasPropertyByName(String name) {
1069cdf0e10cSrcweir             PropertyData p = (PropertyData) properties.get(name);
1070cdf0e10cSrcweir             return p != null && p.present;
1071cdf0e10cSrcweir         }
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir         private final Map properties; // from String to Property
1074cdf0e10cSrcweir     }
1075cdf0e10cSrcweir 
1076cdf0e10cSrcweir     private final XComponentContext context;
1077cdf0e10cSrcweir     private final XInterface object;
1078cdf0e10cSrcweir     private final Type type;
1079cdf0e10cSrcweir     private final String[] absentOptional;
1080cdf0e10cSrcweir     private final XIdlClass idlClass;
1081cdf0e10cSrcweir     private final Map properties; // from String to Property
1082cdf0e10cSrcweir     private final String[] handleMap;
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir     private HashMap boundListeners = new HashMap();
1085cdf0e10cSrcweir         // from String to Vector of XPropertyChangeListener
1086cdf0e10cSrcweir     private HashMap vetoListeners = new HashMap();
1087cdf0e10cSrcweir         // from String to Vector of XVetoableChangeListener
1088cdf0e10cSrcweir     private boolean disposed = false;
1089cdf0e10cSrcweir }
1090