This is an automated email from the ASF dual-hosted git repository.
jamesyong pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git The following commit(s) were added to refs/heads/trunk by this push: new ad2e8de Improved: Open FTL File from browser (OFBIZ-12018) ad2e8de is described below commit ad2e8de7c2e09d41955e7eafb59dbb6d2984f138 Author: James Yong <[hidden email]> AuthorDate: Thu Sep 24 21:36:24 2020 +0800 Improved: Open FTL File from browser (OFBIZ-12018) Add function to open the corresponding FTL file with IDE when the named border is clicked from browser. Thanks Rishi and Jacques for review --- .../java/org/apache/ofbiz/base/util/UtilHtml.java | 2 ++ .../java/org/apache/ofbiz/common/CommonEvents.java | 38 ++++++++++++++++++++++ .../common/webcommon/WEB-INF/common-controller.xml | 7 ++++ framework/widget/config/widget.properties | 14 +++++++- .../org/apache/ofbiz/widget/model/HtmlWidget.java | 13 ++++++-- .../org/apache/ofbiz/widget/model/ModelWidget.java | 9 ++--- .../widget/renderer/html/HtmlWidgetRenderer.java | 18 +++++++--- .../webapp/common/js/util/OfbizUtil.js | 14 ++++++++ 8 files changed, 103 insertions(+), 12 deletions(-) diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHtml.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHtml.java index 5265304..4ca2e17 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHtml.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHtml.java @@ -125,11 +125,13 @@ public final class UtilHtml { String pluginPathKey = File.separator + "plugins" + File.separator; for (File xmlTheme : xmlThemes) { String path = xmlTheme.toURI().toURL().toString(); + // get the path after themes or plugins folders if (path.indexOf(themePathKey) > 0) { path = path.substring(path.indexOf(themePathKey) + 8); } else if (path.indexOf(pluginPathKey) > 0) { path = path.substring(path.indexOf(pluginPathKey) + 9); } + // get folder name path = path.substring(0, path.indexOf(File.separator)); if (!path.contains("common-theme") && !path.contains("ecommerce")) { visualThemeBasePathsName.add(File.separator + path + File.separator); diff --git a/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java b/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java index 3ecf80b..6313fbf 100644 --- a/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java +++ b/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java @@ -24,9 +24,12 @@ import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -42,17 +45,20 @@ import javax.servlet.http.HttpSession; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.apache.ofbiz.base.lang.JSON; +import org.apache.ofbiz.base.location.FlexibleLocation; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.UtilGenerics; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilProperties; import org.apache.ofbiz.base.util.UtilValidate; +import org.apache.ofbiz.base.util.string.FlexibleStringExpander; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.GenericEntityException; import org.apache.ofbiz.entity.GenericValue; import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.ofbiz.webapp.control.JWTManager; import org.apache.ofbiz.webapp.control.LoginWorker; +import org.apache.ofbiz.widget.model.ModelWidget; import org.apache.ofbiz.widget.model.MultiBlockHtmlTemplateUtil; import org.apache.ofbiz.widget.model.ThemeFactory; import org.apache.ofbiz.widget.renderer.VisualTheme; @@ -444,4 +450,36 @@ public class CommonEvents { return "success"; } + public static String openSourceFile(HttpServletRequest request, HttpServletResponse response) { + ModelWidget.NamedBorderType namedBorderType = ModelWidget.widgetNamedBorderEnabled(); + if (namedBorderType == ModelWidget.NamedBorderType.SOURCE) { + String sourceLocation = request.getParameter("sourceLocation"); + if (UtilValidate.isNotEmpty(sourceLocation) && sourceLocation.startsWith("component:")) { + try { + // find absolute path of file + URL sourceFileUrl = FlexibleLocation.resolveLocation(sourceLocation); + String location = sourceFileUrl.getFile(); + // prepare content map for string expansion + Map<String, Object> sourceMap = new HashMap<>(); + sourceMap.put("sourceLocation", location); + // get command to run + String cmdTemplate = UtilProperties.getPropertyValue("widget", "widget.dev.cmd.openSourceFile"); + String cmd = (String) FlexibleStringExpander.getInstance(cmdTemplate).expand(sourceMap); + // run command + Process process = Runtime.getRuntime().exec(String.format(cmd, location)); + // print result + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line = ""; + while ((line = reader.readLine()) != null) { + Debug.logInfo(line, MODULE); + } + return "success"; + } catch (IOException e) { + Debug.logError(e, MODULE); + } + } + } + return "error"; + } + } diff --git a/framework/common/webcommon/WEB-INF/common-controller.xml b/framework/common/webcommon/WEB-INF/common-controller.xml index a2dd12a..36b10c9 100644 --- a/framework/common/webcommon/WEB-INF/common-controller.xml +++ b/framework/common/webcommon/WEB-INF/common-controller.xml @@ -336,6 +336,13 @@ under the License. <response name="error" type="request" value="json"/> </request-map> + <request-map uri="openSourceFile"> + <security https="false" auth="false"/> + <event type="java" path="org.apache.ofbiz.common.CommonEvents" invoke="openSourceFile"/> + <response name="success" type="none" /> + <response name="error" type="none" /> + </request-map> + <!--========================== AJAX events =====================--> <!-- View Mappings --> diff --git a/framework/widget/config/widget.properties b/framework/widget/config/widget.properties index 306fb31..8d7a446 100644 --- a/framework/widget/config/widget.properties +++ b/framework/widget/config/widget.properties @@ -28,7 +28,19 @@ widget.verbose=true # Enable widget named border for development -widget.dev.namedBorder=true +# NONE - For production where no named border will be shown. +# LABEL - Show named border +# SOURCE - Show named border with link to open the source code +widget.dev.namedBorder=NONE + +# Command template to open file with editor +# Linux: +# idea ${sourceLocation} +# eclipse --launcher.openFile ${sourceLocation} +# Windows: +# idea.exe ${sourceLocation} +# eclipse.exe --launcher.openFile ${sourceLocation} +widget.dev.cmd.openSourceFile=idea ${sourceLocation} # Default number of items to be displayed per page in a list form widget.form.defaultViewSize=20 diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java index 3cd8e5f..c75c06f 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java @@ -167,9 +167,16 @@ public class HtmlWidget extends ModelScreenWidget { if (insertWidgetBoundaryComments) { writer.append(HtmlWidgetRenderer.buildBoundaryComment("Begin", "Template", location)); } - boolean insertWidgetNamedBorder = !location.endsWith(".fo.ftl") && ModelWidget.widgetNamedBorderEnabled(); + boolean insertWidgetNamedBorder = false; + NamedBorderType namedBorderType = null; + if (!location.endsWith(".fo.ftl")) { + namedBorderType = ModelWidget.widgetNamedBorderEnabled(); + if (namedBorderType != NamedBorderType.NONE) { + insertWidgetNamedBorder = true; + } + } if (insertWidgetNamedBorder) { - writer.append(HtmlWidgetRenderer.buildNamedBorder("Begin", "Template", location)); + writer.append(HtmlWidgetRenderer.buildNamedBorder("Begin", "Template", location, namedBorderType)); } Template template = null; @@ -181,7 +188,7 @@ public class HtmlWidget extends ModelScreenWidget { FreeMarkerWorker.renderTemplate(template, context, writer); if (insertWidgetNamedBorder) { - writer.append(HtmlWidgetRenderer.buildNamedBorder("End", "Template", location)); + writer.append(HtmlWidgetRenderer.buildNamedBorder("End", "Template", location, namedBorderType)); } if (insertWidgetBoundaryComments) { writer.append(HtmlWidgetRenderer.buildBoundaryComment("End", "Template", location)); diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidget.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidget.java index 8630fd1..9393d7a 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidget.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidget.java @@ -39,6 +39,7 @@ public abstract class ModelWidget implements Serializable { * set to "widgetVerbose". */ public static final String ENABLE_BOUNDARY_COMMENTS_PARAM = "widgetVerbose"; + public enum NamedBorderType { NONE, LABEL, SOURCE } private final String name; private final String systemId; @@ -152,10 +153,10 @@ public abstract class ModelWidget implements Serializable { } /** - * Returns <code>true</code> if showing filename and border on the rendered part of the template. - * @return true if <code>widget.dev.namedBorder</code> is set to <code>true</code> + * determine how to display named border for development + * @return NamedBorderType from <code>widget.dev.namedBorder</code> property */ - public static boolean widgetNamedBorderEnabled() { - return "true".equals(UtilProperties.getPropertyValue("widget", "widget.dev.namedBorder")); + public static NamedBorderType widgetNamedBorderEnabled() { + return NamedBorderType.valueOf(UtilProperties.getPropertyValue("widget", "widget.dev.namedBorder", NamedBorderType.NONE.toString())); } } diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java index 0b89029..e79a718 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java @@ -75,16 +75,26 @@ public class HtmlWidgetRenderer { return "<!-- " + boundaryType + " " + widgetType + " " + widgetName + " -->" + WHITE_SPACE; } - public static String buildNamedBorder(String boundaryType, String widgetType, String widgetName) { + public static String buildNamedBorder(String boundaryType, String widgetType, String widgetName, ModelWidget.NamedBorderType namedBorderType) { List<String> themeBasePathsToExempt = UtilHtml.getVisualThemeFolderNamesToExempt(); if (!themeBasePathsToExempt.stream().anyMatch(widgetName::contains)) { // add additional visual label for non-theme ftl switch (boundaryType) { case "End": String fileName = widgetName.substring(widgetName.lastIndexOf(File.separator) + 1); - return "</div><div class='info-overlay'><span class='info-overlay-item'>" - + fileName - + "</span></div></div>"; + switch (namedBorderType) { + case SOURCE: + return "</div><div class='info-overlay'><span class='info-overlay-item'><a href='#' data-source='" + + widgetName + + "'>" + + fileName + + "</a></span></div></div>"; + case LABEL: + return "</div><div class='info-overlay'><span class='info-overlay-item'>" + + fileName + + "</span></div></div>"; + default: return ""; + } default: return "<div class='info-container'><div class='info-content'>"; } diff --git a/themes/common-theme/webapp/common/js/util/OfbizUtil.js b/themes/common-theme/webapp/common/js/util/OfbizUtil.js index c59fc35..11b4ab3 100644 --- a/themes/common-theme/webapp/common/js/util/OfbizUtil.js +++ b/themes/common-theme/webapp/common/js/util/OfbizUtil.js @@ -44,14 +44,28 @@ $(document).ready(function() { bindObservers("body"); function initNamedBorder() { + jQuery("[data-source]").off(); // fadeout info-overlay labels setTimeout(function(){ $('.info-overlay').fadeOut(1000, function(){ + jQuery("[data-source]").off(); $('.info-container').contents().unwrap(); $('.info-content').contents().unwrap(); $('.info-overlay').delay(1000).remove(); }); }, 3000); + // clickable link in named border to open source file + jQuery("[data-source]").click(function(){ + var sourceLocaton = jQuery(this).data("source"); + jQuery.ajax({ + url: 'openSourceFile', + type: "POST", + data: {sourceLocation:sourceLocaton}, + success: function(data) { + alert("Command is sent to open source file with your IDE"); + } + }); + }); } initNamedBorder(); }); |
Free forum by Nabble | Edit this page |