Hi Christoph,

this kind of wrapper are maybe useful for a specific language but not in general and they provide only a statical snapshot of an UNO object. You have to adapt your wrapper every time the object will change. But of course this shouldn't happen to often. But the wrapper has always the problem that optional interface and properties are not available and you have to deal with this circumstances otherwise the user will be confused anyway. We've addressed all your described obstacles with the new "UNO ease of features" and new API'S will benefit from them. We also plan to adapt often used API areas to support the new features as well. And latest with this improvements this kind of wrapper becomes superfluously. Don't misunderstand me, it's fine to make things easier but from my point of view every wrapper is one too much. The API's and the underlying technology have to be clear and usable without the need of any further wrapper layer. I would agree that we can still improve a lot in our API's and we will do that. But the API is huge and we need more and concrete feedback where the API's lacks of usability and/or completeness (including simple documentation problems, e.g. missing docu ...).

Juergen



Christoph Lutz wrote:
here is a simple wrapper-class for uno-services. please note the included methods for inspecting uno-services in Java (something similar to the XRay-tool)...


------------------------------------------------------------------------

<?xml version="1.0"?>
<snippet language="Java" application="Writer">

<keywords>
        <keyword>wrapper</keyword>
        <keyword>UnoRuntime.queryInterface</keyword>
        <keyword>queryInterface</keyword>
        <keyword>inspect</keyword>
        <keyword>inspection</keyword>
        <keyword>methods</keyword>
        <keyword>interfaces</keyword>
        <keyword>property</keyword>
        <keyword>properties</keyword>
        <keyword>services</keyword>
        <keyword>object</keyword>
        <keyword>convenience</keyword>
        <keyword>class</keyword>
        <keyword>information</keyword>
</keywords>

<authors>
        <author id="CL" initial="true" email="[EMAIL PROTECTED]">Christoph 
Lutz</author>
</authors>

<question heading="Simple wrapper for uno-services">Is there a way to avoid all 
the UnoRuntime.queryInterface-calls
<p>Programming in Java is very uncomfortable. The Java-program is nearly unreadable 
cause of the many temporary variables you need to hold interface-instances. </p>
<p></p>
<p>also uno-services are not very transparent. How do I get the names of the provided 
services, interfaces, properties and methods?</p>
</question>

<answer>
<p>use a wrapperclass to let the wrapper perform the queryInterface-calls. This is my 
wrapper class - simple but effective. </p>
<p></p>
<p>It also provides method for a runtime-inspection similar to the famous 
XRay-tool.</p>
<listing>/*
 * A simple wrapperclass for uno-services.
 * Copyright (C) 2005 Christoph Lutz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
 */

import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;

import com.sun.star.beans.Property;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.container.XEnumeration;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.text.XText;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextField;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.XInterface;
import com.sun.star.util.XCloseable;

/**
 * The class UnoService is a wrapper for UnoService-Objects provided by the
 * OpenOffice.org API. The main aim of this wrapper is to make java-programs
 * more readable by avoiding the neccessity of UnoRuntime.queryInterface-calls.
 * The wrapper performs the queryInterface-calls and holds the corresponding
 * interface-instances. Temporary variables for singular interface-types are no
 * longer needed in your own java-programs.
* * The wrapper provides convenience-methods to certain aspects of uno-services
 * like getter and setter for property-values.
* * The wrapper also increases tranzperency when working with uno-objects. It
 * provides methods to inspect uno-services at runtime and print information
 * about supported-services, implemented interfaces, properties and methods. It
 * makes Uno-Programming in java similar to OOo-Basic programming using tools
 * like the famous XRay-tool.
 */
public class UnoService {
    /**
     * This field contains the original object of the uno-service.
     */
    private final Object unoObject;

    /**
     * This map contains all at least one time required interface-instances of
     * this uno-service.
     */
    private Map interfaceMap;

