| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // which accompanies this distribution, and is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // Contributors: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.library.layout; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.UnsupportedEncodingException; |
| import java.net.URLDecoder; |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.regex.Matcher; |
| |
| import org.eclipse.epf.common.utils.NetUtil; |
| import org.eclipse.epf.common.xml.XSLTProcessor; |
| import org.eclipse.epf.library.ILibraryManager; |
| import org.eclipse.epf.library.LibraryService; |
| import org.eclipse.epf.library.configuration.ConfigurationHelper; |
| import org.eclipse.epf.library.edit.util.MethodElementPropUtil; |
| import org.eclipse.epf.library.layout.util.XmlElement; |
| import org.eclipse.epf.library.layout.util.XmlHelper; |
| import org.eclipse.epf.library.persistence.ILibraryResourceSet; |
| import org.eclipse.epf.library.util.LibraryUtil; |
| import org.eclipse.epf.library.util.ResourceHelper; |
| import org.eclipse.epf.publish.layout.LayoutPlugin; |
| import org.eclipse.epf.uma.CustomCategory; |
| import org.eclipse.epf.uma.MethodConfiguration; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.MethodLibrary; |
| import org.eclipse.epf.uma.MethodPackage; |
| import org.eclipse.epf.uma.ProcessComponent; |
| |
| /** |
| * class to process an element link in the content |
| * |
| * @author Jinhua Xi |
| * @since 1.0 |
| */ |
| public class LinkInfo { |
| |
| public static final String LINK_ATTR_CLASS = "class"; //$NON-NLS-1$ |
| |
| public static final String LINK_ATTR_GUID = "guid"; //$NON-NLS-1$ |
| |
| public static final String LINK_ATTR_HREF = "href"; //$NON-NLS-1$ |
| |
| public static final String LINK_ATTR_KEY = "key"; //$NON-NLS-1$ |
| |
| public static final String LINK_ATTR_TEXT = "text"; //$NON-NLS-1$ |
| |
| public static final String LINK_ATTR_NAME = "name"; //$NON-NLS-1$ |
| |
| private String linkedText = ""; //$NON-NLS-1$ |
| |
| private MethodElement linkElement = null; |
| |
| private MethodElement ownerElement = null; |
| |
| private boolean isMissingReference = false; |
| |
| private Map<String, String> attributeMap = new LinkedHashMap<String, String>(); |
| |
| private IContentValidator validator; |
| |
| private String pubDir; |
| |
| private String tag; |
| |
| //Temp solution for getting around without having a libMgr during migration |
| //Should be removed when lib loaded during migration is registed with Lib service. |
| private static MethodLibrary library; |
| |
| /** |
| * constructor |
| * |
| * @param owner |
| * @param validator |
| * @param pubDir |
| */ |
| public LinkInfo(MethodElement owner, IContentValidator validator, |
| String pubDir, String tag) { |
| this.ownerElement = owner; |
| this.validator = validator; |
| this.pubDir = pubDir; |
| this.tag = tag; |
| } |
| |
| /** |
| * is this an element link? |
| * @return boolean |
| */ |
| public boolean isElementLink() { |
| return ResourceHelper.isElementLink(getElementLinkType()); |
| } |
| |
| /** |
| * get the element link type |
| * @return String |
| */ |
| public String getElementLinkType() { |
| return getAttribute(LINK_ATTR_CLASS); |
| } |
| |
| /** |
| * get the guid of the element link |
| * @return String |
| */ |
| public String getGuid() { |
| return getAttribute(LINK_ATTR_GUID); |
| } |
| |
| /** |
| * get the url of the link |
| * @return String |
| */ |
| public String getUrl() { |
| return getAttribute(LINK_ATTR_HREF); |
| } |
| |
| /** |
| * get the linked text |
| * @return String |
| */ |
| public String getLinkedText() { |
| return linkedText; |
| } |
| |
| /** |
| * get the linked element |
| * @return MethodElement |
| */ |
| public MethodElement getLinkedElement() { |
| return linkElement; |
| } |
| |
| /** |
| * get the html for the link. |
| * |
| * @param showBrokenLinks boolean true to show the broken link mark. false to show text only |
| * @return StringBuffer |
| */ |
| public StringBuffer getHtml(boolean showBrokenLinks) { |
| StringBuffer buffer = new StringBuffer(); |
| |
| if (isMissingReference && (pubDir != null)) { |
| String url = ""; //$NON-NLS-1$ |
| if (!showBrokenLinks) { |
| buffer.append(linkedText); |
| return buffer; |
| } |
| |
| url = getMissingElementUrl(); |
| buffer |
| .append("<img alt=\"\" src=\"" + ResourceHelper.getBackPath(ownerElement) + "images/no_rup.gif\"> "); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| setUrl(url); |
| } |
| |
| buffer.append("<" + tag); //$NON-NLS-1$ |
| |
| for (Iterator<Map.Entry<String, String>> it = attributeMap.entrySet().iterator(); it.hasNext();) { |
| Map.Entry<String, String> entry = it.next(); |
| String key = entry.getKey(); |
| String value = entry.getValue(); |
| if (LINK_ATTR_HREF.equals(key) |
| && (value == null || value.length() == 0)) { |
| continue; |
| } |
| |
| buffer.append(" ") //$NON-NLS-1$ |
| .append(entry.getKey()).append("=") //$NON-NLS-1$ |
| .append("\"").append(entry.getValue()).append("\""); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| buffer.append(">").append(linkedText).append("</" + tag + ">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| |
| return buffer; |
| } |
| |
| /** |
| * validate the link attributes |
| * @param attributes String the link attributes |
| * @param text String the linked text |
| * @param config MethodConfiguration |
| */ |
| public void validateLink(String attributes, String text, |
| MethodConfiguration config) { |
| this.linkedText = text; |
| |
| Matcher m2 = ResourceHelper.p_tag_attributes.matcher(attributes); |
| 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(); |
| } |
| |
| /* |
| * if (attrValue.startsWith("\"")) { attrValue = |
| * attrValue.substring(1); } if (attrValue.endsWith("\"")) { |
| * attrValue = attrValue.substring(0, attrValue.length() - 1); } |
| */ |
| |
| // GVT: Cannot Preview/Browse Description Tab when |
| // the CP contains chinese characters |
| // generated html from xslt got the href urls encoded. we don't want |
| // that make sure decode the url using "UTF-8" encoding |
| if (attrName.equals(LINK_ATTR_HREF)) { |
| try { |
| attrValue = decode(attrValue); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| attributeMap.put(attrName, attrValue); |
| } |
| |
| String guid = getGuid(); |
| if (guid == null) { |
| // check if the file contains guid, if yes, need to get the element |
| String url = getUrl(); |
| guid = ResourceHelper.getGuidFromFileName(url); |
| if (guid != null) { |
| setGuid(guid); |
| } |
| } |
| |
| validateElementUrl(config); |
| } |
| |
| protected String decode(String str) throws UnsupportedEncodingException { |
| if (NetUtil.isRawUrl(str)) { |
| return str; |
| } |
| |
| return URLDecoder.decode(str, "UTF-8"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * get attribute |
| * @param name |
| * @return String |
| */ |
| private String getAttribute(String name) { |
| return (String) attributeMap.get(name); |
| } |
| |
| /** |
| * set guid |
| * @param guid String |
| */ |
| private void setGuid(String guid) { |
| attributeMap.put(LINK_ATTR_GUID, guid); |
| } |
| |
| public void setUrl(String url) { |
| attributeMap.put(LINK_ATTR_HREF, url); |
| } |
| |
| private void validateElementUrl(MethodConfiguration config) { |
| String guid = getGuid(); |
| if (guid != null) { |
| MethodElement e = null; |
| e = getMethodElement(guid); |
| |
| // if process component, get show the process |
| if (e instanceof ProcessComponent) { |
| e = ((ProcessComponent) e).getProcess(); |
| } |
| |
| // 156474 - Process Package (either CP package or DP package) can |
| // not be linked in RTE |
| // don't show link for packages. |
| if (e instanceof MethodPackage || e instanceof MethodConfiguration |
| || e instanceof MethodLibrary) { |
| e = null; |
| // remove the link atytribute |
| setUrl(null); |
| return; |
| } |
| |
| if (e != null) { |
| if (config != null) { |
| MethodElement e1 = ConfigurationHelper |
| .getCalculatedElement(e, config); |
| if (e1 != null) { |
| if (! validator.showBrokenLinks() && validator.isDiscarded(ownerElement, null, e1)) { |
| isMissingReference = true; |
| validator.logMissingReference(ownerElement, e1); |
| } else { |
| e = e1; |
| } |
| } else { |
| isMissingReference = true; |
| validator.logMissingReference(ownerElement, e); |
| } |
| } |
| } else { |
| boolean toLog = true; |
| if (ownerElement instanceof CustomCategory) { |
| if (MethodElementPropUtil.getMethodElementPropUtil().isTransientElement(ownerElement)) { |
| toLog = false; |
| } |
| } |
| if (toLog) { |
| isMissingReference = true; |
| validator.logMissingReference(ownerElement, guid, linkedText); |
| } |
| } |
| |
| if (e != null) { |
| guid = e.getGuid(); |
| setGuid(guid); |
| String url = getUrl(); |
| |
| // url can be null, for example, an element link for |
| // presentation name, such as |
| // <a class="PresentationName" |
| // guid="{EE97A8CD-66CA-4A9B-9871-E3B94CCED528}">Project |
| // Manager</a> |
| // we only need to get the element from the guid |
| if (url != null) { |
| url = url.trim(); |
| if (!url.toLowerCase().startsWith( |
| ResourceHelper.URL_STR_JAVASCRIPT)) { |
| url = ResourceHelper.getUrl(e, ownerElement, |
| ResourceHelper.FILE_EXT_HTML, url); |
| setUrl(url); |
| } |
| } |
| |
| if (isElementLink() && !tag.equals("area")) { //$NON-NLS-1$ |
| String text = ResourceHelper.getLinkText(e, |
| getElementLinkType(), config); |
| if (text != null) { |
| // if null, can be used text, don't reset it |
| this.linkedText = text; |
| } |
| } |
| |
| if (validator.isDiscarded(ownerElement, IContentValidator.elementUrlFeature, e, config)) { |
| isMissingReference = true; |
| validator.logMissingReference(ownerElement, e); |
| e = null; // ignore the element since it's discarded |
| } |
| } |
| |
| this.linkElement = e; |
| |
| } |
| } |
| |
| public static MethodElement getMethodElement(String guid) { |
| MethodElement e; |
| ILibraryManager manager = LibraryService.getInstance() |
| .getCurrentLibraryManager(); |
| if (manager != null && getLibrary() == null) { |
| e = manager.getMethodElement(guid); |
| } else { |
| e = getMethodElement_(guid); |
| if (e == null && manager != null) { |
| e = manager.getMethodElement(guid); |
| } |
| } |
| return e; |
| } |
| |
| // private static final String MISSING_PAGES_XSL = "pages_not_installed/"; |
| // //$NON-NLS-1$ |
| private String getMissingElementUrl() { |
| if (!isMissingReference) { |
| return ""; //$NON-NLS-1$ |
| } |
| |
| String url = null; |
| |
| // if (linkElement == null) { |
| // // this is an invalid element, maybe deleted from the library |
| // // already |
| // url = ResourceHelper.MISSING_PAGES_FOLDER + getGuid() |
| // + ResourceHelper.FILE_EXT_HTML; |
| // } else { |
| // url = ResourceHelper.MISSING_PAGES_FOLDER |
| // + ResourceHelper.getFileName(linkElement, |
| // ResourceHelper.FILE_EXT_HTML); |
| // } |
| |
| url = ResourceHelper.MISSING_PAGES_FOLDER + "pages_not_installed" //$NON-NLS-1$ |
| + ResourceHelper.FILE_EXT_HTML; |
| |
| File f = new File(pubDir, url); |
| File dir = f.getParentFile(); |
| if (!dir.exists()) { |
| dir.mkdirs(); |
| } |
| |
| // if ( !f.exists() ) |
| { |
| // generate the html file |
| XmlElement xml = new XmlElement("Element"); //$NON-NLS-1$ |
| |
| |
| Locale locale = Locale.getDefault(); |
| String lang = locale.getLanguage(); |
| xml.setAttribute("lang", lang); //$NON-NLS-1$ |
| |
| |
| if (linkElement == null) { |
| xml.setAttribute("invalidLink", "true") //$NON-NLS-1$ //$NON-NLS-2$ |
| .setAttribute("guid", getGuid()) //$NON-NLS-1$ |
| .setAttribute("name", linkedText); //$NON-NLS-1$ |
| } else { |
| xml |
| .setAttribute("guid", getGuid()) //$NON-NLS-1$ |
| .setAttribute("type", linkElement.getType().getName()) //$NON-NLS-1$ |
| .setAttribute("name", linkElement.getName()) //$NON-NLS-1$ |
| .setAttribute( |
| "pluginName", LibraryUtil.getMethodPlugin(linkElement).getName()); //$NON-NLS-1$ |
| } |
| String xslPath = LayoutResources.getDefaultXslPath( |
| "page_not_installed", null); //$NON-NLS-1$ |
| saveHtml(xml, xslPath, f); |
| } |
| |
| return ResourceHelper.getBackPath(ownerElement).replace( |
| File.separatorChar, '/') |
| + url; |
| } |
| |
| /** |
| * save a html file |
| * @param xmlElement |
| * @param xsl_uri |
| * @param outputFile |
| * @deprecated this method id not used any more |
| */ |
| public void saveHtml(XmlElement xmlElement, String xsl_uri, File outputFile) { |
| try { |
| StringBuffer xml = new StringBuffer(); |
| xml.append(XmlHelper.XML_HEADER).append(xmlElement.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(xsl_uri, xml.toString(), xslParams, output); |
| output.flush(); |
| output.close(); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| private static MethodElement getMethodElement_(String guid) { |
| try { |
| if (getLibrary() == null) { |
| return null; |
| } |
| ILibraryResourceSet resourceSet = (ILibraryResourceSet) getLibrary() |
| .eResource().getResourceSet(); |
| if (resourceSet != null) { |
| return (MethodElement) resourceSet.getEObject(guid); |
| } |
| } catch (Throwable th) { |
| // Log error here |
| th.printStackTrace(); |
| } |
| return null; |
| } |
| |
| public static MethodLibrary getLibrary() { |
| return library; |
| } |
| |
| public static void setLibrary(MethodLibrary library) { |
| LinkInfo.library = library; |
| } |
| |
| } |