/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



package test.cppuhelper.propertysetmixin.comp;

import com.sun.star.beans.Ambiguous;
import com.sun.star.beans.Defaulted;
import com.sun.star.beans.Optional;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.XFastPropertySet;
import com.sun.star.beans.XPropertyAccess;
import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.beans.XVetoableChangeListener;
import com.sun.star.comp.loader.FactoryHelper;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XEventListener;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.lib.uno.helper.PropertySetMixin;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.uno.Any;
import com.sun.star.uno.IQueryInterface;
import com.sun.star.uno.Type;
import com.sun.star.uno.XComponentContext;
import test.cppuhelper.propertysetmixin.XSupplier;
import test.cppuhelper.propertysetmixin.XTest3;

public final class JavaSupplier extends WeakBase implements XSupplier {
    public JavaSupplier(XComponentContext context) {
        this.context = context;
    }

    public XComponent getEmpty1() { return new Empty1(); }

    public XComponent getEmpty2() { return new Empty2(); }

    public XTest3 getFull() { return new Full(); }

    public static XSingleServiceFactory __getServiceFactory(
        String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey)
    {
        return implName.equals(implementationName)
            ? FactoryHelper.getServiceFactory(
                JavaSupplier.class, serviceName, multiFactory, regKey)
            : null;
    }

    private static final String implementationName
    = JavaSupplier.class.getName();
    private static final String serviceName
    = "test.cppuhelper.propertysetmixin.JavaSupplier";

    private final class Empty1 extends WeakBase implements XComponent {
        public Empty1() {}

        public void dispose() {
            prop.dispose();
        }

        public void addEventListener(XEventListener listener) {}

        public void removeEventListener(XEventListener listener) {}

        private final PropertySetMixin prop = new PropertySetMixin(
            context, this, new Type(XComponent.class), null);
    }

    private final class Empty2 extends WeakBase
        implements XComponent, XPropertySet, XFastPropertySet, XPropertyAccess
    {
        public Empty2() {}

        public void dispose() {
            prop.dispose();
        }

        public void addEventListener(XEventListener listener) {}

        public void removeEventListener(XEventListener listener) {}

        public com.sun.star.beans.XPropertySetInfo getPropertySetInfo() {
            return prop.getPropertySetInfo();
        }

        public void setPropertyValue(String propertyName, Object value)
            throws UnknownPropertyException, PropertyVetoException,
            com.sun.star.lang.IllegalArgumentException, WrappedTargetException
        {
            prop.setPropertyValue(propertyName, value);
        }

        public Object getPropertyValue(String propertyName)
            throws UnknownPropertyException, WrappedTargetException
        {
            return prop.getPropertyValue(propertyName);
        }

        public void addPropertyChangeListener(
            String propertyName, XPropertyChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.addPropertyChangeListener(propertyName, listener);
        }

        public void removePropertyChangeListener(
            String propertyName, XPropertyChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.removePropertyChangeListener(propertyName, listener);
        }

        public void addVetoableChangeListener(
            String propertyName, XVetoableChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.addVetoableChangeListener(propertyName, listener);
        }

        public void removeVetoableChangeListener(
            String propertyName, XVetoableChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.removeVetoableChangeListener(propertyName, listener);
        }

        public void setFastPropertyValue(int handle, Object value)
            throws UnknownPropertyException, PropertyVetoException,
            com.sun.star.lang.IllegalArgumentException, WrappedTargetException
        {
            prop.setFastPropertyValue(handle, value);
        }

        public Object getFastPropertyValue(int handle)
            throws UnknownPropertyException, WrappedTargetException
        {
            return prop.getFastPropertyValue(handle);
        }

        public PropertyValue[] getPropertyValues() {
            return prop.getPropertyValues();
        }

        public void setPropertyValues(PropertyValue[] props)
            throws UnknownPropertyException, PropertyVetoException,
            com.sun.star.lang.IllegalArgumentException, WrappedTargetException
        {
            prop.setPropertyValues(props);
        }

        private final PropertySetMixin prop = new PropertySetMixin(
            context, this, new Type(XComponent.class), null);
    }

