Properties

From Apache OpenOffice Wiki
< Documentation‎ | DevGuide
Revision as of 11:11, 17 February 2009 by TJFrazier (Talk | contribs)

Jump to: navigation, search

Properties are name-value pairs belonging to a service and determine the characteristics of an object in a service instance. Usually, properties are used for non-structural attributes, such as font, size or color of objects, whereas get and set methods are used for structural attributes like a parent or sub-object.

In almost all cases, com.sun.star.beans.XPropertySet is used to access properties by name. Other interfaces, for example, are com.sun.star.beans.XPropertyAccess which is used to set and retrieve all properties at once or com.sun.star.beans.XMultiPropertySet which is used to access several specified properties at once. This is useful on remote connections. Additionally, there are interfaces to access properties by numeric ID, such as com.sun.star.beans.XFastPropertySet.

The following example demonstrates how to query and change the properties of a given text document cursor using its XPropertySet interface:

  // get an XPropertySet, here the one of a text cursor
  XPropertySet xCursorProps = (XPropertySet) 
          UnoRuntime.queryInterface(XPropertySet.class, mxDocCursor);
 
  // get the character weight property 
  Object aCharWeight = xCursorProps.getPropertyValue("CharWeight");
  float fCharWeight = AnyConverter.toFloat(aCharWeight);
  System.out.println("before: CharWeight=" + fCharWeight);
 
  // set the character weight property to BOLD
  xCursorProps.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.BOLD));
 
  // get the character weight property again
  aCharWeight = xCursorProps.getPropertyValue("CharWeight");
  fCharWeight = AnyConverter.toFloat(aCharWeight);
  System.out.println("after: CharWeight=" + fCharWeight);

A possible output of this code could be:

 before: CharWeight=100.0
 after: CharWeight=150.0
Documentation caution.png The sequence of property names must be sorted.

The following example deals with multiple properties at once:

  // get an XMultiPropertySet, here the one of the first paragraph
  XEnumerationAccess xEnumAcc = (XEnumerationAccess) UnoRuntime.queryInterface(
      XEnumerationAccess.class, mxDocText);
  XEnumeration xEnum = xEnumAcc.createEnumeration();
  Object aPara = xEnum.nextElement();
  XMultiPropertySet xParaProps = (XMultiPropertySet) UnoRuntime.queryInterface(
      XMultiPropertySet.class, aPara);
 
  // get three property values with a single UNO call
  String[] aNames = new String[3];
  aNames[0] = "CharColor";
  aNames[1] = "CharFontName";
  aNames[2] = "CharWeight";
  Object[] aValues = xParaProps.getPropertyValues(aNames);
 
  // print the three values
  System.out.println("CharColor=" + AnyConverter.toLong(aValues[0]));
  System.out.println("CharFontName=" + AnyConverter.toString(aValues[1]));
  System.out.println("CharWeight=" + AnyConverter.toFloat(aValues[2]));

Properties can be assigned flags to determine a specific behavior of the property, such as read-only, bound, constrained or void. Possible flags are specified in com.sun.star.beans.PropertyAttribute. Read-only properties cannot be set. Bound properties broadcast changes of their value to registered listeners and constrained properties veto changes to these listeners.

Properties might have a status specifying where the value comes from. See com.sun.star.beans.XPropertyState. The value determines if the value comes from the object, a style sheet or if it cannot be determined at all. For example, in a multi-selection with multiple values within this selection.

