blob: 21f748c5ca86fe6e236a55876ee563d427a17b3f [file] [log] [blame]
//------------------------------------------------------------------------------
// 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.FileInputStream;
import java.io.FileNotFoundException;
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.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.ILibraryResourceManager;
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.BrowsingLayoutSettings;
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.elements.ActivityLayout;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.layout.util.XmlHelper;
import org.eclipse.epf.persistence.MethodLibraryPersister;
import org.eclipse.epf.publish.layout.LayoutPlugin;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
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_template_attachment_url = Pattern
.compile(
"<a\\s+?href\\s*?=\\s*?\"(.*?)\"\\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_area_ref = Pattern
.compile(
"<area\\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(
"\\s*class\\s*?=\\s*?(.*?)\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
public static final Pattern p_link_guid_picker = Pattern
.compile(
"\\s*guid\\s*?=\\s*?(.*?)\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
public static final Pattern p_link_href_picker = Pattern
.compile(
"\\s*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*=\\s*([\\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$
private static ILibraryResourceManager defaultResourceMgr;
private static boolean showSkinResource = false;
public static String LAYOUT_XSL_ROOT_PATH = null;
public ResourceHelper() {
}
public static synchronized void setDefaultResourceMgr(ILibraryResourceManager mgr) {
defaultResourceMgr = mgr;
}
public static synchronized ILibraryResourceManager getDefaultResourceMgr() {
return defaultResourceMgr;
}
public static ILibraryResourceManager getResourceMgr(MethodElement element) {
MethodLibrary lib = UmaUtil.getMethodLibrary(element);
if ( lib != null ) {
ILibraryManager libMgr = LibraryService.getInstance().getLibraryManager(lib);
if (libMgr == null) {
lib = LibraryService.getInstance().getCurrentMethodLibrary();
libMgr = LibraryService.getInstance().getLibraryManager(lib);
}
if (libMgr == null) {
return getDefaultResourceMgr();
}
return libMgr.getResourceManager();
}
return null;
}
/**
* 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) {
ILibraryResourceManager resMgr = getResourceMgr(element);
if ( resMgr != null ) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(element);
if (plugin == null) {
return resMgr.getLogicalResourcePath(element);
} else {
return resMgr.getLogicalResourcePath(plugin);
}
}
return null;
}
/**
* 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) {
ILibraryResourceManager resMgr = getResourceMgr(element);
if ( resMgr != null ) {
return resMgr.getLogicalResourcePath(element);
}
return null;
}
/**
* Gets the absolute path of the resource folder of the element in the library.
*
* @param e
* @return absolute path of the element's resource folder
*/
public static String getAbsoluteElementResourcePath(MethodElement element) {
ILibraryResourceManager resMgr = getResourceMgr(element);
if ( resMgr != null ) {
return resMgr.getPhysicalResourcePath(element);
}
return null;
}
/**
* 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.INSTANCE.getRelativeElementPath(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$
ILibraryResourceManager resMgr = getResourceMgr(element);
if ( resMgr != null ) {
return resMgr.getLogicalPath(element);
}
return null;
}
// private static IFileBasedLibraryPersister getFileBasedLibraryPersister(MethodElement element) {
// Resource resource = element.eResource();
// if(resource != null) {
// ILibraryPersister persister = LibraryServiceUtil.getPersisterFor(resource);
// if(persister instanceof IFileBasedLibraryPersister) {
// return ((IFileBasedLibraryPersister)persister);
// }
// }
// return null;
// }
//
// /**
// * Gets the path of a method element's folder relative to its plug-in.
// *
// * @param element
// * @return
// * @deplicated
// */
// private static String getFolderRelativePath(MethodElement element) {
// IFileBasedLibraryPersister persister = getFileBasedLibraryPersister(element);
// return persister != null ? persister.getFolderRelativePath(element) : null;
// }
/**
* Gets the absolute path of a method element's folder.
*
* @param element
* @return the absolute path
*/
public static String getFolderAbsolutePath(MethodElement element) {
// if ( element == null ) {
// return null;
// }
//
// IFileBasedLibraryPersister persister = getFileBasedLibraryPersister(element);
// return persister != null ? persister.getFolderAbsolutePath(element) : null;
ILibraryResourceManager resMgr = getResourceMgr(element);
if ( resMgr != null ) {
return resMgr.getPhysicalPath(element);
}
return null;
}
// /**
// * return the parent folder of the plugin or configuration of the element.
// * or the library root if the element is the MethodLibrary.
// *
// * @param element MethodElement
// * @return String
// */
// public static String getVirtualLibraryRoot(MethodElement element) {
// if ( element instanceof MethodLibrary ) {
// // default, return the current library path
// return LibraryService.getInstance().getCurrentMethodLibraryLocation();
// }
//
// String path = null;
// if (element instanceof MethodConfiguration ) {
// path = getFolderAbsolutePath(element);
// } else {
// path = getPluginPath(element);
// }
//
// if ( path != null ) {
// File f = new File(path);
// return f.getParentFile().getAbsolutePath();
// }
//
// return null;
// }
// /**
// * 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$
ILibraryResourceManager resMgr = getResourceMgr(element);
if ( resMgr != null ) {
return resMgr.getBackPath(element);
}
return ""; //$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 FileNameGenerator.INSTANCE.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 FileNameGenerator.INSTANCE.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, MethodConfiguration config) {
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, config);
} else if (ELEMENT_LINK_CLASS_elementLink.equalsIgnoreCase(linkType)) {
linkedText = getElementLinkText(e, false, config);
}
}
return linkedText;
}
public static String getLinkText(MethodElement e, String linkType) {
return getLinkText(e, linkType, null);
}
/**
* 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) {
return getElementLinkText(element, withType, null);
}
public static String getElementLinkText(MethodElement element,
boolean withType, final MethodConfiguration config) {
TngUtil.PresentationNameHelper pHelper = config == null ? null :
new TngUtil.PresentationNameHelper() {
public String getPresentationName(MethodElement element) {
if (element == null) {
return null;
}
String str = super.getPresentationName(element);
if (StrUtil.isBlank(str) && element instanceof VariabilityElement) {
VariabilityElement ve = (VariabilityElement) element;
if (ve.getVariabilityType() == VariabilityType.EXTENDS_REPLACES) {
VariabilityElement base = ve.getVariabilityBasedOnElement();
String baseStr = base == null ? null : base.getPresentationName();
if (! StrUtil.isBlank(baseStr)) {
return baseStr;
}
}
}
return str;
}
};
String text = TngUtil.getPresentationName(element, pHelper);
// if (withType) {
// return getElementTypeText(element) + LibraryResources.colon_with_space + text;
// }
//
// return text;
if (withType) {
if (showSkinResource) {
if ((LAYOUT_XSL_ROOT_PATH == null)
|| (LAYOUT_XSL_ROOT_PATH.equals(""))) {//$NON-NLS-1$
File xslPath = BrowsingLayoutSettings.INSTANCE.getXslPath();
if (xslPath != null)
LAYOUT_XSL_ROOT_PATH = xslPath.getAbsolutePath();
}
Properties browsingResource = new Properties();
File file = new File(LAYOUT_XSL_ROOT_PATH, "resources.properties"); //$NON-NLS-1$
// Locale locale = Locale.getDefault();
// String localFileName = I18nUtil.getLocalizedFile(file
// .getAbsolutePath(), locale);
// if (localFileName != null) {
// file = new File(localFileName);
// }
if (file.exists()) {
try {
browsingResource.load(new FileInputStream(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String type = getElementTypeText(element);
String elementName = element.eClass().getName();
String key = elementName.substring(0, 1).toLowerCase()
+ elementName.substring(1) + "Text";//$NON-NLS-1$
String value = browsingResource.getProperty(key);
if (value != null) {
return value + LibraryResources.colon_with_space + text;
} else {
return type + LibraryResources.colon_with_space + text;
}
}
else
{
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 ""; //$NON-NLS-1$
}
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, 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, String layoutXslRootPath) {
try {
ResourceHelper.LAYOUT_XSL_ROOT_PATH = layoutXslRootPath;
showSkinResource = true;
// 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, "a"); //$NON-NLS-1$
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);
while (m.find()) {
String text = m.group();
String urltext = m.group(1);
LinkInfo info = validator.validateLink(element, urltext,
"", config, "area"); //$NON-NLS-1$ //$NON-NLS-2$
if (info != null) {
// don't show broken links in area map. Show plan text instead
text = info.getHtml(false/*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);
// 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();
}
finally
{
ResourceHelper.LAYOUT_XSL_ROOT_PATH = null;
showSkinResource = false;
}
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
String newtext = StrUtil.escapeChar(text, '\\');
newtext = StrUtil.escapeChar(newtext, '$');
return newtext;
}
/**
* 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
// * @deplicated this method is not valid for distributed library
// */
// private 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
// * @deplicated this method is not valid for distributed library
// */
// private 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
* @deplicated
*/
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
// * @deplicated this method is not valid for distributed library
// */
// private static String getFileRelPath(File f) {
// File libraryRootPath = new File(LibraryService.getInstance()
// .getCurrentMethodLibraryLocation());
// 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
// * @deplicated this method is not valid for distributed library
// */
// private static java.net.URI getFileRelativeURI(File f) {
// File libraryRootPath = new File(LibraryService.getInstance()
// .getCurrentMethodLibraryLocation());
// java.net.URI libURI = libraryRootPath.toURI();
// java.net.URI fileURI = f.toURI();
// java.net.URI relUri = libURI.relativize(fileURI);
//
// return relUri;
// }
/**
*
* @param element
* @param attachment
* @return String
*/
public static String getRelativePathToFileFromElement(
MethodElement element, File attachment) {
String elementLoc = getFolderAbsolutePath(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$
return getElementResourcePath(e)
+ FileNameGenerator.INSTANCE.getFileName(e, "", "_" + diagramType, FILE_EXT_JPEG); //$NON-NLS-1$ //$NON-NLS-2$
}
public static String getXmlExportedDiagramImageFileName(MethodElement e, String diagramType, String format) {
String str = e.getName() + " " + e.getGuid() + "_" + diagramType + format; //$NON-NLS-1$ //$NON-NLS-2$
return str;
}
public static boolean isAbsolutepath(String path) {
if ( path == null ) {
return false;
}
if ( path.startsWith("/") //$NON-NLS-1$
|| path.startsWith(File.separator)
|| path.indexOf(":") > 0 ) { //$NON-NLS-1$
return true;
}
return false;
}
/**
* 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) {
String filePath = url;
if (isExternalLink(filePath)
|| filePath.startsWith("mailto:") || filePath.startsWith(URL_BOOKMARK_INDICATOR)) //$NON-NLS-1$
{
return null;
}
int index = filePath.indexOf(NetUtil.FILE_PREFIX_3);
if (index == 0) {
filePath = filePath.substring(NetUtil.FILE_PREFIX_3.length());
}
index = filePath.indexOf(NetUtil.FILE_PREFIX_2);
if (index == 0) {
filePath = filePath.substring(NetUtil.FILE_PREFIX_2.length());
}
if ( isAbsolutepath(filePath) ) {
// assume this is an absolute path
return XMLUtil.unescape(NetUtil.decodedFileUrl(filePath));
// return url;
}
File f = new File(contentPath);
int start = 0;
index = 0;
while ((f != null) && (index = filePath.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
+ filePath.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) {
if ( contentPath == null || backPath == null ) {
return content;
}
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$
if ( isExternalLink(url) ) {
// decode for external link
url = XMLUtil.unescape(NetUtil.decodedFileUrl(url));
} else {
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) {
String new_url = getFilePathFromUrl(url, contentPath);
if (isAbsolutepath(new_url))
return new_url;
if (new_url != null && !new_url.equals(url) ) {
if (backPath != null) {
new_url = backPath + new_url;
}
return new_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$ //$NON-NLS-2$
/**
* 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 rootContentPath String the content path of the root
* @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, String rootContentPath, 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 || isActivityTabUrl(url) ) {
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 = ""; //$NON-NLS-1$
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;
// if the url is a local file in an absolute path, we don't copy the file, leave as is
source = new File(imageFile);
if ( source.exists() ) {
return url + url_tail;
}
// if root Content path is set, remove from the file path
boolean usePubRoot = true;
String filePath = imageFile;
if ( rootContentPath != null && rootContentPath.length() > 0 ) {
if ( filePath.startsWith(rootContentPath) ) {
filePath = filePath.substring(rootContentPath.length());
usePubRoot = false;
}
}
// check if this is a real file, if not, it is a reference to a base
// plugin
source = new File(sourceRootPath, filePath);
// if the source does not exist, might be a reference to a resource in another plugin?
// for example, if the content is contributed from another element in another plugin, this will happen
if (!source.exists()) {
ILibraryResourceManager mgr = getResourceMgr(owner);
if ( mgr != null ) {
String tmpPath = mgr.resolve(owner, filePath);
if ( tmpPath != null ) {
source = new File(tmpPath);
}
}
}
// if the file is not in the library, check the plugin layout folder
if (!source.exists()) {
source = new File(LayoutPlugin.getDefault().getLayoutPath(),
filePath);
}
boolean calledFromGuidanceTypeConvert = false;
File sourceRootParent = sourceRootPath.getParentFile();
if (sourceRootParent.getName().equals("guidances")) { //$NON-NLS-1$
File targetRootParent = targetRootPath.getParentFile();
if (targetRootParent != null) {
targetRootParent = targetRootParent.getParentFile();
}
if (sourceRootParent.equals(targetRootParent)) {
calledFromGuidanceTypeConvert = true;
targetRootPath = targetRootPath.getParentFile();
}
}
// if the filePath is relative to the pub root, fix the target path
if ( !calledFromGuidanceTypeConvert && usePubRoot && rootContentPath != null && rootContentPath.length() > 0 ) {
File tmpf = new File(rootContentPath);
while ( tmpf != null ) {
tmpf = tmpf.getParentFile();
targetRootPath = targetRootPath.getParentFile();
}
}
dest = new File(targetRootPath, filePath);
// To be re-visited for SCM handling
// if (calledFromGuidanceTypeConvert) {
// IStatus status = Services.getFileManager().checkModify(
// new String[] { targetRootPath.getAbsolutePath(),
// dest.getAbsolutePath() },
// PersistencePlugin.getDefault().getContext());
// if (status != null && !status.isOK()) {
// Copy file using ws resource API
// return newUrl + url_tail;
// }
// }
if (source.exists()) {
FileUtil.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, rootContentPath, 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 isActivityTabUrl(String url) {
return ActivityLayout.isActivityTabUrl(url);
}
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 rootContentPath String the content path of the root
* @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, String rootContentPath, 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, rootContentPath,
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, rootContentPath, 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, rootContentPath,
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) {
try {
// 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 = ""; //$NON-NLS-1$
if (m2.group(3) != null) {
attrValue = m2.group(3).trim();
} else if (m2.group(2) != null) {
attrValue = m2.group(2).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;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 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;
}
/**
* returns the attribute name-value map for an HTML link
*
* @param link
* @return Map
*/
public static Map getAttributesFromLink(Pattern pattern, String link) {
Matcher m = pattern.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); //$NON-NLS-1$
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$ //$NON-NLS-2$
.setAttribute("name", linkElement.getName()) //$NON-NLS-1$
.setAttribute(
"pluginName", LibraryUtil.getMethodPlugin(linkElement).getName()); //$NON-NLS-1$
String xslPath = LayoutResources.getDefaultXslPath("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 = LayoutPlugin.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()
*
* this will do the following to the HTML:
* 1. update Element Links
* 2. change <A ..> to <a ..>
* 3. change </A> to </a>
* 4. add double-quotes (") around all attribute values if they are missing
*
* @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, "a"); //$NON-NLS-1$
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);
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);
LinkInfo info = validator.validateLink(element, urltext,
"", config, "area"); //$NON-NLS-1$ //$NON-NLS-2$
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);
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(MethodElement element, File from, File to, boolean recursive) {
//
// ContentResourceScanner scanner = new ContentResourceScanner(from, to, );
// scanner.setTargetRootPath(to);
// scanner.copyResources(element);
//
// if ( recursive ) {
// for ( Iterator it = element.eAllContents(); it.hasNext(); ) {
// Object obj = it.next();
// if ( obj instanceof MethodElement ) {
// scanner.copyResources((MethodElement)obj);
// }
// }
// }
// }
public static String getPluginPath(MethodElement e) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
return getFolderAbsolutePath(plugin);
}
public static String getPluginPath(MethodPlugin plugin) {
return getFolderAbsolutePath(plugin);
}
}