package charactermanaj.util;

import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.AbstractList;
import java.util.Arrays;


/**
 * リソースをロードするためのクラス.
 * @author seraphy
 */
public abstract class ResourceLoader {

	/**
	 * プロパティファイル群をまとめて管理
	 * @author seraphy
	 */
	protected static final class ResourceNames extends AbstractList<String> {
		
		private final String[] resourceNames;
		
		ResourceNames(String[] resourceNames) {
			if (resourceNames == null) {
				throw new IllegalArgumentException();
			}
			this.resourceNames = resourceNames;
		}
		
		@Override
		public int hashCode() {
			return Arrays.hashCode(resourceNames);
		}
		
		@Override
		public boolean equals(Object obj) {
			if (obj == this) {
				return true;
			}
			if (obj != null && obj instanceof ResourceNames) {
				ResourceNames o = (ResourceNames) obj;
				return Arrays.equals(resourceNames, o.resourceNames);
			}
			return false;
		}
		
		@Override
		public int size() {
			return resourceNames.length;
		}
		
		@Override
		public String get(int index) {
			return resourceNames[index];
		}
	}

	/**
	 * クラスローダを取得する.<br>
	 * スレッドに関連づけられているコンテキストクラスローダか、もしなければ、このクラスをロードしたクラスローダを返す.<br>
	 * @return クラスローダ
	 */
	protected ClassLoader getClassLoader() {
		return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
			public ClassLoader run() {
				ClassLoader cl = Thread.currentThread().getContextClassLoader();
				if (cl == null) {
					cl = ResourceLoader.class.getClassLoader();
				}
				return cl;
			}
		});
	}

	/**
	 * クラスローダによりリソースをロードする.<br>
	 * 該当するリソースが存在しない場合はnullを返す.<br>
	 * リソース名がnullの場合もnullを返す.<br>
	 * @param name リソース名またはnull
	 * @return リソースがあれば、そのURL。なければnull
	 */
	protected URL getResource(String name) {
		if (name == null) {
			return null;
		}
		return getClassLoader().getResource(name);
	}
}
