/* $Id: ElementCreationParser.java,v 1.1 2004/01/09 16:55:43 burkhard Exp $
 * Created on 12.05.2003 by sell
 *
 */
package de.skyrix.zsp.logic.parser;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;

import org.apache.xml.serialize.Method;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import de.skyrix.zsp.logic.DAVItem;

/**
 * 
 * @author sell
 * @version 
 */
public class ElementCreationParser extends DefaultParser {

	protected static class EH implements ErrorHandler {
		public void error(SAXParseException x) throws SAXException {
			throw x;
		}
		public void fatalError(SAXParseException x) throws SAXException {
			throw x;
		}

		public void warning(SAXParseException x) throws SAXException {
			throw x;
		}
	}

	private String saveDocumentToString(Document document)
		throws TransformerFactoryConfigurationError, TransformerException, IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		OutputFormat format = new OutputFormat(Method.XHTML, null, true);
		format.setStandalone(true);
		format.setIndent(2);

		XMLSerializer serial = new XMLSerializer(os, format);
		serial.setNamespaces(true);
		serial.serialize(document);

		return os.toString();
	}

	public String createPropfindResponse(DAVItem item, List attributeList) {
		if (item == null)
			return null;

		ArrayList list = new ArrayList();
		list.add(item);
		return createPropfindRespone(list, attributeList);
	}

	public String createPropfindRespone(Collection items, List attributeList) {
		if (items == null)
			throw new IllegalArgumentException("NULL is not a valid list of DAVItem.");

		try {

			DocumentBuilderFactory builder = DocumentBuilderFactory.newInstance();
			setBuilderFactoryPreferences(builder);

			Document doc = builder.newDocumentBuilder().newDocument();
			Node mstatusNode = doc.createElementNS("DAV:", "D:multistatus");
			doc.appendChild(mstatusNode);

			Iterator itemIterator = items.iterator();
			while (itemIterator.hasNext()) {
				try {
					DAVItem item = (DAVItem) itemIterator.next();

					Node responseNode = doc.createElementNS("DAV:", "D:response");
					mstatusNode.appendChild(responseNode);

					Node hrefNode = doc.createElementNS("DAV:", "D:href");
					String location = item.getLocation();

					hrefNode.appendChild(doc.createTextNode(location));

					responseNode.appendChild(hrefNode);

					Node propstatNode = doc.createElementNS("DAV:", "D:propstat");
					responseNode.appendChild(propstatNode);

					Node statusNode = doc.createElementNS("DAV:", "D:status");
					statusNode.appendChild(doc.createTextNode(item.getStatus()));
					propstatNode.appendChild(statusNode);

					Node propNode = doc.createElementNS("DAV:", "D:prop");
					propstatNode.appendChild(propNode);

					Enumeration attributeNameEnumeration = item.propertyNames();
					while (attributeNameEnumeration.hasMoreElements()) {
						try {
							String name = (String) attributeNameEnumeration.nextElement();

							//Check whether we need this item or not
							if (attributeList != null
								&& !attributeList.isEmpty()
								&& !attributeList.contains(name)) {
								continue;
							}

							String value = item.getValue(name);
							String ns = item.getNameSpaceURI(name);
							String prefix = item.getNameSpacePrefix(name);

							if (ns != null) {
								Node attNode =
									doc.createElementNS(
										ns,
										((prefix != null) ? prefix + ":" : "") + name);
								if (value != null)
									if ("resourcetype".equals(name))
										attNode.appendChild(
											doc.createElementNS(
												ns,
												((prefix != null) ? prefix + ":" : "") + value));
									else
										attNode.appendChild(doc.createTextNode(value));
								propNode.appendChild(attNode);
							}
						}
						catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
				catch (Exception e) {
				}
			}

			return saveDocumentToString(doc);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public String createProppatchQuery(DAVItem item) {
		if (item == null)
			throw new IllegalArgumentException("NULL is not a valid DAVItem.");

		try {
			DocumentBuilderFactory builder = DocumentBuilderFactory.newInstance();
			setBuilderFactoryPreferences(builder);

			Document doc = builder.newDocumentBuilder().newDocument();
			Node updateNode = doc.createElementNS("DAV:", "D:propertyupdate");
			doc.appendChild(updateNode);

			try {
				Enumeration attributeNameEnumeration = item.propertyNames();
				while (attributeNameEnumeration.hasMoreElements()) {
					try {
						String name = (String) attributeNameEnumeration.nextElement();

						String value = item.getValue(name);
						String ns = item.getNameSpaceURI(name);
						String prefix = item.getNameSpacePrefix(name);

						if (ns != null) {
							Node attNode =
								doc.createElementNS(
									ns,
									((prefix != null) ? prefix + ":" : "") + name);
							if (value != null)
								if ("resourcetype".equals(name))
									attNode.appendChild(
										doc.createElementNS(
											ns,
											((prefix != null) ? prefix + ":" : "") + value));
								else
									attNode.appendChild(doc.createTextNode(value));

							Node setNode = doc.createElementNS("DAV:", "D:set");
							updateNode.appendChild(setNode);

							Node propNode = doc.createElementNS("DAV:", "D:prop");
							setNode.appendChild(propNode);

							propNode.appendChild(attNode);
						}
					}
					catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			catch (Exception e) {
			}

			return saveDocumentToString(doc);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static void main(String[] args) {
		ArrayList davItems = new ArrayList();
		//		for (int i = 0; i < 3; i++) {
    int i = 1;

		DAVItem item = new DAVItem();
		item.setLocation("http://localhost:23000/evo/so/sell/");
		item.setStatus("HTTP/1.1 200 OK");
		item.setProperty(
			"x" + i,
			"pt:http://schemas.microsoft.com/mapi/proptag/" + "##" + i);
		item.setProperty(
			"x36140015",
			"a:http://schemas.microsoft.com/mapi/proptag/" + "##");
		item.setProperty(
			"x36140016",
			"pt:http://schemas.microsoft.com/mapi/proptag/" + "##" + i + 1);
		//davItems.add(item);
		//}

		ElementCreationParser parser = new ElementCreationParser();
		//ArrayList attList = new ArrayList();
		//attList.add("x2");
		//attList.add("x36140015");
		//System.out.println(parser.createPropfindRespone(davItems, attList));
    System.out.println(parser.createProppatchQuery(item));
	}
}
