//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.NetUtil;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.common.xml.XSLTProcessor;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.DefaultContentValidator;
import org.eclipse.epf.library.layout.IContentValidator;
import org.eclipse.epf.library.layout.LayoutResources;
import org.eclipse.epf.library.layout.LinkInfo;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.layout.util.XmlHelper;
import org.eclipse.epf.library.services.LibraryProcessor;
import org.eclipse.epf.persistence.MethodLibraryPersister;

import com.ibm.uma.MethodConfiguration;
import com.ibm.uma.MethodElement;
import com.ibm.uma.MethodPlugin;
import com.ibm.uma.util.UmaUtil;

/**
 * @author Jinhua Xi
 * @since 1.0
 */
public class ResourceHelper {
	
	//public static final String BRACE_REPLACEMENT = "_BR_";	 //$NON-NLS-1$
	//public static final String OPENBRACE_STRING = "\\{";	 //$NON-NLS-1$

	public static final String URL_BOOKMARK_INDICATOR = "#"; //$NON-NLS-1$

	public static final String URL_PARAMETER_INDICATOR = "?"; //$NON-NLS-1$

	public static final String URL_PARAMETER_PROCESS = "proc"; //$NON-NLS-1$

	public static final String URL_STR_JAVASCRIPT = "javascript:"; //$NON-NLS-1$
	public static final String URL_STR_MAILTO = "mailto:"; //$NON-NLS-1$
	
	public static final String URL_PARAMETER_PATH = "path"; //$NON-NLS-1$

	public static final String TAG_ATTR_NAME = "name"; //$NON-NLS-1$

	public static final String TAG_ATTR_KEY = "key"; //$NON-NLS-1$

	public static final String TAG_ATTR_TEXT = "text"; //$NON-NLS-1$

	public static final String TAG_ATTR_CLASS = "class"; //$NON-NLS-1$

	public static final String TAG_ATTR_GUID = "guid"; //$NON-NLS-1$

	public static final String TAG_ATTR_HREF = "href"; //$NON-NLS-1$

	public static final String TAG_ATTR_VALUE_INDEX = "index"; //$NON-NLS-1$

	public static final String FILE_EXT_HTML = ".html"; //$NON-NLS-1$

	public static final String FILE_EXT_HTM = ".htm"; //$NON-NLS-1$

	public static final String FILE_EXT_JPEG = ".jpeg"; //$NON-NLS-1$

	public static final String MISSING_PAGES_FOLDER = "pages_not_installed/"; //$NON-NLS-1$

	public static final String ELEMENT_LINK_CLASS_elementLink = "elementLink"; //$NON-NLS-1$

	public static final String ELEMENT_LINK_CLASS_elementLinkWithType = "elementLinkWithType"; //$NON-NLS-1$

	public static final String ELEMENT_LINK_CLASS_elementLinkWithUserText = "elementLinkWithUserText"; //$NON-NLS-1$

	public static final String RESOURCE_FOLDER = MethodLibraryPersister.RESOURCE_FOLDER;

	public static final Pattern p_html_file_name = Pattern
			.compile("(.*),(.*)\\.html"); //$NON-NLS-1$

