/*
 * 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.uima.resource.metadata;

import java.util.Collection;

import org.apache.uima.UIMA_UnsupportedOperationException;
import org.apache.uima.resource.ExternalResourceDescription;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.util.InvalidXMLException;

/**
 * Defines a set of external resources and their bindings to
 * {@link org.apache.uima.resource.ExternalResourceDependency ExternalResourceDependencies}.
 * <p>
 * Resource Manager Configurations can declare that they {@link #getImports() import} other Resource
 * Manager Configurations. At runtime, these imports will be resolved to create a single logical
 * Resource Manager Configuration..
 * <p>
 * Note that type system imports are not automatically resolved when a ResourceMangerConfiguration
 * is deserialized from XML. To resolve the imports, call the {@link #resolveImports()} method.
 * Import resolution is done automatically when the {@link org.apache.uima.resource.ResourceManager}
 * is initialized (e.g. during AnalysisEngine initialization).
 * <p>
 * Resource Manager Configurations can optionally be assigned a {@link #getName() name},
 * {@link #getDescription() description}, {@link #getVendor() vendor}, and {@link #getVersion()
 * version}. It is recommended that these properties be set on any Resource Manager Configuration
 * that is meant to be shared by (imported by) multiple components.
 */
public interface ResourceManagerConfiguration extends MetaDataObject {
  /**
   * Gets the name of this Resource Manager Configuration.
   * 
   * @return the name of this Resource Manager Configuration, null if none has been specified.
   */
  String getName();

  /**
   * Sets the name of this Resource Manager Configuration.
   * 
   * @param aName
   *          the name of this Resource Manager Configuration
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void setName(String aName);

  /**
   * Gets the version number of this Resource Manager Configuration.
   * 
   * @return the version number of this Resource Manager Configuration, as a String, null if none
   *         has been specified.
   */
  String getVersion();

  /**
   * Sets the version number of this Resource Manager Configuration.
   * 
   * @param aVersion
   *          the version number of this Resource Manager Configuration, as a String
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void setVersion(String aVersion);

  /**
   * Gets the description of this Resource Manager Configuration.
   * 
   * @return the description of this Resource Manager Configuration, null if none has been
   *         specified.
   */
  String getDescription();

  /**
   * Sets the description of this Resource Manager Configuration.
   * 
   * @param aDescription
   *          the description of this Resource Manager Configuration
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void setDescription(String aDescription);

  /**
   * Gets the vendor of this Resource Manager Configuration.
   * 
   * @return the vendor of this Resource Manager Configuration, as a String
   */
  String getVendor();

  /**
   * Sets the vendor of this Resource Manager Configuration.
   * 
   * @param aVendor
   *          the vendor of this Resource Manager Configuration, as a String, null if none has been
   *          specified.
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void setVendor(String aVendor);

  /**
   * Gets the imports declared by this Resource Manager Configuration.
   * 
   * @return an array of imports declared by this Resource Manager Configuration.
   */
  Import[] getImports();

  /**
   * Sets the imports declared by this Resource Manager Configuration.
   * 
   * @param aImports
   *          an array of imports declared by this Resource Manager Configuration.
   */
  void setImports(Import[] aImports);

  /**
   * Gets the import declared by this Resource Manager Configuration, if any.
   * 
   * @return an object that defines how to locate an external XML file defining the resource manager
   *         configuration. Returns null if there is no import.
   * @deprecated Use {@link #getImports()} instead. There may be many imports; this method only
   *             returns the first.
   */
  @Deprecated
  Import getImport();

  /**
   * Sets the import declared by this Resource Manager Configuration, if any.
   * 
   * @param aImport
   *          an object that defines how to locate an external XML file defining the resource
   *          manager configuration. Null indicates that there is no import.
   * @deprecated Use {@link #setImports(Import[])} instead.
   */
  @Deprecated
  void setImport(Import aImport);

  /**
   * Gets the descriptions of the external resources to be instantiated and managed by the resource
   * manager.
   * 
   * @return an array of {@link org.apache.uima.resource.ExternalResourceDescription} objects that
   *         describe the external resources.
   */
  ExternalResourceDescription[] getExternalResources();

  /**
   * Sets the descriptions of the external resources to be instantiated and managed by the resource
   * manager.
   * 
   * @param aDescriptions
   *          an array of {@link org.apache.uima.resource.ExternalResourceDescription} objects that
   *          describe the external resources.
   */
  void setExternalResources(ExternalResourceDescription... aDescriptions);