    /**
     * The constructor creates a new wrapperclass for a given uno-service
     * object.
* * @param unoObject
     *            an arbitrary object returned by the OOo-API
     */
    public UnoService(Object unoObject) {
        this.unoObject = unoObject;
        interfaceMap = new HashMap();
    }

    /**
     * This method returns the interface-instance of this UnoService for a
     * specified interface-type. It performs a UnoRuntime.queryInterface call
     * and caches the result interface-type. If the service doesn&apos;t 
implement
     * the required interface, the method returns 
&lt;code&gt;null&lt;/code&gt;. Use the
     * construct &lt;code&gt;if (myUnoService.xAnInterface() != null) 
...&lt;/code&gt; to
     * ensure the service really implements the interface.
* * @param ifClass
     *            interface-type to query for.
     * @return The interface instance for this uno-service. If the service
     *         doesn&apos;t implement the required interface, the method returns
     *         &lt;code&gt;null&lt;/null&gt;.
     */
    public Object queryInterface(Class ifClass) {
        if (!interfaceMap.containsKey(ifClass)) {
            Object ifInstance = UnoRuntime.queryInterface(ifClass,
                    this.unoObject);
            interfaceMap.put(ifClass, ifInstance);
        }
        return interfaceMap.get(ifClass);
    }

    /***************************************************************************
     * Methods to inspect the uno-service.
     **************************************************************************/

    /**
     * This method returns the implementationName of this unoService-object.
* * @return the implementationName of this unoService-object of the String
     *         &quot;noneUnoService&quot; if the object is not a proper 
UnoService.
     */
    public String getImplememtationName() {
        if (this.xServiceInfo() != null) {
            return this.xServiceInfo().getImplementationName();
        } else {
            return &quot;noneUnoService&quot;;
        }
    }

    /**
     * This method provides information about supported services, implemented
     * interfaces, supported properties and methods of this uno-service. The
     * lists of services, implemented interfaces and methods are sorted in
     * alphabetical ascending order.
* * @return a string containing all the inspection information.
     */
    public String features() {
        String str = &quot;&quot;;
        str += &quot;------------------------------------------\n&quot;;
        str += &quot;ImplementationName: &quot;
                + this.xServiceInfo().getImplementationName() + 
&quot;\n\n&quot;;

        str += dbg_Services();
        str += dbg_SupportedInterfaces();
        str += dbg_Properties();
        str += dbg_SupportedInterfacesAndMethods();
        return str;
    }

    /**
     * This method prints the inspection-information provides by features() to
     * System.out.
     */
    public void printFeatures() {
        System.out.println(features());
    }

    /**
     * This method returns a sorted list of services supported by this
     * uno-service.
* * @return a string containig the inspection-information.
     */
    private String dbg_Services() {
        String str = &quot;Supported UNO-Services: &quot;;
        if (this.xServiceInfo() != null) {
            str += &quot;\n&quot;;
            Iterator servicesIterator = getSortedServiceIterator();
            while (servicesIterator.hasNext()) {
                str += &quot;  &quot; + ((String) servicesIterator.next()) + 
&quot;\n&quot;;
            }
        } else {
            str += &quot;none\n&quot;;
        }
        return str + &quot;\n&quot;;
    }

    /**
     * This method returns a sorted list of properties supported by this
     * uno-service.
* * @return a string containig the inspection-information.
     */
    private String dbg_Properties() {
        String str = &quot;Supported Properties: &quot;;
        if (this.xPropertySet() != null) {
            str += &quot;\n&quot;;
            Property[] props = this.xPropertySet().getPropertySetInfo()
                    .getProperties();
            for (int i = 0; i &lt; props.length; i++) {
                str += &quot;  &quot; + props[i].Name + &quot; - &quot;
                        + props[i].Type.getZClass().getSimpleName() + 
&quot;\n&quot;;
            }
        } else {
            str = &quot;none&quot;;
        }
        return str + &quot;\n&quot;;
    }

