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