The following example shows how to find out status information about property values:

  // get an XPropertySet, here the one of a text cursor
  XPropertySet xCursorProps = (XPropertySet) UnoRuntime.queryInterface(
      XPropertySet.class, mxDocCursor);
 
  // insert "first" in NORMAL character weight
  mxDocText.insertString(mxDocCursor, "first ", true);
  xCursorProps.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.NORMAL));
 
  // append "second" in BOLD character weight
  mxDocCursor.collapseToEnd();
  mxDocText.insertString(mxDocCursor, "second", true);
  xCursorProps.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.BOLD));
 
  // try to get the character weight property of BOTH words
  mxDocCursor.gotoStart(true);
  try {
      Object aCharWeight = xCursorProps.getPropertyValue("CharWeight");
      float fCharWeight = AnyConverter.toFloat(aCharWeight );
      System.out.println("CharWeight=" + fCharWeight);
  } catch (NullPointerException e) { 
      System.out.println("CharWeight property is NULL");
  }
 
  // query the XPropertState interface of the cursor properties
  XPropertyState xCursorPropsState = (XPropertyState) UnoRuntime.queryInterface(
      XPropertyState.class, xCursorProps);
 
  // get the status of the character weight property
  PropertyState eCharWeightState = xCursorPropsState.getPropertyState("CharWeight");
  System.out.print("CharWeight property state has ");
  if (eCharWeightState == PropertyState.AMBIGUOUS_VALUE)
      System.out.println("an ambiguous value");
  else
      System.out.println("a clear value");

The property state of character weight is queried for a string like this:

 first second

And the output is:

 CharWeight property is NULL
 CharWeight property state has an ambiguous value

The description of properties available for a certain object is given by com.sun.star.beans.XPropertySetInfo. Multiple objects can share the same property information for their description. This makes it easier for introspective caches that are used in scripting languages where the properties are accessed directly, without directly calling the methods of the interfaces mentioned above.

This example shows how to find out which properties an object provides using com.sun.star.beans.XPropertySetInfo:

  try {
      // get an XPropertySet, here the one of a text cursor
      XPropertySet xCursorProps = (XPropertySet)UnoRuntime.queryInterface(
          XPropertySet.class, mxDocCursor);
 
      // get the property info interface of this XPropertySet
      XPropertySetInfo xCursorPropsInfo = xCursorProps.getPropertySetInfo();
 
      // get all properties (NOT the values) from XPropertySetInfo
      Property[] aProps = xCursorPropsInfo.getProperties();
      int i;
      for (i = 0; i < aProps.length; ++i) {
          // number of property within this info object
          System.out.print("Property #" + i);
 
          // name of property
          System.out.print(": Name<" + aProps[i].Name);
 
          // handle of property (only for XFastPropertySet)
          System.out.print("> Handle<" + aProps[i].Handle);
 
          // type of property
          System.out.print("> " + aProps[i].Type.toString());
 
          // attributes (flags)
          System.out.print(" Attributes<");
          short nAttribs = aProps[i].Attributes;
          if ((nAttribs & PropertyAttribute.MAYBEVOID) != 0)
              System.out.print("MAYBEVOID|");
          if ((nAttribs & PropertyAttribute.BOUND) != 0)
              System.out.print("BOUND|");
          if ((nAttribs & PropertyAttribute.CONSTRAINED) != 0)
              System.out.print("CONSTRAINED|");
          if ((nAttribs & PropertyAttribute.READONLY) != 0)
              System.out.print("READONLY|");
          if ((nAttribs & PropertyAttribute.TRANSIENT) != 0)
              System.out.print("TRANSIENT|");
          if ((nAttribs & PropertyAttribute.MAYBEAMBIGUOUS ) != 0)
              System.out.print("MAYBEAMBIGUOUS|");
          if ((nAttribs & PropertyAttribute.MAYBEDEFAULT) != 0)
              System.out.print("MAYBEDEFAULT|");
          if ((nAttribs & PropertyAttribute.REMOVEABLE) != 0)
              System.out.print("REMOVEABLE|");
          System.out.println("0>");
      }
  } catch (Exception e) {
      // If anything goes wrong, give the user a stack trace
      e.printStackTrace(System.out);
  }