    /**
     * This method returns a sorted list of implemented interfaces.
* * @return a string containig the inspection-information.
     */
    public String dbg_SupportedInterfaces() {
        String str = &quot;Supported Interfaces: &quot;;
        if (this.xTypeProvider() != null) {
            str += &quot;\n&quot;;
            Iterator typesIterator = getSortedTypesIterator();
            while (typesIterator.hasNext()) {
                str += &quot;  &quot; + ((Type) 
typesIterator.next()).getTypeName()
                        + &quot;\n&quot;;
            }
        } else {
            str += &quot;none&quot;;
        }
        return str + &quot;\n&quot;;
    }

    /**
     * This method returns a sorted list of implemented interfaces and their
     * corresponding methods.
* * @return a string containig the inspection-information.
     */
    private String dbg_SupportedInterfacesAndMethods() {
        String str = &quot;Supported Interfaces and Methods: &quot;;
        if (this.xTypeProvider() != null) {
            str += &quot;\n&quot;;
            Iterator typesIterator = getSortedTypesIterator();
            while (typesIterator.hasNext()) {
                Type type = (Type) typesIterator.next();
                str += &quot;  &quot; + type.getTypeName() + &quot;\n&quot;;
                Iterator methodsIterator = getSortedMethodsIterator(type);
                while (methodsIterator.hasNext()) {
                    Method m = (Method) methodsIterator.next();
                    str += &quot;    - &quot; + m.getName() + &quot;(&quot;;
                    Class[] par = m.getParameterTypes();
                    for (int k = 0; k &lt; par.length; k++) {
                        if (k != 0) {
                            str += &quot;, &quot;;
                        }
                        str += par[k].getSimpleName();
                    }
                    str += &quot;) - &quot; + m.getReturnType().getSimpleName() + 
&quot;\n&quot;;

                }
            }
        } else {
            str += &quot;none&quot;;
        }
        return str + &quot;\n&quot;;
    }

    /**
     * This method returns an Iterator to a sorted list of supported services.
     */
    private Iterator getSortedServiceIterator() {
        return getSortedArrayIterator(this.xServiceInfo()
                .getSupportedServiceNames(), new Comparator() {
            public int compare(Object arg0, Object arg1) {
                return ((String) arg0).compareTo((String) arg1);
            }

            public boolean equals(Object obj) {
                return this == obj;
            }
        });
    }

    /**
     * This method returns an Iterator to a sorted list of methods supported by
     * the specified interface-type.
     */
    private Iterator getSortedMethodsIterator(Type type) {
        Iterator methodsIterator = getSortedArrayIterator(type.getZClass()
                .getDeclaredMethods(), new Comparator() {
            public int compare(Object arg0, Object arg1) {
                return ((Method) arg0).getName().compareTo(
                        ((Method) arg1).getName());
            }

            public boolean equals(Object obj) {
                return this == obj;
            }
        });
        return methodsIterator;
    }

    /**
     * This method returns an Iterator to a sorted List of implemented
     * interface-types.
     */
    private Iterator getSortedTypesIterator() {
        Iterator i = getSortedArrayIterator(this.xTypeProvider().getTypes(),
                new Comparator() {
                    public int compare(Object arg0, Object arg1) {
                        return ((Type) arg0).getTypeName().compareTo(
                                ((Type) arg1).getTypeName());
                    }

                    public boolean equals(Object obj) {
                        return this == obj;
                    }
                });
        return i;
    }

    /**
     * This generic method sorts an array comparing its elements using a
     * comperator. The method is needes by the methods
     * getSortedServiceIterator(), getSortedMethodsIterator(Type type) and
     * getSortedTypesIterator(),
     */
    private Iterator getSortedArrayIterator(Object[] array, Comparator c) {
        TreeSet set = new TreeSet(c);
        for (int i = 0; i &lt; array.length; i++) {
            set.add(array[i]);
        }
        return set.iterator();
    }

    /***************************************************************************
     * convenience-methods
     **************************************************************************/

