package jp.mydns.masahase.operateXML;

import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import jp.mydns.masahase.InherentStrain.*;
import jp.mydns.masahase.util.Cache;
import jp.mydns.masahase.util.CacheSource;
import jp.mydns.masahase.AbaqusResult.ObjectFactory;

/**
 * {@link jp.mydns.masahase.InherentStrain}で定義・作成されるXML操作
 * 
 * @author MASA.H
 * 
 */
public class InherentStrain {
	InputStream input;
	OutputStream output;
	ObjectFactory objfct;
	JAXBContext jaxbcont;
	private int cache_size = 100;
	InherentStrainType rootnode;
	Cache<Integer, ElementType> et_cache;
	Cache<Integer, NodeType> nd_cache;

	/**
	 * デフォルトコンストラクタ
	 * 
	 * @throws JAXBException
	 */
	public InherentStrain() throws JAXBException {
		objfct = new ObjectFactory();
		jaxbcont = JAXBContext.newInstance("jp.mydns.masahase.InherentStrain");
		input = null;
		output = null;
		rootnode = null;
		et_cache = new Cache<Integer, ElementType>(cache_size);
		nd_cache = new Cache<Integer, NodeType>(cache_size);

	}

	/**
	 * XMLを読む
	 * 
	 * @return 成功したか否か
	 */
	@SuppressWarnings("unchecked")
	public boolean readXML() {
		boolean ret;
		if (input != null) {
			try {
				Unmarshaller um = jaxbcont.createUnmarshaller();
				rootnode = (InherentStrainType) um
						.unmarshal(input);
				ret = true;
				et_cache = new Cache<Integer, ElementType>(cache_size,
						new CacheSource<Integer, ElementType>() {
							public ElementType get(Integer id) {
								ElementType ret = null;
								for (ElementType et : rootnode.getElements()
										.getElement()) {
									if (et.getId().equals(id)) {
										ret = et;
										break;
									}
								}
								return ret;
							}
						});
				nd_cache = new Cache<Integer, NodeType>(cache_size,
						new CacheSource<Integer, NodeType>() {
							public NodeType get(Integer id) {
								NodeType ret = null;
								for (NodeType nd : rootnode.getNodes()
										.getNode()) {
									if (nd.getId() == id.intValue()) {
										ret = nd;
										break;
									}
								}
								return ret;
							}
						});
			} catch (JAXBException e) {
				ret = false;
			}
		} else {
			ret = false;
		}
		return ret;
	}

	/**
	 * XMLを書き出す
	 * 
	 * @return 成功したか否か
	 */
	public boolean writeXML() {
		boolean ret;
		if (output != null) {
			try {
				Marshaller ms = jaxbcont.createMarshaller();
				ms.marshal(rootnode, output);
				ret = true;
			} catch (JAXBException e) {
				ret = false;
			}
		} else {
			ret = false;
		}
		return ret;
	}

	/**
	 * 入力を設定
	 * 
	 * @param is
	 *            入力用のストリーム
	 */
	public void setInput(InputStream is) {
		input = is;
	}

	/**
	 * 出力を設定
	 * 
	 * @param os
	 *            出力用のストリーム
	 */
	public void setOutput(OutputStream os) {
		output = os;
	}

	public NodeType getNode(int id) {
		return nd_cache.get(Integer.valueOf(id));
	}

	public ElementType getElement(int id) {
		return et_cache.get(Integer.valueOf(id));
	}

	public NodesType getNodes(){
		return rootnode.getNodes();
	}
	public ElementsType getElements(){
		return rootnode.getElements();
	}
}