	// this one does not work when containing non-english characters, use the
	// more general one
	// public static final Pattern p_link_ref =
	// Pattern.compile("<a\\s+?([^>]*)>(.*?)</a>", Pattern.CASE_INSENSITIVE |
	// Pattern.DOTALL); //$NON-NLS-1$
	public static final Pattern p_link_ref = Pattern
			.compile(
					"<a\\s+?(.*?)>(.*?)</a>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_area_ref = Pattern
			.compile(
					"<area.*?href\\s*=\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_link_ref_gen = Pattern
			.compile(
					"<(a|area)\\s+?([^>]*)>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_link_type_picker = Pattern
			.compile(
					" class\\s*?=\\s*?(.*?)\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_link_guid_picker = Pattern
			.compile(
					" guid\\s*?=\\s*?(.*?)\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_link_href_picker = Pattern
			.compile(
					" href\\s*?=\\s*?\"(.*?)\"\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_tag_ref = Pattern
			.compile(
					"<([^>]*)(\\n|\\r)([^>]*)>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_image_ref = Pattern
			.compile(
					"(<(img|iframe).*?src\\s*=\\s*\")(.*?)(\")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_url_decoder = Pattern
			.compile(
					"(<[^>]*?(src|href)\\s*=\\s*\")(.*?)(\"[^>]*?>)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static final Pattern p_tag_attributes = Pattern
			.compile(
					"(.*?)\\s*=\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
	
	public static final Pattern p_css_ref = Pattern
		.compile(
				" url\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	// define constants for diagram type.
	// This will be used when linking diagrams into published contents
	//	 Activity diagram
	public static final String DIAGRAM_TYPE_WORKFLOW = "Activity";  //$NON-NLS-1$

	// activity detail diagram
	public static final String DIAGRAM_TYPE_ACTIVITY_DETAIL = "ActivityDetail";  //$NON-NLS-1$

	// WPDependency diagram
	public static final String DIAGRAM_TYPE_WP_DEPENDENCY = "WPDependency";  //$NON-NLS-1$

	public ResourceHelper() {
	}

	/**
	 * the relative path of the resource folder of the plugin in the library,
	 * relative to the library root
	 * 
	 * @param element
	 * @return String
	 */
	public static String getPluginResourcePath(MethodElement element) {
		MethodPlugin plugin = UmaUtil.getMethodPlugin(element);

		String path;
		if (plugin == null) {
			path = MethodLibraryPersister.getResourcePath(element);
		} else {
			path = MethodLibraryPersister.getResourcePath(plugin);
		}

		return fixPath(path);
	}

	/**
	 * get the relative path of the resource folder of the element in the
	 * library, relative to the library root
	 * 
	 * @param element
	 * @return
	 */
	public static String getElementResourcePath(MethodElement element) {
		String path = MethodLibraryPersister.getResourcePath(element);
		return fixPath(path);
	}

	/**
	 * get the relative path of the folder of the element in the library,
	 * relative to the library root
	 * 
	 * @param element
	 * @return
	 */
	public static String getElementPath(MethodElement element) {
		try {
			String path = MethodLibraryPersister.getElementPath(element);
			if (path == null || path.equals("")) //$NON-NLS-1$
			{
				System.out
						.println("Warning! No Path for Element [" + element.getType().getName() + ": " + element.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				return ""; //$NON-NLS-1$
			}
			return fixPath(path);
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return ""; //$NON-NLS-1$
	}

	public static String fixPath(String path) {
		if (path == null || path.equals("")) //$NON-NLS-1$
		{
			return ""; //$NON-NLS-1$
		} else if (!path.endsWith(File.separator)) {
			return path + File.separator;
		} else {
			return path;
		}
	}

	/**
	 * get the path to the library root. For example,
	 * "RUP\guidance\concept\c1.xml", the back path is "./../../../"
	 * 
	 * @param path
	 * @return
	 */
	public static String getBackPath(MethodElement element) {
		// RATLC00384963 - Linux: Browsing and preview shows only plain text.
		// There are no images/sections
		// element path should check File.separatorChar instead of "\"
		String backPath = ""; //$NON-NLS-1$
		String path = getElementPath(element);
		if (path != null && path.length() > 0) {
			backPath = path.replace(File.separatorChar, '/').replaceAll(
					".*?/", "\\.\\./"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return "./" + backPath; //$NON-NLS-1$
	}

	/**
	 * get the file name with the given extension
	 */
	public static String getFileName(MethodElement element, String ext) {
		return getFileName(element, null, null, ext);
	}

	/**
	 * get the file name with the given extension
	 */
	public static String getFileName(MethodElement element, String namePrefix,
			String nameSuffix, String ext) {
		StringBuffer buffer = new StringBuffer();
		if (namePrefix != null) {
			buffer.append(namePrefix);
		}

		// RATLC00386297 - Browsing: Browsing CP with special chars failed with blank pages and Script Error
		// need to make a valid file name
		buffer.append(StrUtil.makeValidFileName(element.getName()));
		if (nameSuffix != null) {
			buffer.append(nameSuffix);
		}
//		if (element.getGuid().startsWith("{"))
//		{
//			String newGuid = element.getGuid().replaceFirst( OPENBRACE_STRING, BRACE_REPLACEMENT );
//			buffer.append(",").append(newGuid.substring(0, newGuid.length()-1)); //$NON-NLS-1$
//		}
//		else
			buffer.append("," + element.getGuid()); //$NON-NLS-1$
		
		if (ext != null) {
			if (ext.indexOf(".") < 0) //$NON-NLS-1$
			{
				ext = "." + ext; //$NON-NLS-1$
			}
			buffer.append(ext);
		}

		return buffer.toString();
	}

	public static String getGuidFromFileName(String fileName) {
		if (fileName == null) {
			return null;
		}

		String guid = null;
		Matcher m = p_html_file_name.matcher(fileName);
		if (m.find()) {
			guid = m.group(2);
		}
		
//		if (null != guid && guid.startsWith(BRACE_REPLACEMENT))
//		{
//			StringBuffer guidBuffer = new StringBuffer(guid.replaceFirst( BRACE_REPLACEMENT, OPENBRACE_STRING ));			
//			guidBuffer.append("}");
//			return guidBuffer.toString();
//		}
//		else
			return guid;
	}

	public static MethodElement getElementFromFileName(String fileName) {
		String guid = getGuidFromFileName(fileName);
		if (guid != null) {
			return LibraryProcessor.getInstance().getElement(guid);
		}

		return null;
	}

	/**
	 * get the element url relative to the refElement
	 * 
	 * @param element
	 * @param refElement
	 * @param fileExt
	 * @param old_url
	 *            the old url
	 * @return
	 */
	public static String getUrl(MethodElement element,
			MethodElement refElement, String fileExt, String old_url) {
		String url = getUrl(element, refElement, fileExt);

		// if the old url has bookmark in it, keep it
		if (old_url != null) {
			int indx = old_url.indexOf(URL_BOOKMARK_INDICATOR);
			if (indx < 0) {
				// keep url query string as well
				indx = old_url.indexOf(URL_PARAMETER_INDICATOR);
			}

			if (indx >= 0) {
				url = url + old_url.substring(indx);
			}
		}

		return url;
	}

	/**
	 * get the element url relative to the refElement
	 * 
	 * @param element
	 * @param refElement
	 * @param fileExt
	 * @return
	 */
	public static String getUrl(MethodElement element,
			MethodElement refElement, String fileExt) {
		if (element == null) {
			return ""; //$NON-NLS-1$
		}

		if (refElement == null) {
			return getElementPath(element).replace(File.separatorChar, '/')
					+ getFileName(element, fileExt);
		} else {
			return (getBackPath(refElement) + getElementPath(element)).replace(
					File.separatorChar, '/')
					+ getFileName(element, fileExt);
		}
	}

	public static String getLinkText(MethodElement e, String linkType) {
		String linkedText = null;
		if ((linkType != null)
				&& !ELEMENT_LINK_CLASS_elementLinkWithUserText.equals(linkType)) {
			if (ELEMENT_LINK_CLASS_elementLinkWithType.equals(linkType)) {
				linkedText = getElementLinkText(e, true);
			} else if (ELEMENT_LINK_CLASS_elementLink.equals(linkType)) {
				linkedText = getElementLinkText(e, false);
			}
		}

		return linkedText;
	}

	public static String getElementLinkText(MethodElement element,
			boolean withType) {
		String text = TngUtil.getPresentationName(element);

		if (withType) {
			return getElementTypeText(element) + ": " + text; //$NON-NLS-1$
		}

		return text;
	}

	public static String getElementTypeText(MethodElement element) {
		if ( element == null )
		{
			return "";
		}
		
		return TngUtil.getTypeText(element);
	}

	/**
	 * auto generated element link <a class="elementLink" href="element_url"
	 * guid="element_guid">element_type: element_presentation_name</a>
	 * 
	 * @param element
	 *            MethodElement
	 * @param withType
	 *            boolean
	 * @param url
	 *            String
	 */
	public static String getElementLink(MethodElement element,
			boolean withType, String url) {
		String text = getElementLinkText(element, withType);
		String linkClass = ELEMENT_LINK_CLASS_elementLink;
		if (withType)
			linkClass = ELEMENT_LINK_CLASS_elementLinkWithType;
		return getElementLink(element, text, url, linkClass);
	}

	/**
	 * element link with user specified link text
	 * 
	 * @param element
	 * @param text
	 * @param url
	 * @return
	 */
	public static String getElementLink(MethodElement element, String text,
			String url) {
		return getElementLink(element, text, url,
				ELEMENT_LINK_CLASS_elementLinkWithUserText);
	}

	/**
	 * element link with user specified link text
	 * 
	 * @param element
	 * @param text
	 * @param url
	 * @return
	 */
	public static String getElementLink(MethodElement element, String text,
			String url, String linkClass) {
		return "<a class=\"" + linkClass + "\" " + getUrlText(url) + " guid=\"" + element.getGuid() + "\" >" + text + "</a>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	}

	/**
	 * the passed in url might contain the href attribute with it, or even other
	 * attributes, so check if this is a pure url or not. return the url href
	 * term string
	 * 
	 * @param url
	 * @return
	 */
	private static String getUrlText(String url) {
		if (url == null) {
			url = ""; //$NON-NLS-1$
		} else {
			url = url.trim();
		}

		// starts with href, or contains an href term in it
		if (url.toLowerCase().startsWith("href") || url.toLowerCase().indexOf(" href") > 0) //$NON-NLS-1$ //$NON-NLS-2$
		{
			return url;
		}

		return "href=\"" + url + "\""; //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * validate the content by checking element links and images
	 * 
	 * @param content
	 * @return
	 */
	public static String validateContent(MethodElement element, String source) {
		return validateContent(element, source, new DefaultContentValidator(),
				null);
	}

	public static boolean isElementLink(String linkType) {
		if (linkType == null || linkType.length() == 0) {
			return false;
		}

		return linkType.equals(ELEMENT_LINK_CLASS_elementLink)
				|| linkType.equals(ELEMENT_LINK_CLASS_elementLinkWithType)
				|| linkType.equals(ELEMENT_LINK_CLASS_elementLinkWithUserText);
	}

	/**
	 * validate the content by checking element links and images, for the
	 * specified element owner
	 * 
	 * @param element
	 *            MethodElement, the element that owns the content
	 * @param content
	 * @param config
	 *            MethodConfiguration the configuration to which the content is
	 *            validated
	 * @param linkedElements
	 *            List a passed in list to collect the linked elements in this
	 *            content, if null, no linked elements are collected.
	 * @return String the validated content
	 */
	public static String validateContent(MethodElement element, String source,
			IContentValidator validator, MethodConfiguration config) {
		try {
			// first validate the tags, remove any CF/LF from the tag text
			source = validateTag(source);
			
			StringBuffer sb = new StringBuffer();
			Matcher m = p_link_ref.matcher(source);

			while (m.find()) {
				String text = m.group();

				// RATLC00381344: Problems parsing <a href> tags
				// need to remove all LF, CR within the <a ..> tag
				String urltext = m.group(1);
				String linkedText = m.group(2);
				LinkInfo info = validator.validateLink(element, urltext,
						linkedText, config);
				if (info != null) {
					text = info.getHtml().toString();
					MethodElement e = info.getLinkedElement();
					if (e != null) {
						validator.addReferencedElement(element, e);
					}
				}

				String replacement = text.replaceAll("file:///", ""); //$NON-NLS-1$ //$NON-NLS-2$
				replacement = replacement.replaceAll("file://", ""); //$NON-NLS-1$ //$NON-NLS-2$
				m.appendReplacement(sb, replacement);
			}

			m.appendTail(sb);

			if (element == null) {
				return sb.toString();
			}
			
			// also fix the area map
			source = sb.toString();
			m = p_area_ref.matcher(source);
			sb.setLength(0);

			while (m.find()) {
				// String text = m.group();
				String href = m.group(1);
				String guid = getGuidFromFileName(href);
				if (guid != null) {
					MethodElement e = LibraryProcessor.getInstance()
							.getElement(guid);
					if (e != null) {
						// should realize the element, and get the realized one
						MethodElement e1 = ConfigurationHelper.getCalculatedElement(e, config);
						if (e1 != null) {
							e = e1;
						}

						validator.addReferencedElement(element, e);
						
						if (ConfigurationHelper.inConfig(e, config) && !validator.isDiscarded(element, null, e))
						{
							href = getUrl(e, element, FILE_EXT_HTML, href);							
						}
						else
						{
							href = getDiscardedElementURL(element, e, guid, ((DefaultContentValidator)validator).getPublishDir());							
						}
					}
				} 
				else 
				{
					href = URLDecoder.decode(href, "UTF-8"); //$NON-NLS-1$
				}

				String replacement = source.substring(m.start(), m.start(1))
						+ href + source.substring(m.end(1), m.end());
				m.appendReplacement(sb, replacement);
			}

			m.appendTail(sb);

			// // RATLC00384332 - GVT: Shape icon broken in preview and browsing
			// // need to decode the image path unless we can disable the url
			// encoding in xslt
			// source = sb.toString();
			// sb.setLength(0);
			// m = ResourceHelper.p_image_ref.matcher(source);
			// while ( m.find() )
			// {
			// String url = m.group(3);
			// url = URLDecoder.decode(url, "UTF-8");
			// m.appendReplacement(sb, m.group(1) + url + m.group(4));
			// }
			// m.appendTail(sb);
			// return sb.toString();

			// decode the urls
			return decodeUrlsInContent(sb.toString());

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return source;
	}

	/**
	 * decode the urls in the content. Content from xslt output are encoded. We
	 * don't want this to be encoded since the browser may decode it in a wrong
	 * encoding.
	 * 
	 * @param content
	 * @return String
	 */
	public static String decodeUrlsInContent(String content) {
		try {
			// RATLC00384332 - GVT: Shape icon broken in preview and browsing
			// need to decode the image path unless we can disable the url
			// encoding in xslt
			StringBuffer sb = new StringBuffer();
			Matcher m = ResourceHelper.p_url_decoder.matcher(content);
			while (m.find()) {
				String url = m.group(3);
				url = URLDecoder.decode(url, "UTF-8"); //$NON-NLS-1$
				m.appendReplacement(sb, m.group(1) + url + m.group(4));
			}
			m.appendTail(sb);

			return sb.toString();

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return content;
	}

	/**
	 * fix the element url in the urltext. the text is the part from the
	 * p_link_ref pattern match
	 * 
	 * @param urltext
	 * @param config
	 *            MethodConfiguration the configuration to which the content is
	 *            validated
	 * @return String the fixed text
	 */
	public static String fixElementUrl(MethodElement element, String urltext,
			MethodConfiguration config) {
		Matcher m = p_link_href_picker.matcher(" " + urltext + " "); //$NON-NLS-1$ //$NON-NLS-2$
		StringBuffer sb = new StringBuffer();
		if (m.find()) {
			String url = m.group(1);
			String newurl = null;
			if (element != null) {
				String guid = getGuidFromUrl(urltext);
				if (guid != null) {
					MethodElement e = LibraryProcessor.getInstance()
							.getElement(guid);
					if (e != null) {
						if (config != null) {
							e = ConfigurationHelper.getCalculatedElement(e,
									config);
						}
						newurl = getUrl(e, element, FILE_EXT_HTML, url);
					}

					// if the element is null, we should remove the url link and
					// log an error
					// TODO
				}
			}

			if (newurl != null && !newurl.equals(url)) {
				String replacement = " href=\"" + newurl + "\" "; //$NON-NLS-1$ //$NON-NLS-2$
				m.appendReplacement(sb, replacement);
				m.appendTail(sb);
				return sb.toString();

			}
		}

		return urltext;
	}

	public static String getElementLinkType(String source) {
		Matcher m = p_link_type_picker.matcher(" " + source + " "); //$NON-NLS-1$ //$NON-NLS-2$
		if (m.find()) {
			return m.group(1).trim().replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
		}

		return null;
	}

	public static String getGuidFromUrl(String source) {
		Matcher m = p_link_guid_picker.matcher(" " + source + " "); //$NON-NLS-1$ //$NON-NLS-2$
		if (m.find()) {
			return m.group(1).trim().replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
		}

		m = p_link_href_picker.matcher(" " + source + " "); //$NON-NLS-1$ //$NON-NLS-2$
		if (m.find()) {
			String href = m.group(1).trim().replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
			return getGuidFromFileName(href);
		}

		return null;
	}

	/**
	 * handle a bug in IE. anchor tag can't have CR LF, like <A \r\n
	 * href="www.yahoo.com" \r\n> scan the string source, find all anchor tags
	 * and replace with space.
	 * 
	 * @param source
	 * @return String the fixed source
	 */
	public static String validateTag(String source) {
		// Pattern p_anchor_ref = Pattern.compile("(*+?)=(*.?)",
		// Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

		StringBuffer sb = new StringBuffer();
		Matcher m = p_tag_ref.matcher(source);
		// StringBuffer tempSb = new StringBuffer();

		while (m.find()) {
			String text = m.group();
			String replacement = fixTagAttribute(text);
			m.appendReplacement(sb, replacement);
		}

		m.appendTail(sb);

		return sb.toString();
	}

	public static String fixTagAttribute(String source) {
		// simply replace all CR LF with ' ', fine tune later
		return source
				.replaceAll("\\\r\\\n", " ").replaceAll("\\\r", " ").replaceAll("\\\n", " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
	}

	/**
	 * get the resource file url relative to the library root
	 * 
	 * @param e
	 *            MethodElement the element that references this resource
	 * @param file
	 *            File the resource's physical path
	 * @return String the url to this resource from the element
	 */
	public static String getResourceFileUrl(MethodElement e, File file) {
		String fileUrl = getFileUrl(file);
		// String elementPath =
		// ResourceHelper.getElementResourcePath(e).replace(File.separatorChar,
		// '/');

		fileUrl = ResourceHelper.getBackPath(e) + fileUrl;

		return fileUrl;

	}

	/**
	 * return the file's relative path to the plugin root
	 * 
	 * @param f
	 * @return
	 */
	public static String getFileUrl(File f) {
		String path = getFileRelPath(f);
		path = path.replace(File.separatorChar, '/');
		return path;
	}

	/**
	 * get the URI relative to the specified base
	 * 
	 * @param uri
	 * @return java.net.URI
	 */
	public static URI getRelativeURI(URI uri, String rootPath) {
		return getRelativeURI(uri, new File(rootPath).toURI());
	}

	/**
	 * get the URI relative to the specified base
	 * 
	 * @param uri
	 * @return java.net.URI
	 */
	public static URI getRelativeURI(URI uri, URI relativeTo) {
		URI relUri = relativeTo.relativize(uri);
		return relUri;
	}

	/**
	 * resolve the relative path to the library root
	 * 
	 * @param f
	 * @return String the raltive path
	 */
	public static String getFileRelPath(File f) {
		File libraryRootPath = LibraryProcessor.getInstance()
				.getLibraryRootPath();
		String root = libraryRootPath.getAbsolutePath();
		String path = f.getAbsolutePath();
		if (path.startsWith(root)) {
			path = path.substring(root.length());
		}

		if (path.startsWith(File.separator)) {
			path = path.substring(1);
		}

		return path;
	}

	/**
	 * get the URI relative to the library root
	 * 
	 * @param f
	 * @return
	 */
	public static java.net.URI getFileRelativeURI(File f) {
		File libraryRootPath = LibraryProcessor.getInstance()
				.getLibraryRootPath();
		java.net.URI libURI = libraryRootPath.toURI();
		java.net.URI fileURI = f.toURI();
		java.net.URI relUri = libURI.relativize(fileURI);

		return relUri;
	}

	/**
	 * copy the file to the specified destination
	 * 
	 * @param source
	 * @param dest
	 * @return
	 */
	public static boolean copyFile(File source, File dest) {
		if ((source == null) || !source.exists()) {
			return false;
		}

		boolean needCopy = true;
		if (dest.exists()) {
			needCopy = (dest.lastModified() != source.lastModified()) || (dest.length() != source.length());
		}

		if (needCopy) {
			File parent = dest.getParentFile();
			if (!parent.exists()) {
				parent.mkdirs();
			}

			try {
				if (!dest.exists()) {
					dest.createNewFile();
				}

				FileUtil.copyFile(source, dest);
			} catch (Exception ex) {
				ex.printStackTrace();

				return false;
			}
		}

		return true;
	}

	/**
	 * Returns file URL for an attachment
	 * 
	 * @param attachment
	 *            the file to attach
	 * @param element
	 *            the MethodElement referencing the file
	 * @param copyFile
	 *            if true, will copy the file (if it isn't already in the plugin
	 *            path)
	 * @return URL of the form ./../&lt;roles&gt;/resources/&lt;filename of
	 *         attachment&gt;
	 * @throws IOException
	 */
	public static String getURLForAttachment(File attachment,
			MethodElement element, boolean copyFile) throws IOException {
		String libDir = LibraryProcessor.getInstance().getLibraryRootPath()
				.getAbsolutePath();
		String pluginDir = new File(UmaUtil.getMethodPlugin(element)
				.eResource().getURI().toFileString()).getParent();
		File formatFile = null;
		if (attachment.getAbsolutePath().startsWith(pluginDir)) {
			formatFile = attachment;
		} else {
			String resourceLoc = libDir + File.separator
					+ MethodLibraryPersister.getResourcePath(element);
			// File resourceDir = new File(resourceLoc);
			formatFile = new File(resourceLoc + File.separator
					+ attachment.getName());
			if (copyFile)
				FileUtil.copyfile(attachment, formatFile);
		}

		return ResourceHelper.getRelativePathToFileFromElement(element,
				formatFile);

	}

	public static String getRelativePathToFileFromElement(
			MethodElement element, File attachment) {
		String libDir = LibraryProcessor.getInstance().getLibraryRootPath()
				.getAbsolutePath();
		// String pluginDir = new
		// File(UmaUtil.getMethodPlugin(element).eResource().getURI().toFileString()).getParent();
		String elementLoc = libDir + File.separator + getElementPath(element);
		return FileUtil.getRelativePath(attachment, new File(elementLoc));
	}

	/**
	 * get the file path name of the type of diagram for the specified element
	 * 
	 * @param e
	 * @param diagramType
	 *            String diagram type defined in one of the diagram type
	 *            constants
	 * @return String the file path relative to the library root
	 */
	public static String getDiagramFilePathName(MethodElement e,
			String diagramType) {
		// RATLC00384528 (Submit): Instances of the same activity/CP share the
		// same diagram in a Delivery Process
		// need to make the name unique
		return getElementResourcePath(e) + StrUtil.makeValidFileName(e.getName())
				+ "_" + e.getGuid() + "_" + diagramType + FILE_EXT_JPEG; //$NON-NLS-1$ //$NON-NLS-2$
	}

	public static final String FILE_PREFIX_2 = "file://"; //$NON-NLS-1$

	public static final String FILE_PREFIX_3 = "file:///"; //$NON-NLS-1$

	/**
	 * get the relative path of the file based on the url
	 * 
	 * @param url
	 *            String the url
	 * @param contentPath
	 *            String the path of the content that contains this url
	 * @return String the file path relative to the content publishing root
	 */
	public static String getFilePathFromUrl(String url, String contentPath) {
		// System.out.println("Processing image url [" + url + "]");
		if (isExternalLink(url)
				|| url.startsWith("mailto:") || url.startsWith(URL_BOOKMARK_INDICATOR)) //$NON-NLS-1$ 
		{
			return null;
		}

		int index = url.indexOf(FILE_PREFIX_3);
		if (index == 0) {
			url = url.substring(FILE_PREFIX_3.length());
		}

		index = url.indexOf(FILE_PREFIX_2);
		if (index == 0) {
			url = url.substring(FILE_PREFIX_2.length());
		}

		File f = new File(contentPath);
		int start = 0;
		index = 0;
		while ((f != null) && (index = url.indexOf("../", start)) >= 0) //$NON-NLS-1$
		{
			f = f.getParentFile();
			start = index + 3;
		}

		String rootFolder = ""; //$NON-NLS-1$
		if (f != null) {
			rootFolder = f.getPath();
		}

		if (rootFolder.length() > 0 && !rootFolder.endsWith(File.separator)) {
			rootFolder += File.separator;
		}

		// the file path is
		String path = rootFolder
				+ url.substring(start).replace('/', File.separatorChar);

		return XMLUtil.unescape(NetUtil.decodedFileUrl(path));
	}

	/**
	 * for the given content with url based on the oldContentPath, resolve to
	 * the path relative to the root of the contentPath. If backpath is
	 * specified, add the backPath. return the updated content. A typical
	 * scenario is the content is from a contributing element, which has urls
	 * relative to the contributing element's contentPath. This method will fix
	 * the url to based on the base element's contentPath.
	 * 
	 * So call fixContentUrlPath(contributor_text, contributor_elementPath,
	 * baseElement_backPath)
	 * 
	 * @param content
	 * @param contentPath
	 * @param oldContentPath
	 * @return String the updated content with fixed path.
	 */
	public static String fixContentUrlPath(String content, String contentPath,
			String backPath) {
		StringBuffer sb = new StringBuffer();
		try {
			// process images
			Matcher m = ResourceHelper.p_image_ref.matcher(content);
			while (m.find()) {
				String url = m.group(3);
				url = resolveUrl(url, contentPath, backPath);
				if (url != null) {
					m.appendReplacement(sb, m.group(1) + url + m.group(4));
				}
			}
			m.appendTail(sb);

			content = sb.toString();
			sb = new StringBuffer();

			// process attachments
			m = ResourceHelper.p_link_ref_gen.matcher(content);
			while (m.find()) {
				StringBuffer sbLink = new StringBuffer();
				// String tag = m.group(1);
				String urltext = " " + m.group(2) + " "; //$NON-NLS-1$ //$NON-NLS-2$
				if (ResourceHelper.getGuidFromUrl(urltext) == null) {
					Matcher m2 = ResourceHelper.p_link_href_picker
							.matcher(urltext);
					if (m2.find()) {
						String url = m2.group(1).trim().replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
						url = resolveUrl(url, contentPath, backPath);
						if (url != null) {
							m2.appendReplacement(sbLink, urltext.substring(m2
									.start(), m2.start(1))
									+ url
									+ urltext.substring(m2.end(1), m2.end()));
							m2.appendTail(sbLink);
							m.appendReplacement(sb, content.substring(
									m.start(), m.start(2))
									+ sbLink.toString()
									+ content.substring(m.end(2), m.end()));
						}
					}
				}

			}
			m.appendTail(sb);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return sb.toString();
	}

	public static String resolveUrl(String url, String contentPath,
			String backPath) {
		url = getFilePathFromUrl(url, contentPath);
		if (url != null) {
			if (backPath != null) {
				url = backPath + url;
			}

			return url.replace(File.separatorChar, '/');
		}

		return null;
	}

	private static final String EXTERNAL_URL_START_WITH = LayoutResources
			.getString("externalUrl_startWith"); //$NON-NLS-1$

	public static final Pattern p_external_url_startWith = Pattern
			.compile(
					"(" + EXTERNAL_URL_START_WITH + ")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	public static boolean isExternalLink(String url) {
		// return url.startsWith("http://") || url.startsWith("www.") ||
		// url.startsWith("ftp://") ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		Matcher m = p_external_url_startWith.matcher(url);
		if (m.find()) {
			return (m.start(1) == 0);
		}

		return false;
	}
	
	
	/**
	 * find the resource file based on the url, copy the file to the destination
	 * folder. if the file is an html attachment, scan the file recursively and
	 * copy contained images, resources.
	 * 
	 * @param owner
	 *            MethodElement, the owner element
	 * @param resourceFile
	 *            File, the resource file
	 * @param url
	 *            String the url to be processed
	 * @param contentPath
	 *            String the content path of the url owner, relative to the
	 *            source root path
	 * @param sourceRootPath
	 *            File the source root path, usually it's the library root path
	 * @param targetRootPath
	 *            File the target root path, usually it's the publishing root
	 *            path
	 * @param processedItems
	 *            List, a list to hold all processed urls, to avoid duplicate
	 *            processing
	 * @param validator
	 *            IContentValidator
	 * @return String the fixed url, not used.
	 */
	public static String processResourceUrl(MethodElement owner,
			File resourceFile, String url, String contentPath,
			File sourceRootPath, File targetRootPath, List processedItems,
			IContentValidator validator) {
		if (url == null
				|| isExternalLink(url)
				|| url.startsWith(URL_STR_MAILTO)
				|| url.toLowerCase().startsWith(URL_STR_JAVASCRIPT)
				|| url.startsWith(URL_BOOKMARK_INDICATOR)) 
		{
			return url;
		}

		// if the url contains the guid, it might be some kind of element link,
		// for example, activity can have model than one element link
		String guid = ""; //$NON-NLS-1$
		if (owner != null)
			guid = owner.getGuid();
		if (url.indexOf(guid) >= 0) {
			return url;
		}

		// RATLC00384586 - Publishing report lists missing resource files that
		// are present
		// bookmarks should be stripped out when checking resource
		int index = url.indexOf(URL_BOOKMARK_INDICATOR);
		if (index < 0) {
			index = url.indexOf(URL_PARAMETER_INDICATOR);
		}

		String url_tail = "";
		if (index > 0) {
			url_tail = url.substring(index);
			url = url.substring(0, index);
		}

		String imageFile = ResourceHelper.getFilePathFromUrl(url, contentPath);
		if (imageFile == null) {
			if (validator != null) {
				validator.logMissingResource(owner, resourceFile, url);
			}
			return null;
		}

		// index.htm is the default index file, always ignore it
		if (imageFile.equalsIgnoreCase("index.htm") || imageFile.equalsIgnoreCase("index.html")) //$NON-NLS-1$ //$NON-NLS-2$
		{
			return url + url_tail;
		}

		String newUrl = url;

		File source;
		File dest;
		// check if this is a real file, if not, it is a reference to a base
		// plugin
		source = new File(sourceRootPath, imageFile);

		// if the file is not in the library, check the plugin layout folder
		if (!source.exists()) {
			source = new File(LibraryPlugin.getDefault().getLayoutPath(),
					imageFile);
		}

		dest = new File(targetRootPath, imageFile);

		if (source.exists()) {
			ResourceHelper.copyFile(source, dest);

			// if the file is an html attachment, need to scan the file and copy
			// the referenced file in it, recursively
			if (imageFile.endsWith(ResourceHelper.FILE_EXT_HTM)
					|| imageFile.endsWith(ResourceHelper.FILE_EXT_HTML)) {
				File f = new File(imageFile);
				try {
					resolveResources(owner, f, FileUtil.readFile(source,
							FileUtil.ENCODING_UTF_8).toString(), f.getParent(),
							sourceRootPath, targetRootPath, processedItems,
							validator);
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
		}
		// if the destination file is there, might be generated dynamically, so
		// don't log it
		else if (!dest.exists() && isValidFileUrl(url) && (validator != null)) {
			validator.logMissingResource(owner, resourceFile, url);
		}

		return newUrl + url_tail;

	}

	private static boolean isValidFileUrl(String url) {
		// just a temp solution here to get rid of the wrong reporting of mssing resource
		if ( url == null || url.equals("' + diagram_img + '") ) { //$NON-NLS-1$
			return false;
		}
		
		return true;
	}
	
	/**
	 * resolve the images in the text. copy the image to destination if needed
	 * This is used for copying resources from a library to another destination
	 * 
	 * @param owner
	 *            MethodElement, the owner element
	 * @param resourceFile
	 *            File, the resource file
	 * @param content
	 *            String the content string to be processed
	 * @param contentPath
	 *            String the content path of the source text, relative to the
	 *            source root path
	 * @param sourceRootPath
	 *            File the source root path, usually it's the library root path
	 * @param targetRootPath
	 *            File the target root path, usually it's the publishing root
	 *            path
	 * @param processedItems
	 *            List, a list to hold all processed urls, to avoid duplicate
	 *            processing
	 * @param validator
	 *            IContentValidator
	 */
	public static void resolveResources(MethodElement owner, File resourceFile,
			String content, String contentPath, File sourceRootPath,
			File targetRootPath, List processedItems,
			IContentValidator validator) {
		try {
			// process images
			Matcher m = ResourceHelper.p_image_ref.matcher(content);
			while (m.find()) {
				String url = m.group(3);
				if (!processedItems.contains(url)) {
					// note: add the url into the processedItems list first,
					// otherwise may get deadlock if the url content has
					// reference back to the owner
					processedItems.add(url);
					ResourceHelper.processResourceUrl(owner, resourceFile, url,
							contentPath, sourceRootPath, targetRootPath,
							processedItems, validator);
				}
			}
			
			m = ResourceHelper.p_css_ref.matcher(content);
			while (m.find()) {
				String cssURL = m.group(1);
				
				// it's hard to tell if this is a right match or not 
				// since we can't tell if the matched one is actually from a css or just a html text
				// for example, text can have something like url(xxx) which is matched here
				// we don't want to report missing resource for this
				// so don't set the validator
				// RATLC00386230 - Publishing warnings:  inappropriate warnings coming from required copyrite.htm

				if (!processedItems.contains(cssURL)) {
					// note: add the url into the processedItems list first,
					// otherwise may get deadlock if the url content has
					// reference back to the owner
					processedItems.add(cssURL);
					ResourceHelper.processResourceUrl(owner, resourceFile, cssURL,
							contentPath, sourceRootPath, targetRootPath,
							processedItems, null/*validator*/);
				}
			}			

			// process attachments
			m = ResourceHelper.p_link_ref_gen.matcher(content);
			while (m.find()) {
				// String tag = m.group(1);
				String urltext = m.group(2);
				if (ResourceHelper.getGuidFromUrl(urltext) == null) {
					Matcher m2 = ResourceHelper.p_link_href_picker
							.matcher(" " + urltext + " "); //$NON-NLS-1$ //$NON-NLS-2$
					if (m2.find()) {
						String url = m2.group(1).trim().replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
						if (!processedItems.contains(url)) {
							// note: add the url into the processedItems list
							// first, otherwise may get deadlock if the url
							// content has reference back to the owner
							processedItems.add(url);
							ResourceHelper.processResourceUrl(owner,
									resourceFile, url, contentPath,
									sourceRootPath, targetRootPath,
									processedItems, validator);
						}
					}
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * take the tag attributes string as input and returns the attribute
	 * name-value map
	 * 
	 * @param attributesStr
	 * @return Map the attribute name-value map
	 */
	public static Map getTagAttributes(String attributesStr) {

		Map attributeMap = new HashMap(3);
		Matcher m2 = p_tag_attributes.matcher(attributesStr);
		while (m2.find()) {
			String attrName = m2.group(1).trim().toLowerCase();
			String attrValue = m2.group(2).trim();

			// RATLC00384297 - GVT: Cannot Preview/Browse Description Tab when
			// the CP contains chinese characters
			// generated html from xslt got the href urls encoded. we don't want
			// that
			// make sure decode the url using "UTF-8" encoding
			if (attrName.equals(TAG_ATTR_HREF)) {
				try {
					attrValue = URLDecoder.decode(attrValue, "UTF-8"); //$NON-NLS-1$
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
			attributeMap.put(attrName, attrValue);
		}

		return attributeMap;
	}

	/**
	 * returns the attribute name-value map for an HTML link
	 * @param link
	 * @return
	 */
	public static Map getAttributesFromLink(String link) {
		Matcher m = p_link_ref.matcher(link);
		if (m.find()) {
			String attributes = m.group(1);
			return getTagAttributes(attributes);
		}
		return null;
	}
	
	/**
	 * takes an attributeMap (ie, from #getTagAttributes) and returns the String representation
	 * @param attributeMap
	 * @return
	 */
	public static String getAttributesAsString(Map attributeMap) {
		StringBuffer buf = new StringBuffer();
		for (Iterator iter = attributeMap.keySet().iterator();iter.hasNext();) {
			String key = (String) iter.next();
			String value = (String) attributeMap.get(key);
			if (buf.length() > 0)
				buf.append(" "); //$NON-NLS-1$
			buf.append(key + "=\"" + value + "\""); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return buf.toString();
	}
	
	/**
	 * Created to handle RATLC00385815: DVT - Bad link from Welcome page hump chart
	 * 
	 */
	private static String getDiscardedElementURL(MethodElement ownerElement, MethodElement linkElement, String guid, String pubDir)
	{
		StringBuffer discardedElementURL = new StringBuffer();
		
		discardedElementURL.append(MISSING_PAGES_FOLDER).append("pages_not_installed").append(FILE_EXT_HTML);
	   
	    File outputFile = new File(pubDir, discardedElementURL.toString());
		File dir = outputFile.getParentFile();
		if (!dir.exists()) 
		{
			dir.mkdirs();
		}
	
		// generate the html file
		XmlElement xml = new XmlElement("Element"); //$NON-NLS-1$
			
		xml.setAttribute("guid", guid).setAttribute("type", linkElement.getType().getName()) //$NON-NLS-1$
			.setAttribute("name", linkElement.getName()) //$NON-NLS-1$
				.setAttribute("pluginName", LibraryUtil.getMethodPlugin(linkElement).getName()); //$NON-NLS-1$								
		String xslPath = LayoutResources.getXslUri("page_not_installed", null); //$NON-NLS-1$
			
		try 
		{
			StringBuffer xml2 = new StringBuffer();
			xml2.append(XmlHelper.XML_HEADER).append(xml.toXml());
	
			OutputStreamWriter output = new OutputStreamWriter(
					new FileOutputStream(outputFile), "utf-8"); //$NON-NLS-1$
			Properties xslParams = LibraryPlugin.getDefault().getProperties(
				"/layout/xsl/resources.properties"); //$NON-NLS-1$
	
			XSLTProcessor.transform(xslPath, xml2.toString(), xslParams, output);
			output.flush();
			output.close();
		} 
		catch (Exception ex) 
		{
			ex.printStackTrace();
		}
	
		return getBackPath(ownerElement).replace(File.separatorChar, '/') + discardedElementURL.toString();
	}
}
