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

}
