/*******************************************************************************
 * The information in this document is proprietary to VeriSign and the VeriSign
 * Registry Business. It may not be used, reproduced, or disclosed without the
 * written approval of the General Manager of VeriSign Information Services.
 * 
 * PRIVILEGED AND CONFIDENTIAL VERISIGN PROPRIETARY INFORMATION (REGISTRY
 * SENSITIVE INFORMATION)
 * Copyright (c) 2006 VeriSign, Inc. All rights reserved.
 * **********************************************************
 */

// jgould -- Dec 2, 2015

package com.verisign.epp.pool.parser;

import org.apache.commons.pool2.BaseObjectPool;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.SoftReferenceObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.verisign.epp.util.EPPEnv;
import com.verisign.epp.util.EPPStrictContactParser;

/**
 * Singleton parser pool class that initializes the parser pool at
 * initialization, and provides a {@link #getPool()} to get the initialized
 * pool. This pool contains instances of {@link EPPStrictContactParser}, which
 * overrides the contact XML schema to use the strict EPP Contact RFC 5733 XML
 * schema "contact-1.0.xsd".
 */
public class EPPStrictContactParserPool {

	/**
	 * Factory to use for {@link EPPStrictContactParserPool}.
	 */
	private static class EPPStrictContactParserPoolFactory extends BasePooledObjectFactory<EPPStrictContactParser> {

		/**
		 * Create instance of {@link EPPStrictContactParser}.
		 */
		@Override
		public EPPStrictContactParser create() throws Exception {
			return new EPPStrictContactParser();
		}

		/**
		 * Wrap a {@link EPPStrictContactParser} in a {@link DefaultPooledObject}.
		 */
		@Override
		public PooledObject<EPPStrictContactParser> wrap(EPPStrictContactParser aParser) {
			return new DefaultPooledObject<EPPStrictContactParser>(aParser);
		}
	}

	/**
	 * Category for logging
	 */
	    private static Logger cat = LoggerFactory.getLogger(EPPStrictContactParserPool.class);
	      

	/**
	 * Singleton instance
	 */
	private static EPPStrictContactParserPool instance = new EPPStrictContactParserPool();

	/**
	 * Contained parser pool
	 */
	private SoftReferenceObjectPool<EPPStrictContactParser> pool = null;

	/**
	 * Singleton {@code getInstance} method for accessing the
	 * {@code EPPStrictContactParserPool} instance.
	 * 
	 * @return {@code EPPStrictContactParserPool} Singleton instance.
	 */
	public static EPPStrictContactParserPool getInstance() {
		return instance;
	}

	/**
	 * Default constructor that will initialize the parser pool.
	 */
	private EPPStrictContactParserPool() {
		cat.info("EPPStrictContactParserPool: initializing pool");

		this.pool = new SoftReferenceObjectPool<EPPStrictContactParser>(new EPPStrictContactParserPoolFactory());

		try {
			this.pool.addObjects(EPPEnv.getSchemaCachingParserPoolSize());
		}
		catch (Exception ex) {
			cat.error("EPPStrictContactParserPool: Exception initializing the EPPStrictContactParserPool: " + ex);
		}

		cat.info("EPPStrictContactParserPool: pool initialized");
	}

	/**
	 * Gets the pool initialized by {@code EPPStrictContactParserPool} for
	 * getting and returning schema caching parsers.
	 * 
	 * @return Parser pool initialized by {@code EPPStrictContactParserPool}.
	 */
	public BaseObjectPool<EPPStrictContactParser> getPool() {
		return this.pool;
	}

}