  /**
   * Adds a External Resource to this configuration
   * 
   * @param aExternalResourceDescription
   *          the ExternalResourceDescription to add
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void addExternalResource(ExternalResourceDescription aExternalResourceDescription);

  /**
   * Removes an ExternalResource from this configuration.
   * 
   * @param aExternalResourceDescription
   *          the ExternalResourceDescription to remove (must be == with an
   *          ExternalResourceDescription in this collection, or this method will do nothing).
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void removeExternalResource(ExternalResourceDescription aExternalResourceDescription);

  /**
   * Gets the bindings between an Analysis Engine's
   * {@link org.apache.uima.resource.ExternalResourceDependency ExternalResourceDependencies} and
   * the {@link org.apache.uima.resource.ExternalResourceDescription} objects defined in this
   * configuration.
   * 
   * @return an array of {@link org.apache.uima.resource.metadata.ExternalResourceBinding} objects
   *         that bind dependencies to resources.
   */
  ExternalResourceBinding[] getExternalResourceBindings();

  /**
   * Sets the bindings between an Analysis Engine's
   * {@link org.apache.uima.resource.ExternalResourceDependency ExternalResourceDependencies} and
   * the {@link org.apache.uima.resource.ExternalResourceDescription} objects defined in this
   * configuration.
   * 
   * @param aBindings
   *          an array of {@link org.apache.uima.resource.metadata.ExternalResourceBinding} objects
   *          that bind dependencies to resources.
   */
  void setExternalResourceBindings(ExternalResourceBinding... aBindings);

  /**
   * Adds a External ResourceBinding to this configuration
   * 
   * @param aExternalResourceBinding
   *          the ExternalResourceBinding to add
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void addExternalResourceBinding(ExternalResourceBinding aExternalResourceBinding);

  /**
   * Removes an ExternalResourceBinding from this configuration.
   * 
   * @param aExternalResourceBinding
   *          the ExternalResourceBinding to remove (must be == with an ExternalResourceBinding in
   *          this collection, or this method will do nothing).
   * 
   * @throws UIMA_UnsupportedOperationException
   *           if this object is not modifiable
   */
  void removeExternalResourceBinding(ExternalResourceBinding aExternalResourceBinding);

  /**
   * Resolves any import declarations in this resource manager configuration, adding the imported
   * external resources and external resource bindings directly onto this
   * ResourceManagerConfiguration's {@link #getExternalResources() externalResources} and
   * {@link #getExternalResourceBindings() externalResourceBindings} lists.
   * 
   * @throws InvalidXMLException
   *           if either the import target does not exist or is invalid
   */
  void resolveImports() throws InvalidXMLException;

  /**
   * Resolves any import declarations in this resource manager configuration, adding the imported
   * external resources and external resource bindings directly onto this
   * ResourceManagerConfiguration's {@link #getExternalResources() externalResources} and
   * {@link #getExternalResourceBindings() externalResourceBindings} lists.
   * 
   * @param aResourceManager
   *          the Resource Manager used to locate the XML file imported by name. For example, the
   *          path in which to locate the imported files can be set via the
   *          {@link ResourceManager#setDataPath(String)} method.
   * 
   * @throws InvalidXMLException
   *           if either the import target does not exist or is invalid
   */
  void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException;

  /**
   * Resolves any import declarations in this resource manager configuration, adding the imported
   * external resources and external resource bindings directly onto this
   * ResourceManagerConfiguration's {@link #getExternalResources() externalResources} and
   * {@link #getExternalResourceBindings() externalResourceBindings} lists.
   * <p>
   * This version is used internally to resolve nested imports.
   * 
   * @param aResourceManager
   *          the Resource Manager used to locate the XML file imported by name. For example, the
   *          path in which to locate the imported files can be set via the
   *          {@link ResourceManager#setDataPath(String)} method.
   * @param aAlreadyImportedURLs
   *          names of already imported URLs, so we don't import them again.
   * 
   * @throws InvalidXMLException
   *           if either the import target does not exist or is invalid
   */
  void resolveImports(Collection<String> aAlreadyImportedURLs, ResourceManager aResourceManager)
          throws InvalidXMLException;

}
