/*******************************************************************************
 * Copyright (c) 2006, 2009 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *   David Knibb               initial implementation
 *   Matthew Webster           Eclipse 3.2 changes
 *   Martin Lippert            extracted weaving service factory
 *   Martin Lippert            caching of generated classes
 *******************************************************************************/

package org.eclipse.equinox.service.weaving;

import java.io.IOException;
import java.util.Map;

/**
 * The IWeavingService is the interface for weavers for individual bundles. This
 * weaver is used by the core equinox aspects runtime to weave bytecodes when a
 * class is loaded and not read from cache.
 * 
 * @author Martin Lippert
 */
public interface IWeavingService {

	/**
	 * Flush all generated classes from the weaving service so that memory kept by
	 * the weaving service for additional classes can be freed.
	 * 
	 * @param loader The class loader the weaving service belongs to
	 */
	public void flushGeneratedClasses(ClassLoader loader);

	/**
	 * Has the weaving service generated new classes on the fly for the given class?
	 * 
	 * @param loader    The class loader of the woven class
	 * @param className The name of the woven class
	 * @return true, if the weaving service has generated additional classes for the
	 *         woven class (closures, for example)
	 */
	public boolean generatedClassesExistFor(ClassLoader loader, String className);

	/**
	 * Returns a map that contains all generated classes for the given class.
	 * Implementations of this method should remove those classes from internal
	 * lists (to free memory). This means also that calling this method a second
	 * time will return an emptry map.
	 * 
	 * @param className The name of the class for which additional classes were
	 *                  generated
	 * @return The generated classes (key: generated class name, value: generated
	 *         class bytecode)
	 */
	public Map<String, byte[]> getGeneratedClassesFor(String className);

	/**
	 * The key of a concrete weaver for a bundle defines the setting in which the
	 * weaver works. This key typically defines a unique key for the set of aspects
	 * which are woven into this bundle. The core equinox aspects runtime uses this
	 * key to feed the caching service. This means, the weaver should return
	 * different keys for different set of aspects (including versions),
	 * respectively when the cache should switch its context.
	 * 
	 * @return A unique key to define the set of aspects that are woven into the
	 *         bundle to which this weaver belongs
	 */
	public String getKey();

	/**
	 * This method is called for each class which is loaded into the JVM and not
	 * read from cache to do the actual weaving, if necessary.
	 * 
	 * @param name       The fully qualified name of the class to be loaded
	 * @param classbytes The original unmodified bytecode of the class read by the
	 *                   standard OSGi classloading mechanism
	 * @param loader     The classloader whichi s responsible for loading the class
	 * @return The modified (woven) bytecode of the class or null, if no
	 *         modification happened
	 * @throws IOException
	 */
	public byte[] preProcess(String name, byte[] classbytes, ClassLoader loader) throws IOException;

}
