package com.harley.myJava;

import java.io.*;
import java.net.*;
import java.util.*;
import opencard.core.util.*;

/**
 *
 * <code>com.harley.myJava.OpenCardPropertyFileLoader</code> implements
 * the <code>opencard.core.util.OpenCardConfigurationProvider</code>
 * interface which is used by <code>opencard.core.service.SmartCard</code>
 * to load user-defined properties into the System Properties.  This class
 * simply retrieves the URL pointed to by the value of the System Property
 * that maps to <code>harleyConstants.PROPERTY_URL</code> and loads that
 * file into the System Properties.
 *
 * If a key already exists in the System Properties, it will note be loaded
 * unless a boolean property exists in the property file named key + ".override"
 * and has value set to true:
 *
 * e.g.:
 * #
 * #
 * a.property.that.already.exists=overriding value
 * a.property.that.already.exists.override=yes
 * #
 *
 *
 * To use this class, simply set the the appropriate system properties before
 * invoking the <code>opencard.core.service.SmartCard</code>.start() method:
 *
 *
 *   NOTE: in order for this property file loader to be used, you have to set these
 *         system properties before calling the start() method of SmartCard.
 *
 *	- Set "OpenCard.loaderClassName" to the fully qualified name of this class.
 *	- Set "com.harley.myJava.propertyfileurl" to fully qualified URL
 *	  pointing to opencard.properties.
 *
 *
 * e.g.:
 *
 *
 * 	import com.harley.myJava.*;
 *
 *	...
 *
 *	//
 *	// NOTE: This code is in a class that is packaged within the same jar file as the opencard.properties
 *	//       file and is within the same directory INSIDE the jar file.
 *	//
 *
 *     // Redirect the searching of the opencard.properties file to a URL
 *     System.getProperties().put(com.harley.myJava.harleyConstants.CLASSNAME_PROPERTY, 	
 *	"com.harley.myJava.OpenCardPropertyFileLoader");
 *     URL propsURL = this.getCodeBase();
 *     System.getProperties().put(com.harley.myJava.harleyConstants.PROPERTY_URL, propsURL.toString() + 
 *	"opencard.properties" );
 *     //SmartCard.start();
 *	...


 */
public class OpenCardPropertyFileLoader
		implements OpenCardConfigurationProvider, harleyConstants {

	private boolean loaded = false;

	public void loadProperties()
			throws OpenCardPropertyLoadingException {

		String urlString = System.getProperty(harleyConstants.PROPERTY_URL);

		try {
			if (!loaded) {
				URL urlSource = new URL(urlString);

				// Get reference to System properties...
				Properties sysProperties = SystemAccess.getSystemAccess().getProperties();

				// Load property file from URL...
				Properties properties = new Properties();
				properties.load(urlSource.openStream());

				// For each property name-value pair loaded from the URL,
				// load it into the System properties if it doesn't already
				// exist.  However, if the System property already exists,
				// check if there is a property in the URL stream with an
				// override flag; if there is, then replace the System
				// property with the one in the URL stream.
				Enumeration props = properties.propertyNames();
				while (props.hasMoreElements()) {
					Object key = props.nextElement();
					Object value = properties.get(key);

					String override = properties.getProperty(key.toString() + ".override");
					if (!sysProperties.containsKey(key) || Boolean.valueOf(override).booleanValue()) {
						sysProperties.put(key, value);
					}
				}

				// success! signify successful download...
				loaded = true;
			}
		} catch (MalformedURLException e) {
			throw new OpenCardPropertyLoadingException("Error in property file URL: " + urlString);
		} catch (IOException e) {
			throw new OpenCardPropertyLoadingException("IO Error while loading: " + urlString);
		}
	}
}