| //------------------------------------------------------------------------------ |
| // 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.Locale; |
| 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.I18nUtil; |
| 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.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) { |
| String xslPath = null; |
| |
| if ((LAYOUT_XSL_ROOT_PATH == null) |
| || (LAYOUT_XSL_ROOT_PATH.equals(""))) {//$NON-NLS-1$ |
| LAYOUT_XSL_ROOT_PATH = BrowsingLayoutSettings.INSTANCE.getXslPath() |
| .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 key = type.substring(0, 1).toLowerCase() |
| + type.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(text, '\\'); |
| 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(LibraryPlugin.getDefault().getLayoutPath(), |
| filePath); |
| } |
| |
| // if the filePath is relative to the pub root, fix the target path |
| if ( 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); |
| |
| 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 = 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() |
| * |
| * 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); |
| } |
| |
| |
| |
| } |