/*
 * 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 org.apache.felix.scr;


import java.util.Dictionary;

import org.osgi.framework.Bundle;
import org.osgi.service.component.ComponentInstance;


/**
 * The <code>Component</code> interface represents a single component managed
 * by the Service Component Runtime. Management agents may access the Component
 * instances through the {@link ScrService}.
 */
public interface Component
{

    /**
     * The Component has just been created and is still disabled or it has
     * been disabled by calling the {@link #disable()} method (value is 1).
     */
    static final int STATE_DISABLED = 1;

    /**
     * The Component is being enabled (value is 512). After the component has
     * been enabled it enters the {@link #STATE_UNSATISFIED} state.
     * @since 1.2
     * @deprecated since 1.8.0
     */
    static final int STATE_ENABLING = 512;

    /**
     * The Component has been enabled and is now going to be activated (value
     * is 2).
     * @deprecated as of version 1.2 the enabled state is collapsed into the
     *      {@link #STATE_UNSATISFIED} state. This status code is never returned
     *      from the {@link #getState()} method.
     */
    static final int STATE_ENABLED = 2;

    /**
     * The Component activation failed because any dependency is not satisfied
     * (value is 4).
     */
    static final int STATE_UNSATISFIED = 4;

    /**
     * The Component is currently being activated either because it has been
     * enabled or because any dependency which was previously unsatisfied has
     * become satisfied (value is 8).
     * @deprecated since 1.8.0 transient states are no longer used
     */
    static final int STATE_ACTIVATING = 8;

    /**
     * The Component has successfully been activated and is fully functional
     * (value is 16). This is the state of immediate components after
     * successful activation. Delayed and Service Factory Components enter
     * this state when the service instance has actually been instantiated because
     * the service has been acquired.
     */
    static final int STATE_ACTIVE = 16;

    /**
     * The Component has successfully been activated but is a Delayed or Service
     * Factory Component pending instantiation on first use (value is 32).
     */
    static final int STATE_REGISTERED = 32;

    /**
     * The Component is a Component Factory ready to create Component instances
     * with the <code>ComponentFactory.newInstance(Dictionary)</code> method
     * or (if enabled with the <code>ds.factory.enabled</code> configuration) to
     * manage Component instances from configuration data received from the
     * Configuration Admin Service (value is 64).
     */
    static final int STATE_FACTORY = 64;

    /**
     * The Component is being deactivated either because it is being disabled
     * or because a dependency is not satisfied any more (value is 128). After
     * deactivation the Component enters the {@link #STATE_UNSATISFIED} state.
     * @deprecated since 1.8.0 transient states are no longer used
     */
    static final int STATE_DEACTIVATING = 128;

    /**
     * The Component is being disabled (value is 1024). After the component has
     * been disabled it enters the {@link #STATE_DISABLED} state.
     * @since 1.2
     * @deprecated since 1.8.0 transient states are no longer used
     */
    static final int STATE_DISABLING = 1024;

    /**
     * The Component is being disposed off (value is 2048). After the component
     * has been disposed off it enters the {@link #STATE_DESTROYED} state.
     * @since 1.2
     * @deprecated since 1.8.0 transient states are no longer used
     */
    static final int STATE_DISPOSING = 2048;

    /**
     * The Component has been destroyed and cannot be used any more (value is
     * 256). This state is only used when the bundle declaring the component
     * is being stopped and all components have to be removed.
     * @deprecated as of version 1.2 this constant has been renamed to
     *      {@link #STATE_DISPOSED}.
     */
    static final int STATE_DESTROYED = 256;

    /**
     * The Component has been disposed off and cannot be used any more (value is
     * 256). This state is used when the bundle declaring the component
     * is being stopped and all components have to be removed. This status is
     * also the final status of a component after the
     * <code>ComponentInstance.dispose()</code> method has been called.
     * @since 1.2
     */
    static final int STATE_DISPOSED = 256;


    /**
     * Returns the component ID of this component. This ID is managed by the
     * SCR. If the component is not currently enabled the ID might not be
     * assigned to the component (yet) and this method will return -1 in this
     * case.
     */
    long getId();


    /**
     * Returns the name of the component, which is also used as the service PID.
     * This method provides access to the <code>name</code> attribute of the
     * <code>component</code> element.
     */
    String getName();


    /**
     * Returns the current state of the Component, which is one of the
     * <code>STATE_*</code> constants defined in this interface.
     */
    int getState();


    /**
     * Returns the <code>Bundle</code> declaring this component.
     */
    Bundle getBundle();


    /**
     * Returns the component factory name or <code>null</code> if this component
     * is not defined as a component factory. This method provides access to
     * the <code>factory</code> attribute of the <code>component</code>
     * element.
     */
    String getFactory();


    /**
     * Returns <code>true</code> if this component is a service factory. This
     * method returns the value of the <code>serviceFactory</code> attribute of
     * the <code>service</code> element. If the component has no service
     * element, this method returns <code>false</code>.
     */
    boolean isServiceFactory();


    /**
     * Returns the class name of the Component implementation. This method
     * provides access to the <code>class</code> attribute of the
     * <code>implementation</code> element.
     */
    String getClassName();


    /**
     * Returns whether the Component is declared to be enabled initially. This
     * method provides access to the <code>enabled</code> attribute of the
     * <code>component</code> element.
     */
    boolean isDefaultEnabled();


