| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2007 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.Iterator; |
| import java.util.LinkedHashMap; |
| 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.core.resources.IResource; |
| import org.eclipse.emf.ecore.EObject; |
| 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.ILibraryManager; |
| import org.eclipse.epf.library.LibraryPlugin; |
| import org.eclipse.epf.library.LibraryResources; |
| import org.eclipse.epf.library.LibraryService; |
| 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.FileNameCache; |
| import org.eclipse.epf.persistence.FileManager; |
| import org.eclipse.epf.persistence.MethodLibraryPersister; |
| import org.eclipse.epf.uma.MethodConfiguration; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.MethodPlugin; |
| import org.eclipse.epf.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*(\"?)(.*?)\\2", 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 MethodElement |
| * @return String |
| */ |
| 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 MethodElement |
| * @return String |
| */ |
| 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$ |
| } |
| |
| /** |
| * fix the path by appending a File.seperator to the end of it |
| * @param path String |
| * @return String |
| */ |
| 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 element's back path relative to the library root. For example, |
| * "OpenUP\guidance\concept\c1.xml", the back path is "./../../../" |
| * |
| * @param element MethodElement |
| * @return String |
| */ |
| public static String getBackPath(MethodElement element) { |
| // 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 |
| * |
| * @param element MethodElement |
| * @param ext String the file extenasion, for example, ".html" |
| * @return String |
| */ |
| public static String getFileName(MethodElement element, String ext) { |
| return getFileName(element, null, null, ext); |
| } |
| |
| /** |
| * get the file name with the given prefix and extension |
| * @param element MethodElement |
| * @param namePrefix String prefix for the name |
| * @param nameSuffix String suffix for the name |
| * @param ext String file extension, for example, ".html" |
| * @return String |
| */ |
| public static String getFileName(MethodElement element, String namePrefix, |
| String nameSuffix, String ext) { |
| return FileNameCache.getInstance().getFileName(element, namePrefix, nameSuffix, ext); |
| } |
| |
| /** |
| * get the guid from the file name, assuming the file name is generated from an element, |
| * return null if not found. |
| * @param fileName String |
| * @return String |
| */ |
| public static String getGuidFromFileName(String fileName) { |
| return FileNameCache.getInstance().getGuidFromFileName(fileName); |
| } |
| |
| /** |
| * get the element from the file name, assuming the file name is generated from an element, |
| * return null if not. |
| * @param fileName String |
| * @return MethodElement |
| */ |
| public static MethodElement getElementFromFileName(String fileName) { |
| String guid = getGuidFromFileName(fileName); |
| if (guid != null) { |
| ILibraryManager manager = LibraryService.getInstance() |
| .getCurrentLibraryManager(); |
| if (manager != null) { |
| return manager.getMethodElement(guid); |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * get the element url relative to the refElement |
| * |
| * @param element MethodElement |
| * @param refElement MethodElement |
| * @param fileExt String file extension |
| * @param old_url String the old url of the element. If the old url is not null, |
| * any bookmark or url parameters are passed to the new url |
| * @return String String the new element |
| */ |
| 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 MethodElement |
| * @param refElement MethodElement |
| * @param fileExt String file extension |
| * @return String the url |
| */ |
| 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); |
| } |
| } |
| |
| /** |
| * get the link text for an element |
| * @param e MethodElement |
| * @param linkType String |
| * @return String |
| */ |
| public static String getLinkText(MethodElement e, String linkType) { |
| String linkedText = null; |
| |
| // RTE may change the case of attributes. |
| if ((linkType != null) |
| && !ELEMENT_LINK_CLASS_elementLinkWithUserText.equalsIgnoreCase(linkType)) { |
| if (ELEMENT_LINK_CLASS_elementLinkWithType.equalsIgnoreCase(linkType)) { |
| linkedText = getElementLinkText(e, true); |
| } else if (ELEMENT_LINK_CLASS_elementLink.equalsIgnoreCase(linkType)) { |
| linkedText = getElementLinkText(e, false); |
| } |
| } |
| |
| return linkedText; |
| } |
| |
| /** |
| * get the element link text for the given element |
| * @param element MethodElement |
| * @param withType boolean if true the element type string will be included |
| * @return String |
| */ |
| public static String getElementLinkText(MethodElement element, |
| boolean withType) { |
| String text = TngUtil.getPresentationName(element); |
| |
| if (withType) { |
| return getElementTypeText(element) + LibraryResources.colon_with_space + text; |
| } |
| |
| return text; |
| } |
| |
| /** |
| * gte the element type string |
| * @param element MethodElement |
| * @return String |
| */ |
| 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 |
| * @return 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 String |
| */ |
| 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 String |
| */ |
| 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 element |
| * @param source |
| * @return String |
| */ |
| public static String validateContent(MethodElement element, String source) { |
| return validateContent(element, source, new DefaultContentValidator(), |
| null); |
| } |
| |
| /** |
| * check if the link type is element link or not |
| * @param linkType String |
| * @return boolean |
| */ |
| public static boolean isElementLink(String linkType) { |
| if (linkType == null || linkType.length() == 0) { |
| return false; |
| } |
| |
| // RTE may change the case of attributes. |
| return linkType.equalsIgnoreCase(ELEMENT_LINK_CLASS_elementLink) |
| || linkType.equalsIgnoreCase(ELEMENT_LINK_CLASS_elementLinkWithType) |
| || linkType.equalsIgnoreCase(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(); |
| |
| // 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(validator.showBrokenLinks()).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, regExpEscape(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); |
| |
| ILibraryManager manager = LibraryService.getInstance() |
| .getCurrentLibraryManager(); |
| while (m.find()) { |
| // String text = m.group(); |
| String href = m.group(2); |
| String guid = null; |
| if ( !isJavascriptUrl(href) ) { |
| guid = getGuidFromFileName(href); |
| } |
| |
| if (guid != null) { |
| MethodElement e = manager != null ? manager |
| .getMethodElement(guid) : null; |
| 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 if ( validator.showBrokenLinks() ){ |
| href = getDiscardedElementURL(element, e, guid, |
| ((DefaultContentValidator) validator) |
| .getPublishDir()); |
| } else { |
| href = ""; |
| } |
| } |
| } else { |
| href = URLDecoder.decode(href, "UTF-8"); //$NON-NLS-1$ |
| } |
| |
| String replacement; |
| if ( href == null || href.length() == 0 ) { |
| replacement = source.substring(m.start(), m.start(1)) |
| + source.substring(m.end(1), m.end()); |
| } else { |
| replacement = source.substring(m.start(), m.start(2)) |
| + href + source.substring(m.end(2), m.end()); |
| } |
| m.appendReplacement(sb, regExpEscape(replacement)); |
| } |
| |
| m.appendTail(sb); |
| |
| // 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 { |
| // 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$ |
| String text = m.group(1) + url + m.group(4); |
| m.appendReplacement(sb, regExpEscape(text)); |
| } |
| m.appendTail(sb); |
| |
| return sb.toString(); |
| |
| } catch (UnsupportedEncodingException e) { |
| e.printStackTrace(); |
| } |
| |
| return content; |
| } |
| |
| /** |
| * escape the regexp reserved words, such as $ |
| * @param text String |
| * @return String |
| */ |
| public static String regExpEscape(String text) { |
| // escape the regExp reserved words, |
| // the $ sign is reserved for group matching |
| int i=text.indexOf('$'); //$NON-NLS-1$ |
| if ( i < 0 ) { |
| return text; |
| } |
| |
| int start = 0; |
| StringBuffer buffer = new StringBuffer(); |
| while ( i > start ) { |
| buffer.append(text.substring(start, i)).append("\\"); //$NON-NLS-1$ |
| start = i; |
| i=text.indexOf('$', start+1); //$NON-NLS-1$ |
| } |
| |
| buffer.append(text.substring(start)); |
| |
| return buffer.toString(); |
| } |
| |
| /** |
| * 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) { |
| ILibraryManager manager = LibraryService.getInstance() |
| .getCurrentLibraryManager(); |
| MethodElement e = manager != null ? manager |
| .getMethodElement(guid) : null; |
| 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, regExpEscape(replacement)); |
| m.appendTail(sb); |
| return sb.toString(); |
| |
| } |
| } |
| |
| return urltext; |
| } |
| |
| /** |
| * get the element link type for the url |
| * @param source String the link |
| * @return String the type string |
| */ |
| 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; |
| } |
| |
| /** |
| * get the guid from the url |
| * @param source String the url |
| * @return Strign the guid |
| */ |
| 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, regExpEscape(replacement)); |
| } |
| |
| m.appendTail(sb); |
| |
| return sb.toString(); |
| } |
| |
| /** |
| * fix tag attribute |
| * @param source |
| * @return String |
| */ |
| 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 String |
| */ |
| 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 = new File(LibraryService.getInstance() |
| .getCurrentMethodLibraryPath()); |
| 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 java.net.URI |
| */ |
| public static java.net.URI getFileRelativeURI(File f) { |
| File libraryRootPath = new File(LibraryService.getInstance() |
| .getCurrentMethodLibraryPath()); |
| 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 boolean |
| */ |
| 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 ./../<roles>/resources/<filename of |
| * attachment> |
| * @throws IOException |
| */ |
| public static String getURLForAttachment(File attachment, |
| MethodElement element, boolean copyFile) throws IOException { |
| String libDir = LibraryService.getInstance() |
| .getCurrentMethodLibraryPath(); |
| String pluginDir = FileUtil.appendSeparator(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); |
| IResource wsResource = FileManager.getResourceForLocation(formatFile.getAbsolutePath()); |
| if(wsResource != null) { |
| try { |
| FileManager.refresh(wsResource); |
| } |
| catch(Exception e) { |
| LibraryPlugin.getDefault().getLogger().logError(e); |
| } |
| } |
| } |
| } |
| |
| return ResourceHelper.getRelativePathToFileFromElement(element, |
| formatFile); |
| |
| } |
| |
| /** |
| * |
| * @param element |
| * @param attachment |
| * @return String |
| */ |
| public static String getRelativePathToFileFromElement( |
| MethodElement element, File attachment) { |
| String libDir = LibraryService.getInstance() |
| .getCurrentMethodLibraryPath(); |
| // 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) { |
| // Instances of the same activity/CP share the |
| // same diagram in a Delivery Process |
| // need to make the name unique |
| return getElementResourcePath(e) |
| + StrUtil.removeSpecialCharacters(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, regExpEscape(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) { |
| String replacement = urltext.substring(m2.start(), m2.start(1)) |
| + url |
| + urltext.substring(m2.end(1), m2.end()); |
| |
| m2.appendReplacement(sbLink, regExpEscape(replacement)); |
| m2.appendTail(sbLink); |
| |
| replacement = content.substring(m.start(), m.start(2)) |
| + sbLink.toString() + content.substring(m.end(2), m.end()); |
| m.appendReplacement(sb, regExpEscape(replacement)); |
| } |
| } |
| } |
| |
| } |
| m.appendTail(sb); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| return sb.toString(); |
| } |
| |
| /** |
| * |
| * @param url |
| * @param contentPath |
| * @param backPath |
| * @return String |
| */ |
| 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$ |
| |
| /** |
| * check if this is an external url or not |
| * @param url |
| * @return boolean |
| */ |
| public static boolean isExternalLink(String url) { |
| // 162969 - Refine external link's regular exp in epf.library/layout/LayoutResources.properties |
| // file:// should be excluded |
| if ( url == null ) { |
| return false; |
| } |
| |
| url = url.toLowerCase(); |
| if ( url.startsWith("file://") ) { //$NON-NLS-1$ |
| return false; |
| } |
| |
| if ( url.startsWith("http://") //$NON-NLS-1$ |
| || url.startsWith("https://") //$NON-NLS-1$ |
| || url.startsWith("ftp://") //$NON-NLS-1$ |
| || url.startsWith("www.") ) { //$NON-NLS-1$ |
| return true; |
| } |
| |
| Matcher m = p_external_url_startWith.matcher(url); |
| if (m.find()) { |
| return (m.start(1) == 0); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * |
| * @param url |
| * @return boolean |
| */ |
| public static boolean isJavascriptUrl(String url) { |
| if (url == null ) { |
| return false; |
| } |
| return url.startsWith(URL_STR_MAILTO) |
| || url.toLowerCase().startsWith(URL_STR_JAVASCRIPT); |
| } |
| |
| /** |
| * 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) || isJavascriptUrl(url) |
| || 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; |
| } |
| } |
| |
| // 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 |
| // 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) { |
| |
| // use LinkedHashMap to reserve the order of the attributes |
| Map attributeMap = new LinkedHashMap(3); |
| Matcher m2 = p_tag_attributes.matcher(attributesStr); |
| while (m2.find()) { |
| String attrName = m2.group(1).trim().toLowerCase(); |
| String attrValue = m2.group(3).trim(); |
| |
| // 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 Map |
| */ |
| 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 String |
| */ |
| 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(); |
| } |
| |
| /** |
| * 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(); |
| } |
| |
| |
| |
| /** |
| * FOR USE WITH RICH TEXT EDITOR |
| * validate the content by checking element links and images, for the |
| * specified element owner |
| * |
| * This is identical to the validateContent method, except it does not decode the results |
| * via URLDecoder.decode() |
| * |
| * @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 validateRichTextContent(MethodElement element, String source, IContentValidator validator) { |
| try { |
| MethodConfiguration config = null; |
| |
| // 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(); |
| |
| // 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(validator.showBrokenLinks()).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, regExpEscape(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); |
| |
| ILibraryManager manager = LibraryService.getInstance() |
| .getCurrentLibraryManager(); |
| while (m.find()) { |
| // String text = m.group(); |
| String href = m.group(2); |
| String guid = getGuidFromFileName(href); |
| if (guid != null) { |
| MethodElement e = manager != null ? manager |
| .getMethodElement(guid) : null; |
| 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 if ( validator.showBrokenLinks() ){ |
| href = getDiscardedElementURL(element, e, guid, |
| ((DefaultContentValidator) validator) |
| .getPublishDir()); |
| } else { |
| href = ""; |
| } |
| } |
| } |
| |
| String replacement; |
| if ( href == null || href.length() == 0 ) { |
| replacement = source.substring(m.start(), m.start(1)) |
| + source.substring(m.end(1), m.end()); |
| } else { |
| replacement = source.substring(m.start(), m.start(2)) |
| + href + source.substring(m.end(2), m.end()); |
| } |
| |
| m.appendReplacement(sb, regExpEscape(replacement)); |
| } |
| |
| m.appendTail(sb); |
| |
| return sb.toString(); |
| |
| } catch (Exception ex) { |
| LibraryPlugin.getDefault().getLogger().logError(ex); |
| } |
| |
| return source; |
| } |
| |
| /** |
| * copy all resource files associated with the element to the target location. |
| * recursive all it's contained elements if recursive is true. |
| * |
| * @param element |
| * @param from |
| * @param to |
| */ |
| public static void copyAllResources(EObject element, File from, File to, boolean recursive) { |
| |
| ContentResourceScanner scanner = new ContentResourceScanner(from); |
| scanner.setTargetRootPath(to); |
| scanner.copyResources(element); |
| |
| if ( recursive ) { |
| for ( Iterator it = element.eAllContents(); it.hasNext(); ) { |
| EObject obj = (EObject)it.next(); |
| scanner.copyResources(obj); |
| } |
| } |
| } |
| } |