    private final class Full extends WeakBase
        implements XTest3, XPropertySet, XFastPropertySet, XPropertyAccess
    {
        public Full() {}

        public synchronized int getFirst() {
            return a1;
        }

        public void setFirst(int value) {
            prop.prepareSet("First", null);
            synchronized (this) {
                a1 = value;
            }
        }

        public synchronized Ambiguous getSecond()
            throws UnknownPropertyException
        {
            return a2;
        }

        public void setSecond(Ambiguous value)
            throws PropertyVetoException, UnknownPropertyException
        {
            PropertySetMixin.BoundListeners l
                = new PropertySetMixin.BoundListeners();
            prop.prepareSet(
                "Second", Any.VOID,
                (((Optional) ((Defaulted) value.Value).Value).IsPresent
                 ? ((Optional) ((Defaulted) value.Value).Value).Value
                 : Any.VOID),
                l);
            synchronized (this) {
                a2 = value;
            }
            l.notifyListeners();
        }

        public int getThird() throws UnknownPropertyException {
            throw new UnknownPropertyException("Third", this);
        }

        public void setThird(int value) throws UnknownPropertyException {
            throw new UnknownPropertyException("Third", this);
        }

        public int getFourth() throws UnknownPropertyException {
            throw new UnknownPropertyException("Fourth", this);
        }

        public void setFourth(int value) throws UnknownPropertyException {
            throw new UnknownPropertyException("Fourth", this);
        }

        public com.sun.star.beans.XPropertySetInfo getPropertySetInfo() {
            return prop.getPropertySetInfo();
        }

        public void setPropertyValue(String propertyName, Object value)
            throws UnknownPropertyException, PropertyVetoException,
            com.sun.star.lang.IllegalArgumentException, WrappedTargetException
        {
            prop.setPropertyValue(propertyName, value);
        }

        public Object getPropertyValue(String propertyName)
            throws UnknownPropertyException, WrappedTargetException
        {
            return prop.getPropertyValue(propertyName);
        }

        public void addPropertyChangeListener(
            String propertyName, XPropertyChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.addPropertyChangeListener(propertyName, listener);
        }

        public void removePropertyChangeListener(
            String propertyName, XPropertyChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.removePropertyChangeListener(propertyName, listener);
        }

        public void addVetoableChangeListener(
            String propertyName, XVetoableChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.addVetoableChangeListener(propertyName, listener);
        }

        public void removeVetoableChangeListener(
            String propertyName, XVetoableChangeListener listener)
            throws UnknownPropertyException, WrappedTargetException
        {
            prop.removeVetoableChangeListener(propertyName, listener);
        }

        public void setFastPropertyValue(int handle, Object value)
            throws UnknownPropertyException, PropertyVetoException,
            com.sun.star.lang.IllegalArgumentException, WrappedTargetException
        {
            prop.setFastPropertyValue(handle, value);
        }

        public Object getFastPropertyValue(int handle)
            throws UnknownPropertyException, WrappedTargetException
        {
            return prop.getFastPropertyValue(handle);
        }

        public PropertyValue[] getPropertyValues() {
            return prop.getPropertyValues();
        }

        public void setPropertyValues(PropertyValue[] props)
            throws UnknownPropertyException, PropertyVetoException,
            com.sun.star.lang.IllegalArgumentException, WrappedTargetException
        {
            prop.setPropertyValues(props);
        }

        private final PropertySetMixin prop = new PropertySetMixin(
            context, this, new Type(XTest3.class), new String[] { "Third" });

        private int a1 = 0;
        private Ambiguous a2 = new Ambiguous(
            new Defaulted(new Optional(), true), false);
    }

    private final XComponentContext context;
}