    /**
     * Returns whether the Component is an Immediate or a Delayed Component.
     * This method provides access to the <code>immediate</code> attribute of
     * the <code>component</code> element.
     */
    boolean isImmediate();


    /**
     * Returns an array of service names provided by this Component or
     * <code>null</code> if the Component is not registered as a service. This
     * method provides access to the <code>interface</code> attributes of the
     * <code>provide</code> elements.
     */
    String[] getServices();


    /**
     * Returns the properties of the Component. The Dictionary returned is a
     * private copy of the actual properties and contains the same entries as
     * are used to register the Component as a service and are returned by
     * the <code>ComponentContext.getProperties()</code> method.
     */
    Dictionary getProperties();


    /**
     * Returns an array of {@link Reference} instances representing the service
     * references (or dependencies) of this Component. If the Component has no
     * references, <code>null</code> is returned.
     */
    Reference[] getReferences();


    /**
     * Returns the <code>org.osgi.service.component.ComponentInstance</code>
     * representing this component or <code>null</code> if this component
     * is not been activated yet.
     *
     * @since 1.2
     */
    ComponentInstance getComponentInstance();


    /**
     * Returns the name of the method to be called when the component is being
     * activated.
     * <p>
     * This method never returns <code>null</code>, that is, if this method is
     * not declared in the component descriptor this method returns the
     * default value <i>activate</i>.
     *
     * @since 1.2
     */
    String getActivate();


    /**
     * Returns <code>true</code> if the name of the method to be called on
     * component activation (see {@link #getActivate()} is declared in the
     * component descriptor or not.
     * <p>
     * For a component declared in a Declarative Services 1.0 descriptor, this
     * method always returns <code>false</code>.
     *
     * @since 1.2
     */
    boolean isActivateDeclared();


    /**
     * Returns the name of the method to be called when the component is being
     * deactivated.
     * <p>
     * This method never returns <code>null</code>, that is, if this method is
     * not declared in the component descriptor this method returns the
     * default value <i>deactivate</i>.
     *
     * @since 1.2
     */
    String getDeactivate();


    /**
     * Returns <code>true</code> if the name of the method to be called on
     * component deactivation (see {@link #getDeactivate()} is declared in the
     * component descriptor or not.
     * <p>
     * For a component declared in a Declarative Services 1.0 descriptor, this
     * method always returns <code>false</code>.
     *
     * @since 1.2
     */
    boolean isDeactivateDeclared();


    /**
     * Returns the name of the method to be called when the component
     * configuration has been updated or <code>null</code> if such a method is
     * not declared in the component descriptor.
     * <p>
     * For a component declared in a Declarative Services 1.0 descriptor, this
     * method always returns <code>null</code>.
     *
     * @since 1.2
     */
    String getModified();


    /**
     * Returns the configuration policy declared in the component descriptor.
     * If the component descriptor is a Declarative Services 1.0 descriptor or
     * no configuration policy has been declared, the default value
     * <i>optional</i> is returned.
     * <p>
     * The returned string is one of the three policies defined in the
     * Declarative Services specification 1.1:
     * <dl>
     * <dt>optional</dt>
     * <dd>Configuration from the Configuration Admin service is supplied to
     * the component if available. Otherwise the component is activated without
     * Configuration Admin configuration. This is the default value reflecting
     * the behaviour of Declarative Services 1.0</dd>
     * <dt>require</dt>
     * <dd>Configuration is required. The component remains unsatisfied until
     * configuration is available from the Configuration Admin service.</dd>
     * <dt>ignore</dt>
     * <dd>Configuration is ignored. No Configuration Admin service
     * configuration is supplied to the component.</dd>
     * </dl>
     *
     * @since 1.2
     */
    String getConfigurationPolicy();

    /**
     * Returns the configuration pid declared in the component descriptor. 
     * The value is used to retrieve the component configuration from the 
     * OSGi configuration admin service. The value returned by this method 
     * depends on the Declarative Service namespace used by the component:
     * <p>
     * <dl>
     * <dt>DS 1.0</dt>
     * <dd>The component name is returned.</dd>
     * <dt>DS 1.1</dt>
     * <dd>The component name is returned, if it has been specified. If not specified, 
     * then the default component name is returned (that is the fully qualified component
     * class name).
     * <dt>DS 1.2</dt>
     * <dd>The value of the configuration-pid attribute is returned if it has been specified.
     * If not specified, then the same DS 1.1 rules are applied.</dd>
     * </dl>
     *
     * @since 1.2
     */
    String getConfigurationPid();

    /**
     * Returns whether the configuration-pid has been declared in the descriptor
     * or not.
     *
     * @return whether the configuration-pid has method has been declared in the descriptor
     *      or not.
     * @since DS 1.2
     */
    boolean isConfigurationPidDeclared();

    /**
     * Enables this Component if it is disabled. If the Component is not
     * currently {@link #STATE_DISABLED disabled} this method has no effect. If
     * the Component is {@link #STATE_DESTROYED destroyed}, this method throws
     * an <code>IllegalStateException</code>.
     *
     * @throws IllegalStateException If the Component is destroyed.
     */
    void enable();


    /**
     * Disables this Component if it is enabled. If the Component is already
     * {@link #STATE_DISABLED disabled} this method has no effect. If the
     * Component is {@link #STATE_DESTROYED destroyed}, this method throws an
     * <code>IllegalStateException</code>.
     *
     * @throws IllegalStateException If the Component is destroyed.
     */
    void disable();

}
