/*
 * 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.fit.internal;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;

import org.apache.uima.resource.ResourceInitializationException;

/**
 * INTERNAL API - Legacy support plug-in API.
 */
public interface LegacySupportPlugin {
  /**
   * Checks if a legacy version of the given modern annotation is present.
   * 
   * @param aObject
   *          an object that might have a legacy annotation.
   * @param aAnnotationClass
   *          the modern annotation type.
   * @return {@code true} if a legacy version of the annotation is present.
   */
  boolean isAnnotationPresent(AccessibleObject aObject, Class<? extends Annotation> aAnnotationClass);

  /**
   * Checks if a legacy version of the given modern annotation is present.
   * 
   * @param aObject
   *          an object that might have a legacy annotation.
   * @param aAnnotationClass
   *          the modern annotation type.
   * @return {@code true} if a legacy version of the annotation is present.
   */
  boolean isAnnotationPresent(Class<?> aObject, Class<? extends Annotation> aAnnotationClass);

  /**
   * Gets the annotation from the given object. Instead of looking for the given modern annotation,
   * this method looks for a legacy version of the annotation, converts it to a modern annotation
   * and returns that.
   * 
   * @param <L>
   *          legacy annotation type
   * @param <M>
   *          modern annotation type
   * @param aObject
   *          an object that has a legacy annotation.
   * @param aAnnotationClass
   *          the modern annotation type.
   * @return an instance of the modern annotation filled with the data from the legacy annotation.
   */
  <L extends Annotation, M extends Annotation> M getAnnotation(AccessibleObject aObject,
          Class<M> aAnnotationClass);

  /**
   * Gets the annotation from the given object. Instead of looking for the given modern annotation,
   * this method looks for a legacy version of the annotation, converts it to a modern annotation
   * and returns that.
   * 
   * @param <L>
   *          legacy annotation type
   * @param <M>
   *          modern annotation type
   * @param aObject
   *          an object that has a legacy annotation.
   * @param aAnnotationClass
   *          the modern annotation type.
   * @return an instance of the modern annotation filled with the data from the legacy annotation.
   */
  <L extends Annotation, M extends Annotation> M getAnnotation(Class<?> aObject,
          Class<M> aAnnotationClass);
//
//  /**
//   * Get the default value of a property of the annotation. This is used for example to get the
//   * default name of a configuration parameter.
//   * 
//   * @param aObject
//   *          an object that has a legacy annotation.
//   * @param aAnnotationClass
//   *          the modern annotation type.
//   * @param aProperty
//   *          a property of the annotation, e.g. {@code "name"} (see
//   *          {@link ConfigurationParameter#name()})
//   * @return
//   */
//  <M extends Annotation> Object getDefaultValue(AccessibleObject aObject, Class<M> aAnnotationClass,
//          String aProperty);

  /**
   * Get all currently accessible descriptor locations for the given type.
   * 
   * @param aType
   *          the type of metadata to scan for
   * @return an array of locations.
   * @throws ResourceInitializationException
   *           if the locations could not be resolved.
   */
  String[] scanTypeDescriptors(MetaDataType aType) throws ResourceInitializationException;
}