    /**
     * This method returns the property of the uno-service and wrappes the
     * result in a new UnoService-object.
* * @param p
     *            the name of the required property
     * @return the value of the property, wrapped in an UnoService object.
     * @throws Exception
     */
    public UnoService getPropertyValue(String p) throws Exception {
        if (this.xPropertySet() != null) {
            return new UnoService(this.xPropertySet().getPropertyValue(p));
        } else {
            throw new Exception(
                    &quot;Service doesn&apos;t support interface 
XPropertySet&quot;);
        }
    }

    /**
     * This method sets a property-value of this
* * @param p
     *            the name of the property to set
     * @param o
     *            the value of the property
     * @throws Exception
     */
    public void setPropertyValue(String p, Object o) throws Exception {
        if (this.xPropertySet() != null) {
            this.xPropertySet().setPropertyValue(p, o);
        } else {
            throw new Exception(
                    &quot;Service doesn&apos;t support interface 
XPropertySet&quot;);
        }
    }

    /**
     * This method states if this servic-object provides a specified
     * uno-service.
* * @param s
     *            the fullqualified name of the service.
     * @return true if the object supports the uno-service, otherwise false.
     */
    public boolean supportsService(String s) {
        if (this.xServiceInfo() != null) {
            return this.xServiceInfo().supportsService(s);
        } else {
            return false;
        }
    }

    /**
     * This method returns the original object of this uno-service.
* * @return original object of this uno-service
     */
    public Object getObject() {
        return unoObject;
    }

    /*
     * (non-Javadoc)
* * @see java.lang.Object#toString()
     */
    public String toString() {
        return unoObject.toString();
    }

    /***************************************************************************
     * Interface-Access
* * Extend this section if you need to access an interface not in this list.
     **************************************************************************/

    public XTextDocument xTextDocument() {
        return (XTextDocument) queryInterface(XTextDocument.class);
    }

    public XComponentLoader xComponentLoader() {
        return (XComponentLoader) queryInterface(XComponentLoader.class);
    }

    public XDesktop xDesktop() {
        return (XDesktop) queryInterface(XDesktop.class);
    }

    public XText xText() {
        return (XText) queryInterface(XText.class);
    }

    public XTextRange xTextRange() {
        return (XTextRange) queryInterface(XTextRange.class);
    }

    public XPropertySet xPropertySet() {
        return (XPropertySet) queryInterface(XPropertySet.class);
    }

    public XCloseable xCloseable() {
        return (XCloseable) queryInterface(XCloseable.class);
    }

    public XComponentContext xComponentContext() {
        return (XComponentContext) queryInterface(XComponentContext.class);
    }

    public XMultiComponentFactory xMultiComponentFactory() {
        return (XMultiComponentFactory) 
queryInterface(XMultiComponentFactory.class);
    }

    public XUnoUrlResolver xUnoUrlResolver() {
        return (XUnoUrlResolver) queryInterface(XUnoUrlResolver.class);
    }

    public XServiceInfo xServiceInfo() {
        return (XServiceInfo) queryInterface(XServiceInfo.class);
    }

    public XPropertySetInfo xPropertySetInfo() {
        return (XPropertySetInfo) queryInterface(XPropertySetInfo.class);
    }

    public XInterface xInterface() {
        return (XInterface) queryInterface(XInterface.class);
    }

    public XTypeProvider xTypeProvider() {
        return (XTypeProvider) queryInterface(XTypeProvider.class);
    }

    public XEnumerationAccess xEnumerationAccess() {
        return (XEnumerationAccess) queryInterface(XEnumerationAccess.class);
    }

    public XEnumeration xEnumeration() {
        return (XEnumeration) queryInterface(XEnumeration.class);
    }

    public XTextField xTextField() {
        return (XTextField) queryInterface(XTextField.class);
    }

    //... add wrapper-methods for your own interfaces here...

}</listing>
</answer>

<versions>
        <version number="1.1.x" status="tested"/>
</versions>

<operating-systems>
<operating-system name="All"/>
</operating-systems>

<changelog>
        <change author-id="CL" date="2005-06-12">Initial version</change>
</changelog>

</snippet>


------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to