xref: /trunk/main/javaunohelper/com/sun/star/lib/uno/helper/PropertySet.java (revision 3309286857f19787ae62bd793a98b5af4edd2ad3)
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
10cdf0e10cSrcweir  *
11a5b190bfSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
20a5b190bfSAndrew Rist  *************************************************************/
21a5b190bfSAndrew Rist 
22a5b190bfSAndrew Rist 
23cdf0e10cSrcweir package com.sun.star.lib.uno.helper;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import com.sun.star.uno.Type;
26cdf0e10cSrcweir import com.sun.star.lang.EventObject;
27cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetException;
28cdf0e10cSrcweir import com.sun.star.uno.TypeClass;
29cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
30cdf0e10cSrcweir import com.sun.star.uno.XInterface;
31cdf0e10cSrcweir import com.sun.star.uno.Any;
32cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
33cdf0e10cSrcweir import com.sun.star.beans.XPropertyChangeListener;
34cdf0e10cSrcweir import com.sun.star.beans.XVetoableChangeListener;
35cdf0e10cSrcweir import com.sun.star.beans.PropertyChangeEvent;
36cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
37cdf0e10cSrcweir import com.sun.star.beans.Property;
38cdf0e10cSrcweir import com.sun.star.beans.PropertyAttribute;
39cdf0e10cSrcweir import com.sun.star.beans.UnknownPropertyException;
40cdf0e10cSrcweir import com.sun.star.beans.XPropertiesChangeListener;
41cdf0e10cSrcweir import com.sun.star.beans.XPropertySetInfo;
42cdf0e10cSrcweir import com.sun.star.beans.XFastPropertySet;
43cdf0e10cSrcweir import com.sun.star.beans.PropertyVetoException;
44cdf0e10cSrcweir import com.sun.star.beans.XMultiPropertySet;
45cdf0e10cSrcweir import java.util.Iterator;
46cdf0e10cSrcweir import java.util.Collection;
47cdf0e10cSrcweir import java.util.HashMap;
48cdf0e10cSrcweir import java.lang.reflect.Field;
49cdf0e10cSrcweir import com.sun.star.lang.DisposedException;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 
52cdf0e10cSrcweir /** This class is an implementation of the interfaces com.sun.star.beans.XPropertySet,
53cdf0e10cSrcweir  *  com.sun.star.beans.XFastPropertySet and com.sun.star.beans.XMultiPropertySet. This
54cdf0e10cSrcweir  *  class has to be inherited to be used. The values of properties are stored in member
55cdf0e10cSrcweir  *  variables of the inheriting class. By overriding the methods
56cdf0e10cSrcweir  *  {@link #convertPropertyValue convertPropertyValue},
57cdf0e10cSrcweir  *  {@link #setPropertyValueNoBroadcast setPropertyValueNoBroadcast} and
58cdf0e10cSrcweir  *  {@link #getPropertyValue(Property)} one can determine how
59cdf0e10cSrcweir  *  property values are stored.
60cdf0e10cSrcweir  *  When using the supplied implementations of this class then the member variables which
61cdf0e10cSrcweir  *  hold property values have to be declared in the class which inherits last in the inheriting
62cdf0e10cSrcweir  *  chain and they have to be public<p>
63cdf0e10cSrcweir  *  Properties have to be registered by one of the registerProperty methods. They take among other
64cdf0e10cSrcweir  *  arguments an Object named <em>id</em> which has to be a String that represents the name of
65cdf0e10cSrcweir  *  the member variable. The registering has to occur in the constructor of the inheriting class.
66cdf0e10cSrcweir  *  It is no allowed to add or change properties later on.<p>
67cdf0e10cSrcweir  *  Example:
68cdf0e10cSrcweir  *  <pre>
69cdf0e10cSrcweir  *  public class Foo extends PropertySet
70cdf0e10cSrcweir  *  {
71cdf0e10cSrcweir  *      protected int intProp;
72cdf0e10cSrcweir  *
73cdf0e10cSrcweir  *      public Foo()
74cdf0e10cSrcweir  *      {
75cdf0e10cSrcweir  *          registerProperty("PropertyA", 0, new Type(int.class), (short)0, "intProp");
76cdf0e10cSrcweir  *      }
77cdf0e10cSrcweir  *  }
78cdf0e10cSrcweir  *
79cdf0e10cSrcweir  *  </pre>
80cdf0e10cSrcweir  */
81cdf0e10cSrcweir public class PropertySet extends ComponentBase implements XPropertySet, XFastPropertySet,
82cdf0e10cSrcweir XMultiPropertySet
83cdf0e10cSrcweir {
84cdf0e10cSrcweir     private HashMap _nameToPropertyMap;
85cdf0e10cSrcweir     private HashMap _handleToPropertyMap;
86cdf0e10cSrcweir     private HashMap _propertyToIdMap;
87cdf0e10cSrcweir     private Property[] arProperties;
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     private int lastHandle= 1;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir     protected XPropertySetInfo propertySetInfo;
92cdf0e10cSrcweir     protected MultiTypeInterfaceContainer aBoundLC= new MultiTypeInterfaceContainer();
93cdf0e10cSrcweir     protected MultiTypeInterfaceContainer aVetoableLC= new MultiTypeInterfaceContainer();
PropertySet()94cdf0e10cSrcweir     public PropertySet()
95cdf0e10cSrcweir     {
96cdf0e10cSrcweir         super();
97cdf0e10cSrcweir         initMappings();
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     /** Registers a property with this helper class and associates the argument <em>id</em> with it.
101cdf0e10cSrcweir      *  <em>id</em> is used to identify the storage of the property value. How property values are stored
102cdf0e10cSrcweir      *  and retrieved is determined by the methods {@link #convertPropertyValue convertPropertyValue},
103cdf0e10cSrcweir      *  {@link #setPropertyValueNoBroadcast setPropertyValueNoBroadcast} and {@link #getPropertyValue(Property) getPropertyValue}
104cdf0e10cSrcweir      *  These methods expect <em>id</em> to be a java.lang.String which represents the name of a member variable
105cdf0e10cSrcweir      *  which holds the property value.
106cdf0e10cSrcweir      *  Only properties which are registered can be accessed. Registration has to occur during
10780c1851dSDamjan Jovanovic      *  initialization of the inheriting class (i.e. within the constructor).
108cdf0e10cSrcweir      *  @param prop The property to be registered.
109cdf0e10cSrcweir      *  @param id Identifies the properties storage.
110cdf0e10cSrcweir      *  @see #getPropertyId
111cdf0e10cSrcweir      */
registerProperty(Property prop, Object id)112cdf0e10cSrcweir     protected void registerProperty(Property prop, Object id)
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         putProperty(prop);
115cdf0e10cSrcweir         assignPropertyId(prop, id);
116cdf0e10cSrcweir     }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     /** Registers a property with this helper class and associates the argument id with it.
119cdf0e10cSrcweir      *  It does the same as {@link #registerProperty(Property, Object)}. The first four
120cdf0e10cSrcweir      *  arguments are used to construct a Property object.
121cdf0e10cSrcweir      *  Registration has to occur during
12280c1851dSDamjan Jovanovic      *  initialization of the inheriting class (i.e. within the constructor)
123cdf0e10cSrcweir      *  @param name The property's name (Property.Name).
124cdf0e10cSrcweir      *  @param handle The property's handle (Property.Handle).
125e0f9f944SDamjan Jovanovic      *  @param type The property's type (Property.Type).
126cdf0e10cSrcweir      *  @param attributes The property's attributes (Property.Attributes).
127cdf0e10cSrcweir      *  @param id Identifies the property's storage.
128cdf0e10cSrcweir      */
registerProperty(String name, int handle, Type type, short attributes, Object id)129cdf0e10cSrcweir     protected void registerProperty(String name, int handle, Type type, short attributes, Object id)
130cdf0e10cSrcweir     {
131cdf0e10cSrcweir         Property p= new Property(name, handle, type, attributes);
132cdf0e10cSrcweir         registerProperty(p, id);
133cdf0e10cSrcweir     }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir     /** Registers a property with this class and associates the argument id with it.
136cdf0e10cSrcweir      *  It does the same as {@link #registerProperty(Property, Object)}. The first three
137cdf0e10cSrcweir      *  arguments are used to construct a Property object. The value for the Property.Handle
138cdf0e10cSrcweir      *  is generated and does not have to be specified here. Use this method for registering
139cdf0e10cSrcweir      *  a property if you do not care about the Property's handles.
140cdf0e10cSrcweir      *  Registration has to occur during
141a8f4084dSMatthias Seidel      *  initialization of the inheriting class (i.e. within the constructor).
142cdf0e10cSrcweir      *  @param name The property's name (Property.Name).
143e0f9f944SDamjan Jovanovic      *  @param type The property's type (Property.Type).
144cdf0e10cSrcweir      *  @param attributes The property's attributes (Property.Attributes).
145cdf0e10cSrcweir      *  @param id Identifies the property's storage.
146cdf0e10cSrcweir      */
registerProperty(String name, Type type, short attributes, Object id)147cdf0e10cSrcweir     protected void registerProperty(String name, Type type, short attributes, Object id)
148cdf0e10cSrcweir     {
149cdf0e10cSrcweir         Property p= new Property(name, lastHandle++, type, attributes);
150cdf0e10cSrcweir         registerProperty(p, id);
151cdf0e10cSrcweir     }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir     /** Registers a property with this class. This method expects that property values
154cdf0e10cSrcweir      *  are stored in member variables as is the case if the methods convertPropertyValue,
155cdf0e10cSrcweir      *  setPropertyValueNoBroadcast and getPropertyValue(Property) are not overridden.
156cdf0e10cSrcweir      *  It is presumed that the type of the member variable
157cdf0e10cSrcweir      *  corresponds Property.Type. For example, if the TypeClass of Property.Type is to be
158cdf0e10cSrcweir      *  a TypeClass.SHORT then the member must be a short or java.lang.Short.
159cdf0e10cSrcweir      *  The handle for the property is generated.<br>
160cdf0e10cSrcweir      *  If there is no member with the specified name or if the member has an incompatible type
161cdf0e10cSrcweir      *  then a com.sun.star.uno.RuntimeException is thrown.
162cdf0e10cSrcweir      *  @param propertyName The name of the property.
163cdf0e10cSrcweir      *  @param memberName The name of the member variable that holds the value of the property.
164cdf0e10cSrcweir      *  @param attributes The property attributes.
165cdf0e10cSrcweir      */
registerProperty(String propertyName, String memberName, short attributes)166cdf0e10cSrcweir     protected void registerProperty(String propertyName, String memberName, short attributes)
167cdf0e10cSrcweir     {
168cdf0e10cSrcweir         Field propField= null;
169cdf0e10cSrcweir         try
170cdf0e10cSrcweir         {
171cdf0e10cSrcweir             propField= getClass().getDeclaredField(memberName);
172cdf0e10cSrcweir         }
173cdf0e10cSrcweir         catch (NoSuchFieldException e)
174cdf0e10cSrcweir         {
175cdf0e10cSrcweir             throw new com.sun.star.uno.RuntimeException("there is no member variable: " + memberName);
176cdf0e10cSrcweir         }
177cdf0e10cSrcweir         Class cl= propField.getType();
178cdf0e10cSrcweir         Type t= new Type(cl);
179cdf0e10cSrcweir         if (t.getTypeClass() != TypeClass.UNKNOWN)
180cdf0e10cSrcweir         {
181cdf0e10cSrcweir             Property p= new Property(propertyName, lastHandle++,  t, attributes);
182cdf0e10cSrcweir             registerProperty(p,memberName);
183cdf0e10cSrcweir         }
184cdf0e10cSrcweir         else
185cdf0e10cSrcweir             throw new com.sun.star.uno.RuntimeException("the member has an unknown type: " + memberName);
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir 
188cdf0e10cSrcweir     /** Registers a property with this class.
189cdf0e10cSrcweir      *  It is presumed that the name of property is equal to the name of the member variable
190cdf0e10cSrcweir      *  that holds the property value.
191cdf0e10cSrcweir      *  @param propertyName The name of the property and the member variable that holds the property's value.
192cdf0e10cSrcweir      *  @param attributes The property attributes.
193cdf0e10cSrcweir      *  @see #registerProperty(String, String, short)
194cdf0e10cSrcweir      */
registerProperty(String propertyName, short attributes)195cdf0e10cSrcweir     protected void registerProperty(String propertyName, short attributes)
196cdf0e10cSrcweir     {
197cdf0e10cSrcweir         registerProperty(propertyName, propertyName, attributes);
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     /** Returns the Property object for a given property name or null if that property does
201cdf0e10cSrcweir      *  not exists (i.e. it has not been registered). Override this method
202cdf0e10cSrcweir      *  if you want to implement your own mapping from property names to Property objects.
203cdf0e10cSrcweir      *  Then you also have to override {@link #initMappings}, {@link #getProperties()} and
204cdf0e10cSrcweir      *  {@link #putProperty(Property)}.
205cdf0e10cSrcweir      *  @param propertyName The name of the property (Property.Name)
206cdf0e10cSrcweir      *  @return The Property object with the name <em>propertyName</em>.
207cdf0e10cSrcweir      */
getProperty(String propertyName)208cdf0e10cSrcweir     protected Property getProperty(String propertyName)
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir         return (Property) _nameToPropertyMap.get(propertyName);
211cdf0e10cSrcweir     }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     /** Returns the Property object with a handle (Property.Handle) as specified by the argument
214cdf0e10cSrcweir      *  <em>nHandle</em>. The method returns null if there is no such property (i.e. it has not
215cdf0e10cSrcweir      *  been registered). Override this method if you want to implement your own mapping from handles
216cdf0e10cSrcweir      *  to Property objects. Then you also have to override {@link #initMappings}, {@link #putProperty(Property)}.
217cdf0e10cSrcweir      *  @param nHandle The handle of the property (Property.Handle).
218cdf0e10cSrcweir      *  @return The Property object with the handle <em>nHandle</em>
219cdf0e10cSrcweir      */
getPropertyByHandle(int nHandle)220cdf0e10cSrcweir     protected Property getPropertyByHandle(int nHandle)
221cdf0e10cSrcweir     {
2225b5659a7SDamjan Jovanovic         return (Property) _handleToPropertyMap.get(nHandle);
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     /** Returns an array of all Property objects or an array of length null if there
226cdf0e10cSrcweir      *  are no properties. Override this method if you want to implement your own mapping from names
227cdf0e10cSrcweir      *  to Property objects. Then you also have to override {@link #initMappings}, {@link #getProperty(String)} and
228cdf0e10cSrcweir      *  {@link #putProperty}.
229cdf0e10cSrcweir      *  @return Array of all Property objects.
230cdf0e10cSrcweir      */
getProperties()231cdf0e10cSrcweir     protected Property[] getProperties()
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         if (arProperties == null)
234cdf0e10cSrcweir         {
235cdf0e10cSrcweir             Collection values= _nameToPropertyMap.values();
236cdf0e10cSrcweir                 arProperties= (Property[]) values.toArray(new Property[_nameToPropertyMap.size()]);
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir         return arProperties;
239cdf0e10cSrcweir     }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir     /** Stores a Property object so that it can be retrieved subsequently by
242cdf0e10cSrcweir      *  {@link #getProperty(String)},{@link #getProperties()},{@link #getPropertyByHandle(int)}.
243cdf0e10cSrcweir      *  Override this method if you want to implement your own mapping from handles
244cdf0e10cSrcweir      *  to Property objects and names to Property objects. Then you also need to override {@link #initMappings},
245cdf0e10cSrcweir      *  {@link #getProperty(String)},{@link #getProperties()},{@link #getPropertyByHandle(int)}.
246cdf0e10cSrcweir      *  @param prop The Property object that is to be stored.
247cdf0e10cSrcweir      */
putProperty(Property prop)248cdf0e10cSrcweir     protected void putProperty(Property prop)
249cdf0e10cSrcweir     {
250cdf0e10cSrcweir         _nameToPropertyMap.put(prop.Name, prop);
251cdf0e10cSrcweir         if (prop.Handle != -1)
2525b5659a7SDamjan Jovanovic             _handleToPropertyMap.put(prop.Handle, prop);
253cdf0e10cSrcweir     }
254cdf0e10cSrcweir 
25580c1851dSDamjan Jovanovic     /** Assigns an identifier object to a Property object so that the identifier
25680c1851dSDamjan Jovanovic      *  can be obtained by {@link #getPropertyId getPropertyId} later on. The identifier
257cdf0e10cSrcweir      *  is used to specify a certain storage for the property's value. If you do not
258cdf0e10cSrcweir      *  override {@link #setPropertyValueNoBroadcast setPropertyValueNoBroadcast} or {@link #getPropertyValue(Property)}
259cdf0e10cSrcweir      *  then the argument <em>id</em> has to be a java.lang.String that equals the name of
260cdf0e10cSrcweir      *  the member variable that holds the Property's value.
261cdf0e10cSrcweir      *  Override this method if you want to implement your own mapping from Property objects to ids or
262cdf0e10cSrcweir      *  if you need ids of a type other then java.lang.String.
263cdf0e10cSrcweir      *  Then you also need to override {@link #initMappings initMappings} and {@link #getPropertyId getPropertyId}.
264cdf0e10cSrcweir      *  @param prop The Property object that is being assigned an id.
265cdf0e10cSrcweir      *  @param id The object which identifies the storage used for the property's value.
266cdf0e10cSrcweir      *  @see #registerProperty(Property, Object)
267cdf0e10cSrcweir      */
assignPropertyId(Property prop, Object id)268cdf0e10cSrcweir     protected void assignPropertyId(Property prop, Object id)
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir        if (id instanceof String && ((String) id).equals("") == false)
271cdf0e10cSrcweir             _propertyToIdMap.put(prop, id);
272cdf0e10cSrcweir     }
273cdf0e10cSrcweir 
27480c1851dSDamjan Jovanovic     /** Returns the identifier object for a certain Property. The object must have been
275cdf0e10cSrcweir      *  previously assigned to the Property object by {@link #assignPropertyId assignPropertyId}.
276cdf0e10cSrcweir      *  Override this method if you want to implement your own mapping from Property objects to ids.
277cdf0e10cSrcweir      *  Then you also need to override {@link #initMappings initMappings} and {@link #assignPropertyId assignPropertyId}.
278cdf0e10cSrcweir      *  @param prop The property for which the id is to be retrieved.
279cdf0e10cSrcweir      *  @return The id object that identifies the storage used for the property's value.
280cdf0e10cSrcweir      *  @see #registerProperty(Property, Object)
281cdf0e10cSrcweir      */
getPropertyId(Property prop)282cdf0e10cSrcweir     protected Object getPropertyId(Property prop)
283cdf0e10cSrcweir     {
284cdf0e10cSrcweir         return _propertyToIdMap.get(prop);
285cdf0e10cSrcweir     }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     /** Initializes data structures used for mappings of property names to property object,
288cdf0e10cSrcweir      *  property handles to property objects and property objects to id objects.
289cdf0e10cSrcweir      *  Override this method if you want to implement your own mappings. Then you also need to
290cdf0e10cSrcweir      *  override {@link #putProperty putProperty},{@link #getProperty getProperty}, {@link #getPropertyByHandle},
291cdf0e10cSrcweir      *  {@link #assignPropertyId assignPropertyId} and {@link #getPropertyId getPropertyId}.
292cdf0e10cSrcweir      */
initMappings()293cdf0e10cSrcweir     protected void initMappings()
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir        _nameToPropertyMap= new HashMap();
296cdf0e10cSrcweir        _handleToPropertyMap= new HashMap();
297cdf0e10cSrcweir        _propertyToIdMap= new HashMap();
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     /** Makes sure that listeners which are kept in aBoundLC (XPropertyChangeListener) and aVetoableLC
30180c1851dSDamjan Jovanovic      *  (XVetoableChangeListener) receive a disposing call. Also those listeners are released.
302cdf0e10cSrcweir      */
postDisposing()303cdf0e10cSrcweir     protected void postDisposing()
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         // Create an event with this as sender
306cdf0e10cSrcweir         EventObject aEvt= new EventObject(this);
307cdf0e10cSrcweir 
30880c1851dSDamjan Jovanovic         // inform all listeners to release this object
309cdf0e10cSrcweir         aBoundLC.disposeAndClear(aEvt);
310cdf0e10cSrcweir         aVetoableLC.disposeAndClear(aEvt);
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
addPropertyChangeListener(String str, XPropertyChangeListener xPropertyChangeListener)314cdf0e10cSrcweir     synchronized public void addPropertyChangeListener(String str, XPropertyChangeListener xPropertyChangeListener)
315cdf0e10cSrcweir     throws UnknownPropertyException, WrappedTargetException
316cdf0e10cSrcweir     {
317cdf0e10cSrcweir         // only add listeners if you are not disposed
318cdf0e10cSrcweir         if (! bInDispose && ! bDisposed)
319cdf0e10cSrcweir         {
320cdf0e10cSrcweir             if (str.length() > 0)
321cdf0e10cSrcweir             {
322cdf0e10cSrcweir                 Property prop= getProperty(str);
323cdf0e10cSrcweir                 if (prop == null)
324cdf0e10cSrcweir                     throw new UnknownPropertyException("Property " + str + " is unknown");
325cdf0e10cSrcweir 
326cdf0e10cSrcweir                 // Add listener for a certain property
327cdf0e10cSrcweir                 if ((prop.Attributes & PropertyAttribute.BOUND) > 0)
328cdf0e10cSrcweir                     aBoundLC.addInterface(str, xPropertyChangeListener);
329cdf0e10cSrcweir                 else
330cdf0e10cSrcweir                     //ignore silently
331cdf0e10cSrcweir                     return;
332cdf0e10cSrcweir             }
333cdf0e10cSrcweir             else
334cdf0e10cSrcweir                 // Add listener for all properties
335cdf0e10cSrcweir                 listenerContainer.addInterface(XPropertyChangeListener.class, xPropertyChangeListener);
336cdf0e10cSrcweir         }
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
addVetoableChangeListener(String str, com.sun.star.beans.XVetoableChangeListener xVetoableChangeListener)339cdf0e10cSrcweir     synchronized public void addVetoableChangeListener(String str, com.sun.star.beans.XVetoableChangeListener xVetoableChangeListener) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.lang.WrappedTargetException
340cdf0e10cSrcweir     {
341cdf0e10cSrcweir         // only add listeners if you are not disposed
342cdf0e10cSrcweir         if (! bInDispose && ! bDisposed)
343cdf0e10cSrcweir         {
344cdf0e10cSrcweir             if (str.length() > 0)
345cdf0e10cSrcweir             {
346cdf0e10cSrcweir                 Property prop= getProperty(str);
347cdf0e10cSrcweir                 if (prop == null)
348cdf0e10cSrcweir                     throw new UnknownPropertyException("Property " + str + " is unknown");
349cdf0e10cSrcweir 
350cdf0e10cSrcweir                 // Add listener for a certain property
351cdf0e10cSrcweir                 if ((prop.Attributes & PropertyAttribute.CONSTRAINED) > 0)
352cdf0e10cSrcweir                     aVetoableLC.addInterface(str, xVetoableChangeListener);
353cdf0e10cSrcweir                 else
354cdf0e10cSrcweir                     //ignore silently
355cdf0e10cSrcweir                     return;
356cdf0e10cSrcweir             }
357cdf0e10cSrcweir             else
358cdf0e10cSrcweir                 // Add listener for all properties
359cdf0e10cSrcweir                 listenerContainer.addInterface(XVetoableChangeListener.class, xVetoableChangeListener);
360cdf0e10cSrcweir         }
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
getPropertySetInfo()363cdf0e10cSrcweir     public com.sun.star.beans.XPropertySetInfo getPropertySetInfo()
364cdf0e10cSrcweir     {
365cdf0e10cSrcweir         if (propertySetInfo == null)
366cdf0e10cSrcweir         {
367cdf0e10cSrcweir             synchronized (this)
368cdf0e10cSrcweir             {
369cdf0e10cSrcweir                 if (propertySetInfo == null)
370cdf0e10cSrcweir                     propertySetInfo= new PropertySetInfo();
371cdf0e10cSrcweir             }
372cdf0e10cSrcweir         }
373cdf0e10cSrcweir         return propertySetInfo;
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
getPropertyValue(String name)376cdf0e10cSrcweir     public Object getPropertyValue(String name) throws UnknownPropertyException, WrappedTargetException
377cdf0e10cSrcweir     {
378cdf0e10cSrcweir         Object ret= null;
379cdf0e10cSrcweir         if (bInDispose || bDisposed)
380cdf0e10cSrcweir             throw new com.sun.star.lang.DisposedException("The component has been disposed already");
381cdf0e10cSrcweir 
382cdf0e10cSrcweir         Property prop= getProperty(name);
383cdf0e10cSrcweir         if (prop == null)
384cdf0e10cSrcweir             throw new UnknownPropertyException("The property " + name + " is unknown");
385cdf0e10cSrcweir 
386cdf0e10cSrcweir         synchronized (this)
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir             ret= getPropertyValue(prop);
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir         // null must not be returned. Either a void any is returned or an any containing
391cdf0e10cSrcweir         // an interface type and a null reference.
392cdf0e10cSrcweir         if (ret == null)
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             if (prop.Type.getTypeClass() == TypeClass.INTERFACE)
395cdf0e10cSrcweir                 ret= new Any(prop.Type, null);
396cdf0e10cSrcweir             else
397cdf0e10cSrcweir                 ret= new Any(new Type(void.class), null);
398cdf0e10cSrcweir         }
399cdf0e10cSrcweir         return ret;
400cdf0e10cSrcweir     }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
removePropertyChangeListener(String propName, XPropertyChangeListener listener)403cdf0e10cSrcweir     synchronized public void removePropertyChangeListener(String propName, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException
404a893be29SPedro Giffuni     {   // all listeners are automatically released in a dispose call
405cdf0e10cSrcweir         if (!bInDispose && !bDisposed)
406cdf0e10cSrcweir         {
407cdf0e10cSrcweir             if (propName.length() > 0)
408cdf0e10cSrcweir             {
409cdf0e10cSrcweir                 Property prop = getProperty(propName);
410cdf0e10cSrcweir                 if (prop == null)
411cdf0e10cSrcweir                     throw new UnknownPropertyException("Property " + propName + " is unknown");
412cdf0e10cSrcweir                 aBoundLC.removeInterface(propName, listener);
413cdf0e10cSrcweir             }
414cdf0e10cSrcweir             else
415cdf0e10cSrcweir                 listenerContainer.removeInterface(XPropertyChangeListener.class, listener);
416cdf0e10cSrcweir         }
417cdf0e10cSrcweir     }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
removeVetoableChangeListener(String propName, XVetoableChangeListener listener)420cdf0e10cSrcweir     synchronized public void removeVetoableChangeListener(String propName, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException
421a893be29SPedro Giffuni     {// all listeners are automatically released in a dispose call
422cdf0e10cSrcweir         if (!bInDispose && !bDisposed)
423cdf0e10cSrcweir         {
424cdf0e10cSrcweir             if (propName.length() > 0)
425cdf0e10cSrcweir             {
426cdf0e10cSrcweir                 Property prop = getProperty(propName);
427cdf0e10cSrcweir                 if (prop == null)
428cdf0e10cSrcweir                     throw new UnknownPropertyException("Property " + propName + " is unknown");
429cdf0e10cSrcweir                 aVetoableLC.removeInterface(propName, listener);
430cdf0e10cSrcweir             }
431cdf0e10cSrcweir             else
432cdf0e10cSrcweir                 listenerContainer.removeInterface(XVetoableChangeListener.class, listener);
433cdf0e10cSrcweir         }
434cdf0e10cSrcweir     }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     //XPropertySet ----------------------------------------------------
437cdf0e10cSrcweir     /** Sets the value of a property.
438cdf0e10cSrcweir      *  The idl description for this interfaces, stipulates that the argument value is an Any. Since a java.lang.Object
439cdf0e10cSrcweir      *  reference has the same meaning as an Any this function accepts
440cdf0e10cSrcweir      *  java anys (com.sun.star.uno.Any) and all other appropriate objects as arguments. The value argument can be one
441cdf0e10cSrcweir      *  of these:
442cdf0e10cSrcweir      *  <ul>
443cdf0e10cSrcweir      *  <li>java.lang.Boolean</li>
444cdf0e10cSrcweir      *  <li>java.lang.Character</li>
445cdf0e10cSrcweir      *  <li>java.lang.Byte</li>
446cdf0e10cSrcweir      *  <li>java.lang.Short</li>
447cdf0e10cSrcweir      *  <li>java.lang.Integer</li>
448cdf0e10cSrcweir      *  <li>java.lang.Long</li>
449cdf0e10cSrcweir      *  <li>java.lang.Float</li>
450cdf0e10cSrcweir      *  <li>java.lang.Double</li>
451cdf0e10cSrcweir      *  <li>java.lang.String</li>
452cdf0e10cSrcweir      *  <li>com.sun.star.uno.Type</li>
453cdf0e10cSrcweir      *  <li><em>objects which implement UNO interfaces</em></li>
454cdf0e10cSrcweir      *  <li><em>arrays which contain elements of the types above</em></li>
455cdf0e10cSrcweir      *  <li>com.sun.star.uno.Any containing an instance of one of the above types</li>
456cdf0e10cSrcweir      *  </ul>
457cdf0e10cSrcweir      *
458cdf0e10cSrcweir      *  Properties can have the attribute com.sun.star.beans.PropertyAttribute.MAYBEVOID, which means that the value
459cdf0e10cSrcweir      *  (not the type) can be void. In order to assign a void value to a property one can either pass an Any which
46080c1851dSDamjan Jovanovic      *  contains a null reference or pass null directly. In both cases the null reference is only accepted if
461cdf0e10cSrcweir      *  the PropertyAttribute.MAYBEVOID attribute is set for the property.
462cdf0e10cSrcweir      *
463cdf0e10cSrcweir      *  Properties which have the attribute MAYBEVOID set (Property.Attributes) can have a void value. The following
464cdf0e10cSrcweir      *  considerations presume that the Property has that attribute set. Further, when mentioning an Any's value we
465cdf0e10cSrcweir      *  actually refer to the object returned by Any.getObject.
466cdf0e10cSrcweir      *  If the argument <em>value</em> is null, or it is an Any whose value is null (but with a valid Type)
467cdf0e10cSrcweir      *  then the member variable used for storing the property's value is set to null.
468cdf0e10cSrcweir      *  Therefore those properties can only be stored in objects
469cdf0e10cSrcweir      *  and primitive types are not allowed (one can use the wrapper classes instead,e.g. java.lang.Byte) .
470cdf0e10cSrcweir      *  If a property's value is kept in a member variable of type Any and that reference is still null
471cdf0e10cSrcweir      *  then when setPropertyValue is called with
472cdf0e10cSrcweir      *  <em>value</em> = null then the member variable is assigned an Any with type void and a null value.
473cdf0e10cSrcweir      *  Or if the argument is an Any with a null value then it is assigned to the member variable.
474cdf0e10cSrcweir      *  Further, if the variable already
475cdf0e10cSrcweir      *  references an Any and setPropertyValue is called with <em>value</em> = null, then the variable is assigned
476cdf0e10cSrcweir      *  a new Any with the same type as the previously referenced Any and with a null value.
477cdf0e10cSrcweir      *  @param name The name of the property.
478cdf0e10cSrcweir      *  @param value The new value of the property.
479cdf0e10cSrcweir      *     *     */
setPropertyValue(String name, Object value)480cdf0e10cSrcweir     public void setPropertyValue(String name, Object value) throws UnknownPropertyException,
481cdf0e10cSrcweir     PropertyVetoException, com.sun.star.lang.IllegalArgumentException,  WrappedTargetException
482cdf0e10cSrcweir     {
483cdf0e10cSrcweir         Property prop= getProperty(name);
484cdf0e10cSrcweir         if (prop == null)
485cdf0e10cSrcweir             throw new UnknownPropertyException("Property " + name + " is unknown");
486cdf0e10cSrcweir         setPropertyValue(prop, value);
487cdf0e10cSrcweir     }
488cdf0e10cSrcweir 
489cdf0e10cSrcweir     /** Sets the value of a property. It checks if the property's attributes (READONLY,MAYBEVOID), allow that the
490cdf0e10cSrcweir      *  new value can be set. It also causes the notification of listeners.
491cdf0e10cSrcweir      *  @param prop The property whose value is to be set.
492cdf0e10cSrcweir      *  @param value The new value for the property.
493cdf0e10cSrcweir      */
setPropertyValue(Property prop, Object value)494cdf0e10cSrcweir     protected void setPropertyValue(Property prop, Object value) throws UnknownPropertyException,
495cdf0e10cSrcweir     PropertyVetoException, com.sun.star.lang.IllegalArgumentException, WrappedTargetException
496cdf0e10cSrcweir     {
497cdf0e10cSrcweir         if ((prop.Attributes & PropertyAttribute.READONLY) == PropertyAttribute.READONLY)
498cdf0e10cSrcweir             throw new com.sun.star.beans.PropertyVetoException();
499cdf0e10cSrcweir         // The value may be null only if MAYBEVOID attribute is set
500cdf0e10cSrcweir         boolean bVoidValue= false;
501cdf0e10cSrcweir         if (value instanceof Any)
502cdf0e10cSrcweir             bVoidValue= ((Any) value).getObject() == null;
503cdf0e10cSrcweir         else
504cdf0e10cSrcweir             bVoidValue= value == null;
505cdf0e10cSrcweir         if (bVoidValue && (prop.Attributes & PropertyAttribute.MAYBEVOID) == 0)
506cdf0e10cSrcweir             throw new com.sun.star.lang.IllegalArgumentException("The property must have a value; the MAYBEVOID attribute is not set!");
507cdf0e10cSrcweir         if (bInDispose || bDisposed)
508cdf0e10cSrcweir             throw new DisposedException("Component is already disposed");
509cdf0e10cSrcweir 
510cdf0e10cSrcweir         //Check if the argument is allowed
511cdf0e10cSrcweir         boolean bValueOk= false;
512cdf0e10cSrcweir         if (value instanceof Any)
513cdf0e10cSrcweir             bValueOk= checkType(((Any) value).getObject());
514cdf0e10cSrcweir         else
515cdf0e10cSrcweir             bValueOk= checkType(value);
516cdf0e10cSrcweir         if (! bValueOk)
517cdf0e10cSrcweir             throw new com.sun.star.lang.IllegalArgumentException("No valid UNO type");
518cdf0e10cSrcweir 
519cdf0e10cSrcweir 
520cdf0e10cSrcweir         boolean bConversionOk= false;
521cdf0e10cSrcweir         Object[] outConvertedVal= new Object[1];
522cdf0e10cSrcweir         Object[] outOldValue= new Object[1];
523cdf0e10cSrcweir         synchronized (this)
524cdf0e10cSrcweir         {
525cdf0e10cSrcweir             bConversionOk= convertPropertyValue(prop, outConvertedVal, outOldValue, value);
526cdf0e10cSrcweir         }
527cdf0e10cSrcweir 
528cdf0e10cSrcweir         //The next step following the conversion is to set the new value of the property. Prior to this
529cdf0e10cSrcweir         // the XVetoableChangeListener s have to be notified.
530cdf0e10cSrcweir         if (bConversionOk)
531cdf0e10cSrcweir         {
532cdf0e10cSrcweir             // If the property is CONSTRAINED, then we must notify XVetoableChangeListener. The listener can throw a com.sun.star.lang.beans.PropertyVetoException which
533cdf0e10cSrcweir             // will cause this method to return (the exception is not caught here).
534cdf0e10cSrcweir             fire( new Property[]{prop}, outConvertedVal, outOldValue, true);
535cdf0e10cSrcweir 
536cdf0e10cSrcweir             synchronized (this)
537cdf0e10cSrcweir             {
538cdf0e10cSrcweir                 setPropertyValueNoBroadcast(prop, outConvertedVal[0]);
539cdf0e10cSrcweir             }
540cdf0e10cSrcweir             // fire a change event (XPropertyChangeListener, PropertyAttribute.BOUND
541cdf0e10cSrcweir             fire( new Property[]{prop}, outConvertedVal, outOldValue, false);
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir     }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     /** Converts a value in a way so that it is appropriate for storing as a property value, that is
546cdf0e10cSrcweir      *  {@link #setPropertyValueNoBroadcast setPropertyValueNoBroadcast} can process the value without any further
547cdf0e10cSrcweir      *  conversion. This implementation presumes that
548cdf0e10cSrcweir      *  the values are stored in member variables of the furthest inheriting class. For example,
549cdf0e10cSrcweir      *  class A inherits this class then members of class A
550cdf0e10cSrcweir      *  can hold property values. If there is a class B which inherits A then only members of B can hold
551cdf0e10cSrcweir      *  property values. The variables must be public. A property must have been registered (e.g. by
55280c1851dSDamjan Jovanovic      *  {@link #registerProperty(Property, Object)} in order for this method to work. The identifier argument (type Object)
553cdf0e10cSrcweir      *  used in the registerProperty methods must
554cdf0e10cSrcweir      *  be a java.lang.String, which is, the name of the member variable that holds the property value.
555cdf0e10cSrcweir      *  If one opts to store values differently then one may override
556cdf0e10cSrcweir      *  this method, as well as {@link #setPropertyValueNoBroadcast setPropertyValueNoBroadcast} and
557cdf0e10cSrcweir      *  {@link #getPropertyValue(Property) getPropertyValue(Property)}.
558cdf0e10cSrcweir      *  This method is always called as a result of a call to one of the setter methods, such as
559cdf0e10cSrcweir      *  {@link #setPropertyValue(String,Object) XPropertySet.setPropertyValue},
560cdf0e10cSrcweir      *  {@link #setFastPropertyValue XFastPropertySet.setFastPropertyValue}
561cdf0e10cSrcweir      *  and {@link #setPropertyValues XMultiPropertySet.setPropertyValues}.
562cdf0e10cSrcweir      *  If this method fails, that is, it returns false or throws an exception, then no listeners are notified and the
563e0f9f944SDamjan Jovanovic      *  property value, that was intended to be changed, remains untouched.<br> This method does not have to deal with property attributes, such as
564cdf0e10cSrcweir      *  PropertyAttribute.READONLY or PropertyAttribute.MAYBEVOID. The processing of these attributes occurs
565e0f9f944SDamjan Jovanovic      *  in the calling methods.<br>
566cdf0e10cSrcweir      *  Only if this method returns successfully further processing, such
56780c1851dSDamjan Jovanovic      *  as listener notification and finally the modification of the property's value, will occur.<br>
568cdf0e10cSrcweir      *
569cdf0e10cSrcweir      *  The actual modification of a property's value is done by {@link #setPropertyValueNoBroadcast setPropertyValueNoBroadcast}
570cdf0e10cSrcweir      *  which is called subsequent to convertPropertyValue.
571cdf0e10cSrcweir      *<p>
572cdf0e10cSrcweir      *  This method converts values by help of the com.sun.star.uno.AnyConverter which only does a few widening
573cdf0e10cSrcweir      *  conversions on integer types and floating point types. For example, there is the property PropA with a Type equivalent
574cdf0e10cSrcweir      *  to int.class and the
575cdf0e10cSrcweir      *  value of the property is to be stored in a member variable of type int with name intProp. Then setPropertyValue is
576cdf0e10cSrcweir      *  called:
577cdf0e10cSrcweir      *  <pre>
5785b5659a7SDamjan Jovanovic      *  set.setPropertyValue( "PropA", (byte)111);
579cdf0e10cSrcweir      *  </pre>
580cdf0e10cSrcweir      *  At some point setPropertyValue will call convertPropertyValue and pass in the Byte object. Since we allow
581cdf0e10cSrcweir      *  that Byte values can be used with the property and know that the value is to be stored in intProp (type int)
582cdf0e10cSrcweir      *  we convert the Byte object into an Integer object which is then returned in the out-parameter <em>newVal</em>. This
583cdf0e10cSrcweir      *  conversion is actually performed by the AnyConverter. Later
584cdf0e10cSrcweir      *  the setPropertyValueNoBroadcast is called with that Integer object and the int value can be easily extracted
585cdf0e10cSrcweir      *  from the object and be assigned to the member intProp.
586cdf0e10cSrcweir      *  <p>
587cdf0e10cSrcweir      *  The method handles Any arguments the same as Object arguments. That is, the <em>setVal</em> argument can
588cdf0e10cSrcweir      *  be a java.lang.Boolean or a com.sun.star.uno.Any containing a java.lang.Boolean. Likewise, a member
589cdf0e10cSrcweir      *  containing a property value can be a com.sun.star.uno.Any or an java.lang.Object.
590cdf0e10cSrcweir      *  Then, no conversion is necessary, since they can hold all possible values. However, if
591cdf0e10cSrcweir      *  the member is an Object and <em>setVal</em> is an Any then the object contained in the any is assigned to
592cdf0e10cSrcweir      *  the member. The extra type information which exists as Type object in the Any will get lost. If this is not
593e0f9f944SDamjan Jovanovic      *  intended then use an Any variable rather then an Object.<br>
594cdf0e10cSrcweir      *  If a member is an Object or Any and the argument <em>setVal</em> is an Object, other than String or array,
595cdf0e10cSrcweir      *  then it is presumed to be an UNO object and queried for XInterface. If successful, the out-param <em>newVal</em>
596e0f9f944SDamjan Jovanovic      *  returns the XInterface.<br>
597cdf0e10cSrcweir      *  If a member is an UNO interface, then <em>setVal</em> is queried for this interface and the result is returned.
598cdf0e10cSrcweir      *  If <em>setVal</em> is null then <em>newVal</em> will be null too after return.
599cdf0e10cSrcweir      *  <p>
600*7950f2afSmseidel      *  If a property value is stored using a primitive type the out-parameters
601cdf0e10cSrcweir      *  <em>curVal</em> and <em>newVal</em> contain the respective wrapper class (e.g.java.lang.Byte, etc.).
602cdf0e10cSrcweir      *  curVal is used in calls to the XVetoableChangeListener and XPropertyChangeListener.
603cdf0e10cSrcweir      *
604cdf0e10cSrcweir      * @param property - in-param property for which the data is to be converted.
605cdf0e10cSrcweir      * @param newVal - out-param which contains the converted value on return.
606cdf0e10cSrcweir      * @param curVal - out-param the current value of the property. It is used in calls to the
607cdf0e10cSrcweir      *                   XVetoableChangeListener and XPropertyChangeListener.
608cdf0e10cSrcweir      *  @param setVal - in-param. The value that is to be converted so that it matches Property and the internally used
609cdf0e10cSrcweir      *  dataformat for that property.
610cdf0e10cSrcweir      *  @return true - Conversion was successful. <em>newVal</em> contains a valid value for the property. false -
611cdf0e10cSrcweir      *  conversion failed for some reason.
612cdf0e10cSrcweir      *  @throws com.sun.star.lang.IllegalArgumentException The value provided is unfit for the property.
613a893be29SPedro Giffuni      *  @throws com.sun.star.lang.WrappedTargetException - An exception occurred during the conversion, that is to be made known
614cdf0e10cSrcweir      *  to the caller.
615cdf0e10cSrcweir      */
convertPropertyValue(Property property, Object[] newVal, Object[]curVal, Object setVal)616cdf0e10cSrcweir     protected boolean convertPropertyValue(Property property, Object[] newVal, Object[]curVal,  Object setVal)
617cdf0e10cSrcweir         throws com.sun.star.lang.IllegalArgumentException, WrappedTargetException, UnknownPropertyException
618cdf0e10cSrcweir     {
619cdf0e10cSrcweir         boolean ret= true;
620cdf0e10cSrcweir         try
621cdf0e10cSrcweir         {
622cdf0e10cSrcweir             // get the member name
623cdf0e10cSrcweir             String sMember= (String) getPropertyId(property);
624cdf0e10cSrcweir             if (sMember != null)
625cdf0e10cSrcweir             {
626cdf0e10cSrcweir                 // use reflection to obtain the field that holds the property value
627cdf0e10cSrcweir                 // Class.getDeclaredFields does not return inherited fields. One could use Class.getFields to
628cdf0e10cSrcweir                 // also get inherited fields, but only those which are public.
629cdf0e10cSrcweir                 Field propField= getClass().getDeclaredField(sMember);
630cdf0e10cSrcweir                 if (propField != null)
631cdf0e10cSrcweir                 {
632cdf0e10cSrcweir                     curVal[0]= propField.get(this);
633cdf0e10cSrcweir                     Class memberClass= propField.getType();
634cdf0e10cSrcweir 
635cdf0e10cSrcweir                     // MAYBEVOID: if setVal == null or it is an Any and getObject returns null, then a void value is to be set
636cdf0e10cSrcweir                     // This works only if there are no primitive types. For those we use the respective wrapper classes.
637cdf0e10cSrcweir                     // In this implementation, a null reference means void value.
638cdf0e10cSrcweir                     boolean bVoidValue= false;
639cdf0e10cSrcweir                     boolean bAnyVal= setVal instanceof Any;
640cdf0e10cSrcweir                     if (bAnyVal)
641cdf0e10cSrcweir                         bVoidValue= ((Any) setVal).getObject() == null;
642cdf0e10cSrcweir                     else
643cdf0e10cSrcweir                         bVoidValue= setVal == null;
644cdf0e10cSrcweir                     if (bVoidValue && memberClass.isPrimitive())
645cdf0e10cSrcweir                         throw new com.sun.star.lang.IllegalArgumentException("The implementation does not support the MAYBEVOID attribute for this property");
646cdf0e10cSrcweir 
647cdf0e10cSrcweir                     Object convObj= null;
648cdf0e10cSrcweir                     //The member that keeps the value of the Property is an Any. It can contain all possible
649cdf0e10cSrcweir                     //types, therefore a conversion is not necessary.
650cdf0e10cSrcweir                     if (memberClass.equals(Any.class))
651cdf0e10cSrcweir                     {
652cdf0e10cSrcweir                         if (bAnyVal)
653cdf0e10cSrcweir                             //parameter setVal is also an Any and can be used without further processing
654cdf0e10cSrcweir                             convObj= setVal;
655cdf0e10cSrcweir                         else
656cdf0e10cSrcweir                         {
657cdf0e10cSrcweir                             // Parameter setVal is not an Any. We need to construct an Any that contains
658cdf0e10cSrcweir                             // the argument setVal.
659cdf0e10cSrcweir                             // If setVal is an interface implementation then, we cannot constuct the
660cdf0e10cSrcweir                             // Any with setVal.getClass(), because the Any.Type._typeClass would be TypeClass.UNKNOWN.
661cdf0e10cSrcweir                             // We try to get an XInterface of setVal and set an XInterface type.
662cdf0e10cSrcweir                             if (setVal instanceof XInterface)
663cdf0e10cSrcweir                             {
664cdf0e10cSrcweir                                 XInterface xint= UnoRuntime.queryInterface(XInterface.class, setVal);
665cdf0e10cSrcweir                                 if (xint != null)
666cdf0e10cSrcweir                                     convObj= new Any(new Type(XInterface.class), xint);
667cdf0e10cSrcweir                             }
668cdf0e10cSrcweir                             // The member is an any, and the past in argument was null reference (MAYBEVOID is set)
669cdf0e10cSrcweir                             else if (setVal == null)
670cdf0e10cSrcweir                             {
671cdf0e10cSrcweir                                 // if the any member is still null we create a void any
672cdf0e10cSrcweir                                 if (curVal[0] == null)
673cdf0e10cSrcweir                                     convObj= new Any(new Type(), null);
674cdf0e10cSrcweir                                 else
675cdf0e10cSrcweir                                 {
676cdf0e10cSrcweir                                     //otherwise we create an Any with the same type as a value of null;
677cdf0e10cSrcweir                                     convObj= new Any( ((Any)curVal[0]).getType(), null);
678cdf0e10cSrcweir                                 }
679cdf0e10cSrcweir                             }
680cdf0e10cSrcweir                             else
681cdf0e10cSrcweir                                 convObj= new Any(new Type(setVal.getClass()), setVal);
682cdf0e10cSrcweir                         }
683cdf0e10cSrcweir                     }
684cdf0e10cSrcweir                     else
685cdf0e10cSrcweir                         convObj= convert(memberClass, setVal);
686cdf0e10cSrcweir                     newVal[0]= convObj;
687cdf0e10cSrcweir                 }
688cdf0e10cSrcweir             }
689cdf0e10cSrcweir             else
690cdf0e10cSrcweir                 throw new UnknownPropertyException("Property " + property.Name + " is unknown");
691cdf0e10cSrcweir         }
692cdf0e10cSrcweir         catch (java.lang.NoSuchFieldException e)
693cdf0e10cSrcweir         {
694cdf0e10cSrcweir             throw new WrappedTargetException("Field does not exist", this, e);
695cdf0e10cSrcweir         }
696cdf0e10cSrcweir         catch (java.lang.IllegalAccessException e)
697cdf0e10cSrcweir         {
698cdf0e10cSrcweir             throw new WrappedTargetException("", this ,e);
699cdf0e10cSrcweir         }
700cdf0e10cSrcweir         return ret;
701cdf0e10cSrcweir     }
702cdf0e10cSrcweir 
checkType(Object obj)703cdf0e10cSrcweir     private boolean checkType(Object obj)
704cdf0e10cSrcweir     {
705cdf0e10cSrcweir         if (obj == null
706cdf0e10cSrcweir         || obj instanceof Boolean
707cdf0e10cSrcweir         || obj instanceof Character
708cdf0e10cSrcweir         || obj instanceof Number
709cdf0e10cSrcweir         || obj instanceof String
710cdf0e10cSrcweir         || obj instanceof XInterface
711cdf0e10cSrcweir         || obj instanceof Type
712cdf0e10cSrcweir         || obj instanceof com.sun.star.uno.Enum
713cdf0e10cSrcweir         || obj.getClass().isArray())
714cdf0e10cSrcweir             return true;
715cdf0e10cSrcweir         return false;
716cdf0e10cSrcweir     }
717cdf0e10cSrcweir 
718cdf0e10cSrcweir     // Param object can be an Any or other object. If obj is null then the return value is null
convert( Class cl, Object obj)719cdf0e10cSrcweir     private Object convert( Class cl, Object obj) throws com.sun.star.lang.IllegalArgumentException
720cdf0e10cSrcweir     {
721cdf0e10cSrcweir         Object retVal= null;
722cdf0e10cSrcweir        //The member that keeps the value of the Property is an Object.Objects are similar to Anys in that they can
723cdf0e10cSrcweir        // hold all types.
724cdf0e10cSrcweir         if (obj == null || (obj instanceof Any && ((Any) obj).getObject() == null))
725cdf0e10cSrcweir             retVal= null;
726cdf0e10cSrcweir         else if(cl.equals(Object.class))
727cdf0e10cSrcweir         {
728cdf0e10cSrcweir             if (obj instanceof Any)
729cdf0e10cSrcweir                 obj= ((Any) obj).getObject();
730cdf0e10cSrcweir             retVal= obj;
731cdf0e10cSrcweir         }
732cdf0e10cSrcweir         else if(cl.equals(boolean.class))
7335b5659a7SDamjan Jovanovic             retVal= AnyConverter.toBoolean(obj);
734cdf0e10cSrcweir         else if (cl.equals(char.class))
7355b5659a7SDamjan Jovanovic             retVal= AnyConverter.toChar(obj);
736cdf0e10cSrcweir         else if (cl.equals(byte.class))
7375b5659a7SDamjan Jovanovic             retVal= AnyConverter.toByte(obj);
738cdf0e10cSrcweir         else if (cl.equals(short.class))
7395b5659a7SDamjan Jovanovic             retVal= AnyConverter.toShort(obj);
740cdf0e10cSrcweir         else if (cl.equals(int.class))
7415b5659a7SDamjan Jovanovic             retVal= AnyConverter.toInt(obj);
742cdf0e10cSrcweir         else if (cl.equals(long.class))
7435b5659a7SDamjan Jovanovic             retVal= AnyConverter.toLong(obj);
744cdf0e10cSrcweir         else if (cl.equals(float.class))
7455b5659a7SDamjan Jovanovic             retVal= AnyConverter.toFloat(obj);
746cdf0e10cSrcweir         else if (cl.equals(double.class))
7475b5659a7SDamjan Jovanovic             retVal= AnyConverter.toDouble(obj);
748cdf0e10cSrcweir         else if (cl.equals(String.class))
749cdf0e10cSrcweir             retVal= AnyConverter.toString(obj);
750cdf0e10cSrcweir         else if (cl.isArray())
751cdf0e10cSrcweir             retVal= AnyConverter.toArray(obj);
752cdf0e10cSrcweir         else if (cl.equals(Type.class))
753cdf0e10cSrcweir             retVal= AnyConverter.toType(obj);
754cdf0e10cSrcweir         else if (cl.equals(Boolean.class))
7555b5659a7SDamjan Jovanovic             retVal= AnyConverter.toBoolean(obj);
756cdf0e10cSrcweir         else if (cl.equals(Character.class))
7575b5659a7SDamjan Jovanovic             retVal= AnyConverter.toChar(obj);
758cdf0e10cSrcweir         else if (cl.equals(Byte.class))
7595b5659a7SDamjan Jovanovic             retVal= AnyConverter.toByte(obj);
760cdf0e10cSrcweir         else if (cl.equals(Short.class))
7615b5659a7SDamjan Jovanovic             retVal= AnyConverter.toShort(obj);
762cdf0e10cSrcweir         else if (cl.equals(Integer.class))
7635b5659a7SDamjan Jovanovic             retVal= AnyConverter.toInt(obj);
764cdf0e10cSrcweir         else if (cl.equals(Long.class))
7655b5659a7SDamjan Jovanovic             retVal= AnyConverter.toLong(obj);
766cdf0e10cSrcweir         else if (cl.equals(Float.class))
7675b5659a7SDamjan Jovanovic             retVal= AnyConverter.toFloat(obj);
768cdf0e10cSrcweir         else if (cl.equals(Double.class))
7695b5659a7SDamjan Jovanovic             retVal= AnyConverter.toDouble(obj);
770cdf0e10cSrcweir         else if (XInterface.class.isAssignableFrom(cl))
771cdf0e10cSrcweir             retVal= AnyConverter.toObject(new Type(cl), obj);
772cdf0e10cSrcweir         else if (com.sun.star.uno.Enum.class.isAssignableFrom(cl))
773cdf0e10cSrcweir             retVal= AnyConverter.toObject(new Type(cl), obj);
774cdf0e10cSrcweir         else
775cdf0e10cSrcweir             throw new com.sun.star.lang.IllegalArgumentException("Could not convert the argument");
776cdf0e10cSrcweir         return retVal;
777cdf0e10cSrcweir     }
778cdf0e10cSrcweir 
779cdf0e10cSrcweir     /**  Sets the value of a property. In this implementation property values are stored in member variables
780cdf0e10cSrcweir      *  (see {@link #convertPropertyValue convertPropertyValue} Notification of property listeners
781cdf0e10cSrcweir      *  does not occur in this method. By overriding this method one can take full control about how property values
782cdf0e10cSrcweir      *  are stored. But then, the {@link #convertPropertyValue convertPropertyValue} and
783cdf0e10cSrcweir      *  {@link #getPropertyValue(Property)} must be overridden too.
784cdf0e10cSrcweir      *
785cdf0e10cSrcweir      *  A Property with the MAYBEVOID attribute set, is stored as null value. Therefore the member variable must be
786cdf0e10cSrcweir      *  an Object in order to make use of the property attribute. An exception is Any. The Any variable can be initially null, but
787cdf0e10cSrcweir      *  once it is set the reference will not become null again. If the value is to be set to
788cdf0e10cSrcweir      *  void then a new Any will be stored
789cdf0e10cSrcweir      *  with a valid type but without a value (i.e. Any.getObject returns null).
790cdf0e10cSrcweir      *  If a property has the READONLY attribute set, and one of the setter methods, such as setPropertyValue, has been
791cdf0e10cSrcweir      *  called, then this method is not going to be called.
792cdf0e10cSrcweir      *  @param property the property for which the new value is set
793e0f9f944SDamjan Jovanovic      *  @param newVal the new value for the property.
794cdf0e10cSrcweir      *  @throws com.sun.star.lang.WrappedTargetException An exception, which has to be made known to the caller,
795a893be29SPedro Giffuni      *  occurred during the setting of the value.
796cdf0e10cSrcweir      */
setPropertyValueNoBroadcast(Property property, Object newVal)797cdf0e10cSrcweir     protected void setPropertyValueNoBroadcast(Property property, Object newVal)
798cdf0e10cSrcweir     throws WrappedTargetException
799cdf0e10cSrcweir     {
800cdf0e10cSrcweir         try
801cdf0e10cSrcweir         {
802cdf0e10cSrcweir             // get the member name
803cdf0e10cSrcweir             String sMember= (String) getPropertyId(property);
804cdf0e10cSrcweir             if (sMember != null)
805cdf0e10cSrcweir             {
806cdf0e10cSrcweir                 // use reflection to obtain the field that holds the property value
807cdf0e10cSrcweir                 // Class.getDeclaredFields does not return inherited fields. One could use Class.getFields to
808cdf0e10cSrcweir                 // also get inherited fields, but only those which are public.
809cdf0e10cSrcweir                 Field propField= getClass().getDeclaredField(sMember);
810cdf0e10cSrcweir                 if (propField != null)
811cdf0e10cSrcweir                     propField.set(this, newVal);
812cdf0e10cSrcweir             }
813cdf0e10cSrcweir         }
814cdf0e10cSrcweir         catch(java.lang.Exception e)
815cdf0e10cSrcweir         {
816cdf0e10cSrcweir             throw new WrappedTargetException("PropertySet.setPropertyValueNoBroadcast", this, e);
817cdf0e10cSrcweir         }
818cdf0e10cSrcweir     }
819cdf0e10cSrcweir     /** Retrieves the value of a property. This implementation presumes that the values are stored in member variables
820cdf0e10cSrcweir      *  of the furthest inheriting class (see {@link #convertPropertyValue convertPropertyValue}) and that the
821cdf0e10cSrcweir      *  variables are public. The property must have
82280c1851dSDamjan Jovanovic      *  been registered, for example by {@link #registerProperty(Property, Object)}. The identifier Object argument
823cdf0e10cSrcweir      *  must have been a java.lang.String which was the name of the member variable holding the property value.
824cdf0e10cSrcweir      *  When properties are to be stored differently one has to override this method as well as
825cdf0e10cSrcweir      *  {@link #convertPropertyValue} and {@link #setPropertyValueNoBroadcast}. <br>
826cdf0e10cSrcweir      *  If a value is stored in a variable of a primitive type then this method returns an instance of the respective
827cdf0e10cSrcweir      *  wrapper class (e.g. java.lang.Boolean).
828cdf0e10cSrcweir      *  @param property The property for which the value is to be retrieved.
829cdf0e10cSrcweir      *  @return The value of the property.
830cdf0e10cSrcweir      */
getPropertyValue(Property property)831cdf0e10cSrcweir     protected Object getPropertyValue(Property property)
832cdf0e10cSrcweir     {
833cdf0e10cSrcweir         Object ret= null;
834cdf0e10cSrcweir         try
835cdf0e10cSrcweir         {
836cdf0e10cSrcweir             // get the member name
837cdf0e10cSrcweir             String sMember= (String) getPropertyId(property);
838cdf0e10cSrcweir             if (sMember != null)
839cdf0e10cSrcweir             {
840cdf0e10cSrcweir                 // use reflection to obtain the field that holds the property value
841cdf0e10cSrcweir                 // Class.getDeclaredFields does not return inherited fields. One could use Class.getFields to
842cdf0e10cSrcweir                 // also get inherited fields, but only those which are public.
843cdf0e10cSrcweir                 Field propField= getClass().getDeclaredField(sMember);
844cdf0e10cSrcweir                 if (propField != null)
845cdf0e10cSrcweir                     ret= propField.get(this);
846cdf0e10cSrcweir             }
847cdf0e10cSrcweir         }
848cdf0e10cSrcweir         catch(java.lang.NoSuchFieldException e)
849cdf0e10cSrcweir         {
850cdf0e10cSrcweir             throw new java.lang.RuntimeException(e);
851cdf0e10cSrcweir         }
852cdf0e10cSrcweir         catch(java.lang.IllegalAccessException e)
853cdf0e10cSrcweir         {
854cdf0e10cSrcweir             throw new java.lang.RuntimeException(e);
855cdf0e10cSrcweir         }
856cdf0e10cSrcweir         return ret;
857cdf0e10cSrcweir     }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir     /**
860cdf0e10cSrcweir      *  This method fires events to XPropertyChangeListener,XVetoableChangeListener and
861cdf0e10cSrcweir      *  XPropertiesChangeListener event sinks.
862cdf0e10cSrcweir      *  To distinguish what listeners are to be called the argument <em>bVetoable</em> is to be set to true if
863cdf0e10cSrcweir      *  a XVetoableChangeListener is meant. For XPropertyChangeListener and XPropertiesChangeListener
864cdf0e10cSrcweir      *  it is to be set to false.
865cdf0e10cSrcweir      *
866a893be29SPedro Giffuni      * @param properties    Properties which will be or have been affected.
867cdf0e10cSrcweir      * @param newValues the new values of the properties.
868cdf0e10cSrcweir      * @param oldValues the old values of the properties.
869cdf0e10cSrcweir      * @param bVetoable true means fire to VetoableChangeListener, false means fire to
870cdf0e10cSrcweir      * XPropertyChangedListener and XMultiPropertyChangedListener.
871cdf0e10cSrcweir      */
fire( Property[] properties, Object[] newValues, Object[] oldValues, boolean bVetoable )872cdf0e10cSrcweir     protected void  fire(
873cdf0e10cSrcweir     Property[]  properties,
874cdf0e10cSrcweir     Object[] newValues,
875cdf0e10cSrcweir     Object[] oldValues,
876cdf0e10cSrcweir     boolean bVetoable ) throws PropertyVetoException
877cdf0e10cSrcweir     {
878cdf0e10cSrcweir         // Only fire, if one or more properties changed
879cdf0e10cSrcweir         int nNumProps= properties.length;
880cdf0e10cSrcweir         if (nNumProps > 0)
881cdf0e10cSrcweir         {
882cdf0e10cSrcweir             PropertyChangeEvent[] arEvts= new PropertyChangeEvent[nNumProps];
883cdf0e10cSrcweir             int nAffectedProps= 0;
884cdf0e10cSrcweir             // Loop over all changed properties to fill the event struct
885cdf0e10cSrcweir             for (int i= 0; i < nNumProps; i++)
886cdf0e10cSrcweir             {
887cdf0e10cSrcweir                 if ((bVetoable && (properties[i].Attributes & PropertyAttribute.CONSTRAINED) > 0)
888cdf0e10cSrcweir                     || (!bVetoable && (properties[i].Attributes & PropertyAttribute.BOUND) > 0))
889cdf0e10cSrcweir                 {
890cdf0e10cSrcweir                     arEvts[i]= new PropertyChangeEvent(this, properties[i].Name, false,
891cdf0e10cSrcweir                                         properties[i].Handle, oldValues[i], newValues[i]);
892cdf0e10cSrcweir                     nAffectedProps++;
893cdf0e10cSrcweir                 }
894cdf0e10cSrcweir             }
895cdf0e10cSrcweir             // fire the events for all changed properties
896cdf0e10cSrcweir             for (int i= 0; i < nAffectedProps; i++)
897cdf0e10cSrcweir             {
898cdf0e10cSrcweir                 // get the listener container for the property name
899cdf0e10cSrcweir                 InterfaceContainer lc= null;
900cdf0e10cSrcweir                 if (bVetoable)
901cdf0e10cSrcweir                     lc= aVetoableLC.getContainer(arEvts[i].PropertyName);
902cdf0e10cSrcweir                 else
903cdf0e10cSrcweir                     lc= aBoundLC.getContainer(arEvts[i].PropertyName);
904cdf0e10cSrcweir                 if (lc != null)
905cdf0e10cSrcweir                 {
906cdf0e10cSrcweir                     Iterator it= lc.iterator();
907cdf0e10cSrcweir                     while( it.hasNext())
908cdf0e10cSrcweir                     {
909cdf0e10cSrcweir                         Object listener= it.next();
910cdf0e10cSrcweir                         if (bVetoable)
911cdf0e10cSrcweir                             ((XVetoableChangeListener) listener).vetoableChange(arEvts[i]);
912cdf0e10cSrcweir                         else
913cdf0e10cSrcweir                             ((XPropertyChangeListener) listener).propertyChange(arEvts[i]);
914cdf0e10cSrcweir                     }
915cdf0e10cSrcweir                 }
916cdf0e10cSrcweir                 // broadcast to all listeners with "" property name
917cdf0e10cSrcweir                 if(bVetoable)
918cdf0e10cSrcweir                     lc= listenerContainer.getContainer(XVetoableChangeListener.class);
919cdf0e10cSrcweir                 else
920cdf0e10cSrcweir                     lc= listenerContainer.getContainer(XPropertyChangeListener.class);
921cdf0e10cSrcweir                 if(lc != null)
922cdf0e10cSrcweir                 {
923cdf0e10cSrcweir                     Iterator it= lc.iterator();
924cdf0e10cSrcweir                     while(it.hasNext() )
925cdf0e10cSrcweir                     {
926cdf0e10cSrcweir                         Object listener= it.next();
927cdf0e10cSrcweir                         if( bVetoable ) // fire change Events?
928cdf0e10cSrcweir                             ((XVetoableChangeListener) listener).vetoableChange(arEvts[i]);
929cdf0e10cSrcweir                         else
930cdf0e10cSrcweir                             ((XPropertyChangeListener) listener).propertyChange(arEvts[i]);
931cdf0e10cSrcweir                     }
932cdf0e10cSrcweir                 }
933cdf0e10cSrcweir             }
934cdf0e10cSrcweir             // fire at XPropertiesChangeListeners
935cdf0e10cSrcweir             // if nAffectedProps == 0 then there are no BOUND properties
936cdf0e10cSrcweir             if (!bVetoable && nAffectedProps > 0)
937cdf0e10cSrcweir             {
938cdf0e10cSrcweir 
939cdf0e10cSrcweir                 PropertyChangeEvent[] arReduced= new PropertyChangeEvent[nAffectedProps];
940cdf0e10cSrcweir                 System.arraycopy(arEvts, 0, arReduced, 0, nAffectedProps);
941cdf0e10cSrcweir                 InterfaceContainer lc= listenerContainer.getContainer(XPropertiesChangeListener.class);
942cdf0e10cSrcweir                 if (lc != null)
943cdf0e10cSrcweir                 {
944cdf0e10cSrcweir                     Iterator it= lc.iterator();
945cdf0e10cSrcweir                     while (it.hasNext())
946cdf0e10cSrcweir                     {
947cdf0e10cSrcweir                         XPropertiesChangeListener listener = (XPropertiesChangeListener) it.next();
948cdf0e10cSrcweir                         // fire the hole event sequence to the XPropertiesChangeListener's
949cdf0e10cSrcweir                         listener.propertiesChange( arEvts );
950cdf0e10cSrcweir                     }
951cdf0e10cSrcweir                 }
952cdf0e10cSrcweir             }
953cdf0e10cSrcweir         }
954cdf0e10cSrcweir     }
955cdf0e10cSrcweir     // XFastPropertySet--------------------------------------------------------------------------------
setFastPropertyValue(int nHandle, Object aValue )956cdf0e10cSrcweir     public void setFastPropertyValue(int nHandle, Object aValue ) throws UnknownPropertyException,
957cdf0e10cSrcweir     PropertyVetoException, com.sun.star.lang.IllegalArgumentException, WrappedTargetException
958cdf0e10cSrcweir     {
959cdf0e10cSrcweir         Property prop= getPropertyByHandle(nHandle);
960cdf0e10cSrcweir         if (prop == null)
961cdf0e10cSrcweir             throw new UnknownPropertyException(" The property with handle : " + nHandle +" is unknown");
962cdf0e10cSrcweir         setPropertyValue(prop, aValue);
963cdf0e10cSrcweir     }
964cdf0e10cSrcweir 
965cdf0e10cSrcweir     // XFastPropertySet --------------------------------------------------------------------------------
getFastPropertyValue(int nHandle )966cdf0e10cSrcweir     public Object getFastPropertyValue(int nHandle ) throws UnknownPropertyException,
967cdf0e10cSrcweir     WrappedTargetException
968cdf0e10cSrcweir     {
969cdf0e10cSrcweir         Property prop= getPropertyByHandle(nHandle);
970cdf0e10cSrcweir         if (prop == null)
971cdf0e10cSrcweir             throw new UnknownPropertyException("The property with handle : " + nHandle + " is unknown");
972cdf0e10cSrcweir         return getPropertyValue(prop);
973cdf0e10cSrcweir     }
974cdf0e10cSrcweir 
975cdf0e10cSrcweir     // XMultiPropertySet -----------------------------------------------------------------------------------
addPropertiesChangeListener(String[] propNames, XPropertiesChangeListener listener)976cdf0e10cSrcweir     public void addPropertiesChangeListener(String[] propNames, XPropertiesChangeListener listener)
977cdf0e10cSrcweir     {
978cdf0e10cSrcweir         listenerContainer.addInterface(XPropertiesChangeListener.class, listener);
979cdf0e10cSrcweir     }
980cdf0e10cSrcweir 
981cdf0e10cSrcweir     // XMultiPropertySet -----------------------------------------------------------------------------------
firePropertiesChangeEvent(String[] propNames, XPropertiesChangeListener listener)982cdf0e10cSrcweir     public void firePropertiesChangeEvent(String[] propNames, XPropertiesChangeListener listener)
983cdf0e10cSrcweir     {
984cdf0e10cSrcweir         // Build the events.
985cdf0e10cSrcweir         PropertyChangeEvent[] arEvents= new PropertyChangeEvent[propNames.length];
986cdf0e10cSrcweir         int eventCount= 0;
987cdf0e10cSrcweir         // get a snapshot of the current property values
988cdf0e10cSrcweir         synchronized (this)
989cdf0e10cSrcweir         {
990cdf0e10cSrcweir             for (int i= 0; i < propNames.length; i++)
991cdf0e10cSrcweir             {
992cdf0e10cSrcweir                 Property prop= getProperty(propNames[i]);
993cdf0e10cSrcweir                 if (prop != null)
994cdf0e10cSrcweir                 {
995cdf0e10cSrcweir                     Object value= null;
996cdf0e10cSrcweir                     try
997cdf0e10cSrcweir                     {
998cdf0e10cSrcweir                        value= getPropertyValue(prop);
999cdf0e10cSrcweir                     }
1000cdf0e10cSrcweir                     catch(Exception e)
1001cdf0e10cSrcweir                     {
1002cdf0e10cSrcweir                         continue;
1003cdf0e10cSrcweir                     }
1004cdf0e10cSrcweir                     arEvents[eventCount]= new PropertyChangeEvent(this, prop.Name,
1005cdf0e10cSrcweir                                         false, prop.Handle, value, value);
1006cdf0e10cSrcweir                     eventCount++;
1007cdf0e10cSrcweir                 }
1008cdf0e10cSrcweir             }
1009cdf0e10cSrcweir         }
1010cdf0e10cSrcweir 
1011cdf0e10cSrcweir         // fire events from unsynchronized section so as to prevent deadlocks
1012cdf0e10cSrcweir         if (eventCount > 0)
1013cdf0e10cSrcweir         {
1014cdf0e10cSrcweir             // Reallocate the array of the events if necessary
1015cdf0e10cSrcweir             if (arEvents.length != eventCount)
1016cdf0e10cSrcweir             {
1017cdf0e10cSrcweir                 PropertyChangeEvent[] arPropsTmp= new PropertyChangeEvent[eventCount];
1018cdf0e10cSrcweir                 System.arraycopy(arEvents, 0, arPropsTmp, 0, eventCount);
1019cdf0e10cSrcweir                 arEvents= arPropsTmp;
1020cdf0e10cSrcweir             }
1021cdf0e10cSrcweir             listener.propertiesChange(arEvents);
1022cdf0e10cSrcweir         }
1023cdf0e10cSrcweir     }
1024cdf0e10cSrcweir     // XMultiPropertySet -----------------------------------------------------------------------------------
1025cdf0e10cSrcweir     /** If a value for a property could not be retrieved then the respective element in the returned
1026cdf0e10cSrcweir      *  array has the value null.
1027cdf0e10cSrcweir      */
getPropertyValues(String[] propNames)1028cdf0e10cSrcweir     public Object[] getPropertyValues(String[] propNames)
1029cdf0e10cSrcweir     {
1030cdf0e10cSrcweir         Object[] arValues= new Object[propNames.length];
1031cdf0e10cSrcweir         synchronized (this)
1032cdf0e10cSrcweir         {
1033cdf0e10cSrcweir             for (int i= 0; i < propNames.length; i++)
1034cdf0e10cSrcweir             {
1035cdf0e10cSrcweir                 Object value= null;
1036cdf0e10cSrcweir                 try
1037cdf0e10cSrcweir                 {
1038cdf0e10cSrcweir                     value= getPropertyValue(propNames[i]);
1039cdf0e10cSrcweir                 }
1040cdf0e10cSrcweir                 catch (Exception e)
1041cdf0e10cSrcweir                 {
1042cdf0e10cSrcweir                 }
1043cdf0e10cSrcweir                 arValues[i]= value;
1044cdf0e10cSrcweir             }
1045cdf0e10cSrcweir         }
1046cdf0e10cSrcweir         return arValues;
1047cdf0e10cSrcweir     }
1048cdf0e10cSrcweir     // XMultiPropertySet -----------------------------------------------------------------------------------
removePropertiesChangeListener(XPropertiesChangeListener xPropertiesChangeListener)1049cdf0e10cSrcweir     public void removePropertiesChangeListener(XPropertiesChangeListener xPropertiesChangeListener)
1050cdf0e10cSrcweir     {
1051cdf0e10cSrcweir         listenerContainer.removeInterface(XPropertiesChangeListener.class, xPropertiesChangeListener);
1052cdf0e10cSrcweir     }
1053cdf0e10cSrcweir     // XMultiPropertySet -----------------------------------------------------------------------------------
1054a893be29SPedro Giffuni     /** If the array of property names contains an unknown property then it will be ignored.
1055cdf0e10cSrcweir      */
setPropertyValues(String[] propNames, Object[] values)1056cdf0e10cSrcweir     public void setPropertyValues(String[] propNames, Object[] values) throws PropertyVetoException, com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
1057cdf0e10cSrcweir     {
1058cdf0e10cSrcweir         for (int i= 0; i < propNames.length; i++)
1059cdf0e10cSrcweir         {
1060cdf0e10cSrcweir             try
1061cdf0e10cSrcweir             {
1062cdf0e10cSrcweir                 setPropertyValue(propNames[i], values[i]);
1063cdf0e10cSrcweir             }
1064cdf0e10cSrcweir             catch (UnknownPropertyException e)
1065cdf0e10cSrcweir             {
1066cdf0e10cSrcweir                 continue;
1067cdf0e10cSrcweir             }
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir         }
1070cdf0e10cSrcweir     }
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir     private class PropertySetInfo implements XPropertySetInfo
1073cdf0e10cSrcweir     {
getProperties()1074cdf0e10cSrcweir         public com.sun.star.beans.Property[] getProperties()
1075cdf0e10cSrcweir         {
1076cdf0e10cSrcweir             return PropertySet.this.getProperties();
1077cdf0e10cSrcweir         }
1078cdf0e10cSrcweir 
getPropertyByName(String name)1079cdf0e10cSrcweir         public com.sun.star.beans.Property getPropertyByName(String name) throws UnknownPropertyException
1080cdf0e10cSrcweir         {
1081cdf0e10cSrcweir             return getProperty(name);
1082cdf0e10cSrcweir         }
1083cdf0e10cSrcweir 
hasPropertyByName(String name)1084cdf0e10cSrcweir         public boolean hasPropertyByName(String name)
1085cdf0e10cSrcweir         {
1086cdf0e10cSrcweir             return getProperty(name) != null;
1087cdf0e10cSrcweir         }
1088cdf0e10cSrcweir 
1089cdf0e10cSrcweir     }
1090cdf0e10cSrcweir }
1091