/*
 * 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}.
 * @deprecated clients should use {@link org.osgi.service.component.runtime.dto.ComponentDescriptionDTO} instead.
 */
@Deprecated
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
	 */
	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).
	 */
	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 be 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.
	 */
	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
	 */
	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
	 */
	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.
	 */
	@SuppressWarnings("rawtypes")
	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
	 */
	<S> ComponentInstance<S> 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
	 * not 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 behavior 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();

	/**
	 * 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();

}
