/*
 * BaseAssociatorProvider.java
 *
 * Generated by {productTitle}  {versionName} - {utilityTitle}
 *
 * {copywrite}
 */
package {packageName}.common;

import javax.cim.CIMInstance;
import javax.cim.CIMObjectPath;
import javax.wbem.CloseableIterator;
import javax.wbem.WBEMException;
import javax.wbem.WBEMOperation;
import javax.wbem.provider.PullAssociatorProvider;

import com.ws.wbem.CloseableAddableIterator;
import com.ws.wbem.query.fql.FQLParser;

public abstract class BaseAssociatorProvider extends BaseProvider implements
		PullAssociatorProvider {

	protected BaseAssociatorProvider() {
		super();
	}

	@Override
	public CloseableIterator<CIMInstance> associators(
			final CIMObjectPath associationClassName,
			final CIMObjectPath target, final String resultClass,
			final String role, final String resultRole,
			final String[] propertyList, final String filterQueryLanguage,
			final String filterQuery, boolean continueOnError)
			throws WBEMException {
		return threadedAssocEnumerate(associationClassName, target,
				resultClass, role, resultRole, propertyList,
				filterQueryLanguage, filterQuery, continueOnError, false);
	}

	@Override
	public CloseableIterator<CIMInstance> references(
			final CIMObjectPath associationClassName,
			final CIMObjectPath target, final String role,
			final String[] propertyList, final String filterQueryLanguage,
			final String filterQuery, boolean continueOnError)
			throws WBEMException {
		return (CloseableIterator<CIMInstance>) threadedRefEnumerate(
				associationClassName, target, role, propertyList,
				filterQueryLanguage, filterQuery, continueOnError, false);
	}

	protected CloseableIterator<CIMInstance> threadedAssocEnumerate(
			final CIMObjectPath assocName, final CIMObjectPath objectName,
			final String resultClass, final String role,
			final String resultRole, final String[] propertyList,
			final String filterQueryLanguage, final String filterQuery,
			final boolean continueOnError, final boolean isObjectPaths)
			throws WBEMException {
		final CloseableAddableIterator<CIMInstance> iter = new CloseableAddableIterator<CIMInstance>();
		Runnable enumerateThread = new Runnable() {
			@Override
			public void run() {
				try {
					assocEnumerate(iter, assocName, objectName, resultClass,
							role, resultRole, propertyList,
							filterQueryLanguage, filterQuery, continueOnError,
							isObjectPaths);
				} catch (WBEMException we) {
					// iterator should already have the exception set.
					// lets check that it is set, if it isn't then set it.
					if (iter.getWBEMException() == null) {
						// not set! lets put exception into iterator
						iter.setException(we);
						// close the iterator
						iter.close();
					}
				}

			}
		};
		// add thread to executor (can not be null)
		exec.execute(enumerateThread);
		return iter;
	}

	protected void assocEnumerate(CloseableAddableIterator<CIMInstance> iter,
			CIMObjectPath assocName, CIMObjectPath objectName,
			String resultClass, String role, String resultRole,
			String[] propertyList, String filterQueryLanguage,
			String filterQuery, boolean continueOnError, boolean isObjectPath)
			throws WBEMException {
		// create FQLParser object. This will verify the FilterQuery and
		// FilterQueryLanguage values. This will be used later to determine
		// if CIMInstance objects match the the query
		final FQLParser fqlParser = FQLParser.getFQLParser(filterQueryLanguage,
				filterQuery, objectName, WBEMOperation.OPENASSOCIATORS);
		getImplementation().assocEnumerate(iter, assocName, objectName,
				resultClass, role, resultRole, propertyList, fqlParser,
				continueOnError, WBEMOperation.OPENASSOCIATORS);
	}

	protected CloseableIterator<CIMInstance> threadedRefEnumerate(
			final CIMObjectPath assocName, final CIMObjectPath objectName,
			final String role, final String[] propertyList,
			final String filterQueryLanguage, final String filterQuery,
			final boolean continueOnError, final boolean isObjectPaths)
			throws WBEMException {
		final CloseableAddableIterator<CIMInstance> iter = new CloseableAddableIterator<CIMInstance>();
		Runnable enumerateThread = new Runnable() {
			@Override
			public void run() {
				try {
					refEnumerate(iter, assocName, objectName, role,
							propertyList, filterQueryLanguage, filterQuery,
							continueOnError, isObjectPaths);
				} catch (WBEMException we) {
					// iterator should already have the exception set.
					// lets check that it is set, if it isn't then set it.
					if (iter.getWBEMException() == null) {
						// not set! lets put exception into iterator
						iter.setException(we);
						// close the iterator
						iter.close();
					}
				}
			}
		};
        // add thread to executor (can not be null)
		exec.execute(enumerateThread);

		return iter;
	}

	protected void refEnumerate(CloseableAddableIterator<CIMInstance> iter,
			CIMObjectPath assocName, CIMObjectPath objectName, String role,
			String[] propertyList, String filterQueryLanguage,
			String filterQuery, boolean continueOnError, boolean isObjectPath)
			throws WBEMException {
		// create FQLParser object. This will verify the FilterQuery and
		// FilterQueryLanguage values. This will be used later to determine
		// if CIMInstance objects match the the query
		final FQLParser fqlParser = FQLParser.getFQLParser(filterQueryLanguage,
				filterQuery, objectName, WBEMOperation.OPENREFERENCES);
		getImplementation().refEnumerate(iter, assocName, objectName, role,
				propertyList, fqlParser, continueOnError,
				WBEMOperation.OPENREFERENCES);
	}

	@Override
	abstract protected BaseAssociatorImpl getImplementation()
			throws WBEMException;
}