The following is an example output for the code above. The output shows the names of the text cursor properties, and their handle, type and property attributes. The handle is not unique, since the specific object does not implement com.sun.star.beans.XFastPropertySet, so proper handles are not needed here.

 Using default connect string: socket,host=localhost,port=8100
 Opening an empty Writer document
 Property #0: Name<BorderDistance> Handle<93> Type<long> Attributes<MAYBEVOID|0>
 Property #1: Name<BottomBorder> Handle<93> Type<com.sun.star.table.BorderLine> Attributes<MAYBEVOID|0>
 Property #2: Name<BottomBorderDistance> Handle<93> Type<long> Attributes<MAYBEVOID|0>
 Property #3: Name<BreakType> Handle<81> Type<com.sun.star.style.BreakType> Attributes<MAYBEVOID|0>
 
 ...
 
 Property #133: Name<TopBorderDistance> Handle<93> Type<long> Attributes<MAYBEVOID|0>
 Property #134: Name<UnvisitedCharStyleName> Handle<38> =Type<string> Attributes<MAYBEVOID|0>
 Property #135: Name<VisitedCharStyleName> Handle<38> Type<string> Attributes<MAYBEVOID|0>

In some cases properties are used to specify the options in a sequence of com.sun.star.beans.PropertyValue. See com.sun.star.view.PrintOptions or com.sun.star.document.MediaDescriptor for examples of properties in sequences. These are not accessed by the methods mentioned above, but by accessing the sequence specified in the language binding.

This example illustrates how to deal with sequences of property values:

  // create a sequence of PropertyValue
  PropertyValue[] aArgs = new PropertyValue[2];
 
  // set name/value pairs (other fields are irrelevant here)
  aArgs[0] = new PropertyValue();
  aArgs[0].Name = "FilterName";
  aArgs[0].Value = "HTML (StarWriter)";
  aArgs[1] = new PropertyValue();
  aArgs[1].Name = "Overwrite";
  aArgs[1].Value = Boolean.TRUE;
 
  // use this sequence of PropertyValue as an argument
  // where a service with properties but without any interfaces is specified
  com.sun.star.frame.XStorable xStorable = (com.sun.star.frame.XStorable) UnoRuntime.queryInterface(
      com.sun.star.frame.XStorable.class, mxDoc);
  xStorable.storeAsURL("file:///tmp/devmanual-test.html", aArgs);

Usually the properties supported by an object, as well as their type and flags are fixed over the lifetime of the object. There may be exceptions. If the properties can be added and removed externally, the interface com.sun.star.beans.XPropertyContainer has to be used. In this case, the fixed com.sun.star.beans.XPropertySetInfo changes its supplied information over the lifetime of the object. Listeners for such changes can register at com.sun.star.beans.XPropertyChangeListener.

Template:Documentation/Tip

The following diagram shows the relationship between the property-related interfaces.

The relationship between property related interfaces

Starting with OpenOffice.org 2.0, interface attributes are comparable in expressiveness to the properties described above:

  • A [property] T P (with type T and name P) corresponds to an [attribute] T P.
  • A [property, readonly] T P corresponds to an [attribute, readonly] T P.
  • A [property, bound] T P corresponds to an [attribute, bound] T P.
  • A [property, maybeambiguous] T P corresponds to an [attribute] com.sun.star.beans.Ambiguous<T> P.
  • A [property, maybedefault] T P corresponds to an [attribute] com.sun.star.beans.Defaulted<T> P.
  • A [property, maybevoid] T P corresponds to an [attribute] com.sun.star.beans.Optional<T> P.
  • A [property, optional] T P corresponds to an [attribute] T P { get raises (com.sun.star.beans.UnknownPropertyException); set raises (com.sun.star.beans.UnknownPropertyException); }.
  • A [property, constrained] T P corresponds to an [attribute] T P { set raises (com.sun.star.beans.PropertyVetoException); }.

Interface attributes offer the following advantages compared to properties:

  • The attributes an object supports follows directly from the description of the interface types the object supports.
  • Accessing an interface attribute is type-safe, whereas accessing a property uses the generic any. This is an advantage mainly in statically typed languages like Java and C++, where accessing an interface attribute typically also requires less code to be written than for accessing a generic property.

The main disadvantage is that the set of interface attributes supported by an object is static, so that scenarios that exploit the dynamic nature of XpropertySet, and so on, do not map well to interface attributes. In cases where it might be useful to have all the interface attributes supported by an object also accessible via XPropertySet etc., the Java and C++ language bindings offer experimental, not yet published support to do just that.See www.openoffice.org to find out more.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages