完善看板展示逻辑

This commit is contained in:
datagear 2019-12-23 20:20:43 +08:00
parent c1ccac0f84
commit 837d110272
23 changed files with 512 additions and 151 deletions

View File

@ -19,6 +19,13 @@ import java.io.InputStream;
*/
public interface Icon
{
/**
* 获取图标类型{@code png}{@code jpeg}未知则返回空字符串
*
* @return
*/
String getType();
/**
* 获取图标输入流
*
@ -26,4 +33,11 @@ public interface Icon
* @throws IOException
*/
InputStream getInputStream() throws IOException;
/**
* 获取上次修改时间
*
* @return
*/
long getLastModified();
}

View File

@ -14,6 +14,7 @@ import java.io.IOException;
import java.io.InputStream;
import org.datagear.analysis.Icon;
import org.datagear.util.FileUtil;
import org.datagear.util.IOUtil;
/**
@ -24,16 +25,33 @@ import org.datagear.util.IOUtil;
*/
public class BytesIcon implements Icon
{
private String type;
private byte[] bytes;
private long lastModified;
public BytesIcon()
{
}
public BytesIcon(byte[] bytes)
public BytesIcon(String type, byte[] bytes, long lastModified)
{
super();
this.type = type;
this.bytes = bytes;
this.lastModified = lastModified;
}
@Override
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public byte[] getBytes()
@ -46,6 +64,17 @@ public class BytesIcon implements Icon
this.bytes = bytes;
}
@Override
public long getLastModified()
{
return lastModified;
}
public void setLastModified(long lastModified)
{
this.lastModified = lastModified;
}
@Override
public InputStream getInputStream() throws IOException
{
@ -56,11 +85,12 @@ public class BytesIcon implements Icon
* 构建{@linkplain BytesIcon}
*
* @param bytes
* @param lastModified
* @return
*/
public static BytesIcon valueOf(byte[] bytes)
public static BytesIcon valueOf(String type, byte[] bytes, long lastModified)
{
return new BytesIcon(bytes);
return new BytesIcon(type, bytes, lastModified);
}
/**
@ -71,6 +101,19 @@ public class BytesIcon implements Icon
* @throws IOException
*/
public static BytesIcon valueOf(File file) throws IOException
{
return valueOf(FileUtil.getExtension(file), file);
}
/**
* 构建{@linkplain BytesIcon}
*
* @param type
* @param file
* @return
* @throws IOException
*/
public static BytesIcon valueOf(String type, File file) throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -83,7 +126,7 @@ public class BytesIcon implements Icon
IOUtil.close(out);
}
return new BytesIcon(out.toByteArray());
return new BytesIcon(type, out.toByteArray(), file.lastModified());
}
/**
@ -92,24 +135,28 @@ public class BytesIcon implements Icon
* 它不会关闭{@code in}输入流
* </p>
*
* @param type
* @param in
* @param lastModified
* @return
* @throws IOException
*/
public static BytesIcon valueOf(InputStream in) throws IOException
public static BytesIcon valueOf(String type, InputStream in, long lastModified) throws IOException
{
return valueOf(in, false);
return valueOf(type, in, lastModified, false);
}
/**
* 构建{@linkplain BytesIcon}
*
* @param type
* @param in
* @param lastModified
* @param closeIn
* @return
* @throws IOException
*/
public static BytesIcon valueOf(InputStream in, boolean closeIn) throws IOException
public static BytesIcon valueOf(String type, InputStream in, long lastModified, boolean closeIn) throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -125,6 +172,6 @@ public class BytesIcon implements Icon
IOUtil.close(out);
}
return new BytesIcon(out.toByteArray());
return new BytesIcon(type, out.toByteArray(), lastModified);
}
}

View File

@ -7,10 +7,12 @@
*/
package org.datagear.analysis.support;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.datagear.analysis.Icon;
import org.datagear.util.FileUtil;
/**
* 位置图标
@ -22,6 +24,10 @@ public class LocationIcon extends LocationResource implements Icon
{
private static final long serialVersionUID = 1L;
private String type = "";
private long lastModified = System.currentTimeMillis();
public LocationIcon()
{
}
@ -29,6 +35,38 @@ public class LocationIcon extends LocationResource implements Icon
public LocationIcon(String location)
{
super(location);
this.type = FileUtil.getExtension(location);
}
@Override
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
@Override
public long getLastModified()
{
String location = getLocation();
if (LocationResource.isFileLocation(location))
{
File file = getLocationFile(location);
return file.lastModified();
}
else
return lastModified;
}
public void setLastModified(long lastModified)
{
this.lastModified = lastModified;
}
@Override

View File

@ -73,10 +73,7 @@ public class LocationResource implements Serializable
{
if (location.startsWith(PREFIX_FILE))
{
location = location.substring(PREFIX_FILE.length());
File file = new File(location);
File file = getLocationFile(location);
return new FileInputStream(file);
}
else if (location.startsWith(PREFIX_CLASSPATH))
@ -89,6 +86,15 @@ public class LocationResource implements Serializable
throw new UnsupportedOperationException("Location [" + location + "] is not supported");
}
protected File getLocationFile(String fileLocation)
{
location = location.substring(PREFIX_FILE.length());
File file = new File(location);
return file;
}
/**
* 是否是文件路径位置
*

View File

@ -113,17 +113,31 @@ public abstract class AbstractHtmlScriptObjectWriter
}
/**
* {@linkplain HtmlRenderContext}
* 仅有{@linkplain #getContextPath()}{@linkplain HtmlRenderContext}
*
* @author datagear@163.com
*
*/
protected static class EmptyHtmlRenderContext extends AbstractRenderContext implements HtmlRenderContext
protected static class OnlyContextPathHtmlRenderContext extends AbstractRenderContext implements HtmlRenderContext
{
public EmptyHtmlRenderContext()
private String contextPath;
public OnlyContextPathHtmlRenderContext(HtmlRenderContext renderContext)
{
super();
super.setAttributes(null);
this.contextPath = renderContext.getContextPath();
}
@Override
public String getContextPath()
{
return contextPath;
}
public void setContextPath(String contextPath)
{
this.contextPath = contextPath;
}
@Override
@ -150,12 +164,6 @@ public abstract class AbstractHtmlScriptObjectWriter
throw new UnsupportedOperationException();
}
@Override
public String getContextPath()
{
return "";
}
@Override
public Writer getWriter()
{
@ -212,7 +220,7 @@ public abstract class AbstractHtmlScriptObjectWriter
@Override
public String getContextPath()
{
return "";
return null;
}
@Override
@ -295,7 +303,7 @@ public abstract class AbstractHtmlScriptObjectWriter
@Override
public String getContextPath()
{
return "";
return null;
}
@Override

View File

@ -309,7 +309,7 @@ public class HtmlChartPlugin<T extends HtmlRenderContext> extends AbstractChartP
+ BUILTIN_CHART_ELEMENT_STYLE_NAME
+ (StringUtil.isEmpty(this.elementStyleName) ? "" : " " + this.elementStyleName) + "\">");
writer.write("</" + this.elementTagName + ">");
writer.write(this.newLine);
writeNewLine(writer);
}
catch (IOException e)
{
@ -333,29 +333,29 @@ public class HtmlChartPlugin<T extends HtmlRenderContext> extends AbstractChartP
if (!inScriptContext)
{
writeScriptStartTag(renderContext);
out.write(this.newLine);
writeNewLine(out);
}
out.write("var ");
out.write(chart.getVarName());
out.write("=");
out.write(this.newLine);
writeNewLine(out);
writeChartScriptObject(renderContext, chart);
out.write(";");
out.write(this.newLine);
writeNewLine(out);
writeChartScriptContent(renderContext, chart);
out.write(this.newLine);
writeNewLine(out);
if (!HtmlRenderAttributes.getChartScriptNotInvokeRender(renderContext))
{
out.write(chart.getVarName() + "." + this.scriptRenderFunctionName + "();");
out.write(this.newLine);
writeNewLine(out);
}
if (!inScriptContext)
{
writeScriptEndTag(renderContext);
out.write(this.newLine);
writeNewLine(out);
}
}
@ -396,7 +396,7 @@ public class HtmlChartPlugin<T extends HtmlRenderContext> extends AbstractChartP
while ((line = reader.readLine()) != null)
{
out.write(replaceChartRefPlaceholder(line, chartVarName));
out.write(this.newLine);
writeNewLine(out);
}
}
finally
@ -432,6 +432,17 @@ public class HtmlChartPlugin<T extends HtmlRenderContext> extends AbstractChartP
renderContext.getWriter().write("</script>");
}
/**
* 写换行符
*
* @param out
* @throws IOException
*/
protected void writeNewLine(Writer out) throws IOException
{
out.write(getNewLine());
}
/**
* 替换字符串中的图表名引用占位符为真是的图表变量名
*

View File

@ -318,7 +318,8 @@ public class HtmlChartPluginLoader
}
else
{
File tmpFile = File.createTempFile(HtmlChartPluginLoader.class.getSimpleName(), ".tmp");
File tmpFile = File.createTempFile(HtmlChartPluginLoader.class.getSimpleName(),
"." + FileUtil.getExtension(name));
IOUtil.write(in, tmpFile);
resourceFiles.put(name, tmpFile);
}
@ -416,10 +417,14 @@ public class HtmlChartPluginLoader
if (file == null || !file.exists())
return null;
String type = FileUtil.getExtension(file);
if (type == null)
type = "";
InputStream in = IOUtil.getInputStream(file);
byte[] bytes = IOUtil.readBytes(in, true);
return new BytesIcon(bytes);
return BytesIcon.valueOf(type, bytes, file.lastModified());
}
/**

View File

@ -15,11 +15,15 @@ import org.datagear.analysis.Chart;
import org.datagear.analysis.ChartPlugin;
import org.datagear.analysis.ChartProperties;
import org.datagear.analysis.ChartPropertyValues;
import org.datagear.analysis.DataSet;
import org.datagear.analysis.DataSetException;
import org.datagear.analysis.DataSetFactory;
import org.datagear.analysis.DataSetParamValues;
import org.datagear.analysis.Icon;
import org.datagear.analysis.RenderContext;
import org.datagear.analysis.RenderException;
import org.datagear.analysis.RenderStyle;
import org.datagear.analysis.support.AbstractDataSetFactory;
import org.datagear.util.StringUtil;
import org.datagear.util.i18n.Label;
@ -77,11 +81,6 @@ public class HtmlChartScriptObjectWriter extends AbstractHtmlScriptObjectWriter
*/
protected static class JsonHtmlChart extends HtmlChart
{
public JsonHtmlChart()
{
super();
}
public JsonHtmlChart(HtmlChart htmlChart)
{
this(htmlChart, null);
@ -93,18 +92,13 @@ public class HtmlChartScriptObjectWriter extends AbstractHtmlScriptObjectWriter
(StringUtil.isEmpty(chartRenderContextVarName)
? new AttributesHtmlRenderContext(htmlChart.getRenderContext())
: new RefHtmlRenderContext(chartRenderContextVarName)),
htmlChart.getPropertyValues(), htmlChart.getDataSetFactories(), htmlChart.getElementId(),
htmlChart.getVarName());
htmlChart.getPropertyValues(), JsonDataSetFactory.valuesOf(htmlChart.getDataSetFactories()),
htmlChart.getElementId(), htmlChart.getVarName());
}
}
protected static class IdChartPlugin extends AbstractIdentifiable implements ChartPlugin<RenderContext>
{
public IdChartPlugin()
{
super();
}
public IdChartPlugin(ChartPlugin<?> chartPlugin)
{
super(chartPlugin.getId());
@ -153,4 +147,33 @@ public class HtmlChartScriptObjectWriter extends AbstractHtmlScriptObjectWriter
throw new UnsupportedOperationException();
}
}
protected static class JsonDataSetFactory extends AbstractDataSetFactory
{
public JsonDataSetFactory(DataSetFactory dataSetFactory)
{
super(dataSetFactory.getId());
setParams(dataSetFactory.getParams());
setExports(dataSetFactory.getExports());
}
@Override
public DataSet getDataSet(DataSetParamValues dataSetParamValues) throws DataSetException
{
return null;
}
public static JsonDataSetFactory[] valuesOf(DataSetFactory[] dataSetFactories)
{
if (dataSetFactories == null)
return null;
JsonDataSetFactory[] jsonDataSetFactories = new JsonDataSetFactory[dataSetFactories.length];
for (int i = 0; i < dataSetFactories.length; i++)
jsonDataSetFactories[i] = new JsonDataSetFactory(dataSetFactories[i]);
return jsonDataSetFactories;
}
}
}

View File

@ -75,7 +75,7 @@ public class HtmlDashboardScriptObjectWriter extends AbstractHtmlScriptObjectWri
public JsonHtmlDashboard(HtmlDashboard dashboard, boolean renderContextEmpty)
{
super(dashboard.getId(), new IdDashboardWidget(dashboard.getWidget()),
(renderContextEmpty ? new EmptyHtmlRenderContext()
(renderContextEmpty ? new OnlyContextPathHtmlRenderContext(dashboard.getRenderContext())
: new AttributesHtmlRenderContext(dashboard.getRenderContext())),
Collections.EMPTY_LIST, dashboard.getVarName());
}

View File

@ -30,10 +30,10 @@ import org.datagear.analysis.support.ChartWidgetSource;
import org.datagear.analysis.support.SimpleDashboardThemeSource;
import org.datagear.analysis.support.TemplateDashboardWidgetResManager;
import org.datagear.util.FileUtil;
import org.datagear.util.Global;
import org.datagear.util.IDUtil;
import org.datagear.util.IOUtil;
import org.datagear.util.StringUtil;
import org.datagear.util.i18n.Label;
import freemarker.core.Environment;
import freemarker.ext.util.WrapperTemplateModel;
@ -120,9 +120,8 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
protected static final String KEY_HTML_DASHBOARD_RENDER_DATA_MODEL = HtmlDashboardRenderDataModel.class
.getSimpleName();
protected static final String CHART_PLUGIN_FOR_NOT_FOUND_SCRIPT = "(function(chart){"
+ "chart.render=function(){ document.getElementById(this.elementId).innerHTML='Not Found'; };"
+ "chart.update = function(){};" + "})($CHART);";
protected static final String RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT = StringUtil
.firstLowerCase(Global.PRODUCT_NAME_EN) + "RenderValueForNotFound";
/** "@import"指令的输出内容 */
private String importContent;
@ -142,8 +141,10 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
private HtmlDashboardScriptObjectWriter htmlDashboardScriptObjectWriter = new HtmlDashboardScriptObjectWriter();
private HtmlChartWidget<HtmlRenderContext> htmlChartWidgetForNotFound = new HtmlChartWidget<HtmlRenderContext>(
"htmlChartWidgetForNotFound", new HtmlChartPlugin<HtmlRenderContext>("htmlChartPluginForNotFound",
new Label("htmlChartPluginForNotFound"), CHART_PLUGIN_FOR_NOT_FOUND_SCRIPT));
StringUtil.firstLowerCase(Global.PRODUCT_NAME_EN) + "HtmlChartWidgetForNotFound",
new ValueHtmlChartPlugin<HtmlRenderContext>(
StringUtil.firstLowerCase(Global.PRODUCT_NAME_EN) + "HtmlChartPluginForNotFound",
RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT));
private String templateEncoding = "UTF-8";
@ -242,6 +243,16 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
this.htmlDashboardScriptObjectWriter = htmlDashboardScriptObjectWriter;
}
public HtmlChartWidget<HtmlRenderContext> getHtmlChartWidgetForNotFound()
{
return htmlChartWidgetForNotFound;
}
public void setHtmlChartWidgetForNotFound(HtmlChartWidget<HtmlRenderContext> htmlChartWidgetForNotFound)
{
this.htmlChartWidgetForNotFound = htmlChartWidgetForNotFound;
}
public String getTemplateEncoding()
{
return templateEncoding;
@ -468,17 +479,23 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
* 此方法不会返回{@code null}如果找不到指定ID的{@linkplain ChartWidget}它将返回
* </p>
*
* @param renderContext
* @param id
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected HtmlChartWidget<T> getHtmlChartWidgetForRender(String id)
protected HtmlChartWidget<HtmlRenderContext> getHtmlChartWidgetForRender(HtmlRenderContext renderContext, String id)
{
ChartWidget chartWidget = this.chartWidgetSource.getChartWidget(id);
if (chartWidget == null)
chartWidget = this.htmlChartWidgetForNotFound;
ChartWidget chartWidget = (StringUtil.isEmpty(id) ? null : this.chartWidgetSource.getChartWidget(id));
return (HtmlChartWidget<T>) chartWidget;
if (chartWidget == null)
{
chartWidget = this.htmlChartWidgetForNotFound;
renderContext.setAttribute(RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT,
"Chart '" + (id == null ? "" : id) + "' Not Found");
}
return (HtmlChartWidget<HtmlRenderContext>) chartWidget;
}
protected Object buildHtmlDashboardRenderDataModel(HtmlDashboardRenderDataModel dataModel)
@ -905,6 +922,8 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
HtmlRenderAttributes.removeChartVarName(renderContext);
HtmlRenderAttributes.removeChartElementId(renderContext);
renderContext.removeAttribute(RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT);
out.write("var ");
out.write(tmpRenderContextVar);
out.write("=");
@ -1027,14 +1046,13 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
String var = getStringParamValue(params, "var");
String elementId = getStringParamValue(params, "elementId");
if (StringUtil.isEmpty(widget))
throw new TemplateException("The [widget] attribute must be set", env);
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
HtmlDashboard htmlDashboard = dataModel.getHtmlDashboard();
HtmlRenderContext renderContext = htmlDashboard.getRenderContext();
int nextSequence = -1;
HtmlChartWidget<HtmlRenderContext> chartWidget = getHtmlChartWidgetForRender(renderContext, widget);
if (StringUtil.isEmpty(var))
{
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
@ -1047,14 +1065,12 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
elementId = HtmlRenderAttributes.generateChartElementId(nextSequence);
}
HtmlChartWidget<T> chartWidget = getHtmlChartWidgetForRender(widget);
HtmlRenderAttributes.setChartNotRenderScriptTag(renderContext, false);
HtmlRenderAttributes.setChartScriptNotInvokeRender(renderContext, true);
HtmlRenderAttributes.setChartVarName(renderContext, var);
HtmlRenderAttributes.setChartElementId(renderContext, elementId);
HtmlChart chart = chartWidget.render((T) renderContext);
HtmlChart chart = chartWidget.render(renderContext);
List<HtmlChart> charts = (List<HtmlChart>) htmlDashboard.getCharts();
if (charts == null)

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2018 datagear.tech. All Rights Reserved.
*/
/**
*
*/
package org.datagear.analysis.support.html;
import java.io.IOException;
import java.io.Writer;
import org.datagear.util.StringUtil;
import org.datagear.util.i18n.Label;
/**
* 仅渲染指定内容值的{@linkplain HtmlChartPlugin}
* <p>
* 它从{@linkplain HtmlRenderContext}中获取{@linkplain #getValueAttributeName()}的属性值并将其作为图表内容渲染
* </p>
*
* @author datagear@163.com
*
*/
public class ValueHtmlChartPlugin<T extends HtmlRenderContext> extends HtmlChartPlugin<T>
{
private String valueAttributeName;
public ValueHtmlChartPlugin()
{
super();
}
public ValueHtmlChartPlugin(String id, String valueAttributeName)
{
super(id, new Label("ValueHtmlChartPlugin"), "");
this.valueAttributeName = valueAttributeName;
}
public String getValueAttributeName()
{
return valueAttributeName;
}
public void setValueAttributeName(String valueAttributeName)
{
this.valueAttributeName = valueAttributeName;
}
@Override
protected void writeChartScriptContent(T renderContext, HtmlChart chart) throws IOException
{
String value = "";
Object valueObj = renderContext.getAttribute(this.valueAttributeName);
if (valueObj == null)
;
else if (valueObj instanceof String)
value = (String) valueObj;
else
value = valueObj.toString();
value = StringUtil.escapeJavaScriptStringValue(value);
Writer out = renderContext.getWriter();
String chartVarName = chart.getVarName();
out.write("(function(chart)");
writeNewLine(out);
out.write("{");
writeNewLine(out);
out.write(
" chart.render = function(){ var element = document.getElementById(this.elementId); element.innerHTML=\""
+ value + "\"; };");
writeNewLine(out);
out.write(" chart.update = function(){};");
writeNewLine(out);
out.write("})");
writeNewLine(out);
out.write("(" + chartVarName + ");");
}
}

View File

@ -11,6 +11,7 @@ import org.datagear.analysis.support.html.HtmlRenderContext;
import org.datagear.analysis.support.html.HtmlTplDashboardWidget;
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetRenderer;
import org.datagear.management.domain.HtmlTplDashboardWidgetEntity;
import org.datagear.management.domain.User;
/**
* {@linkplain HtmlTplDashboardWidgetEntity}业务服务接口
@ -31,8 +32,9 @@ public interface HtmlTplDashboardWidgetEntityService
/**
* 获取可用于执行分析的{@linkplain HtmlTplDashboardWidget}
*
* @param user
* @param id
* @return
*/
HtmlTplDashboardWidget<HtmlRenderContext> getHtmlTplDashboardWidget(String id);
HtmlTplDashboardWidget<HtmlRenderContext> getHtmlTplDashboardWidget(User user, String id);
}

View File

@ -86,9 +86,9 @@ public class HtmlTplDashboardWidgetEntityServiceImpl
}
@Override
public HtmlTplDashboardWidget<HtmlRenderContext> getHtmlTplDashboardWidget(String id)
public HtmlTplDashboardWidget<HtmlRenderContext> getHtmlTplDashboardWidget(User user, String id)
{
return getById(id);
return getById(user, id);
}
@Override

View File

@ -118,7 +118,7 @@ public class SqlDataSetFactoryEntityServiceImpl
for (SqlDataSetFactoryEntity entry : list)
postProcessSelect(entry);
SqlDataSetFactory[] array = new SqlDataSetFactory[list.size()];
SqlDataSetFactoryEntity[] array = new SqlDataSetFactoryEntity[list.size()];
list.toArray(array);
return array;

View File

@ -119,4 +119,72 @@ public class StringUtil
return sb.toString();
}
/**
* 转义HTML字符串
*
* @param s
* @return
*/
public static String escapeHtml(String s)
{
if (s == null || s.isEmpty())
return s;
StringBuilder sb = new StringBuilder();
char[] cs = s.toCharArray();
for (char c : cs)
{
if (c == '<')
sb.append("&lt;");
else if (c == '>')
sb.append("&gt;");
else if (c == '&')
sb.append("&amp;");
else if (c == '"')
sb.append("&quot;");
else
sb.append(c);
}
return sb.toString();
}
/**
* 转换为JavaScript语法的字符串
*
* @param s
* @return
*/
public static String escapeJavaScriptStringValue(String s)
{
if (s == null)
return "";
StringBuilder sb = new StringBuilder();
char[] cs = s.toCharArray();
for (char c : cs)
{
if (c == '\\')
sb.append("\\\\");
else if (c == '\'')
sb.append("\\\'");
else if (c == '"')
sb.append("\\\"");
else if (c == '\t')
sb.append("\\\t");
else if (c == '\n')
sb.append("\\\n");
else if (c == '\r')
sb.append("\\\r");
else
sb.append(c);
}
return sb.toString();
}
}

View File

@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
/**
* 数据集控制器
@ -112,13 +113,15 @@ public class ChartController extends AbstractController
public ResponseEntity<OperationMessage> saveAdd(HttpServletRequest request, HttpServletResponse response,
HtmlChartWidgetEntity chart)
{
User user = WebUtils.getUser(request, response);
checkSaveEntity(chart);
chart.setId(IDUtil.uuid());
chart.setCreateUser(WebUtils.getUser(request, response));
chart.setCreateUser(user);
chart.setSqlDataSetFactoryEntities(getSqlDataSetFactoryEntityParams(request));
this.htmlChartWidgetEntityService.add(chart);
this.htmlChartWidgetEntityService.add(user, chart);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@ -127,7 +130,12 @@ public class ChartController extends AbstractController
public String edit(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id)
{
HtmlChartWidgetEntity chart = this.htmlChartWidgetEntityService.getById(id);
User user = WebUtils.getUser(request, response);
HtmlChartWidgetEntity chart = this.htmlChartWidgetEntityService.getByIdForEdit(user, id);
if (chart == null)
throw new RecordNotFoundException();
List<HtmlChartPluginInfo> pluginInfos = getAllHtmlChartPluginInfos(request);
@ -144,11 +152,13 @@ public class ChartController extends AbstractController
public ResponseEntity<OperationMessage> saveEdit(HttpServletRequest request, HttpServletResponse response,
HtmlChartWidgetEntity chart)
{
User user = WebUtils.getUser(request, response);
checkSaveEntity(chart);
chart.setSqlDataSetFactoryEntities(getSqlDataSetFactoryEntityParams(request));
this.htmlChartWidgetEntityService.update(chart);
this.htmlChartWidgetEntityService.update(user, chart);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@ -157,7 +167,9 @@ public class ChartController extends AbstractController
public String view(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id)
{
HtmlChartWidgetEntity chart = this.htmlChartWidgetEntityService.getById(id);
User user = WebUtils.getUser(request, response);
HtmlChartWidgetEntity chart = this.htmlChartWidgetEntityService.getById(user, id);
if (chart == null)
throw new RecordNotFoundException();
@ -177,7 +189,13 @@ public class ChartController extends AbstractController
public ResponseEntity<OperationMessage> delete(HttpServletRequest request, HttpServletResponse response,
@RequestParam("id") String[] ids)
{
this.htmlChartWidgetEntityService.deleteByIds(ids);
User user = WebUtils.getUser(request, response);
for (int i = 0; i < ids.length; i++)
{
String id = ids[i];
this.htmlChartWidgetEntityService.deleteById(user, id);
}
return buildOperationMessageDeleteSuccessResponseEntity(request);
}
@ -214,7 +232,7 @@ public class ChartController extends AbstractController
}
@RequestMapping(value = "/pluginicon/{pluginId}", produces = CONTENT_TYPE_JSON)
public void getPluginIcon(HttpServletRequest request, HttpServletResponse response,
public void getPluginIcon(HttpServletRequest request, HttpServletResponse response, WebRequest webRequest,
@PathVariable("pluginId") String pluginId) throws Exception
{
ChartPlugin<?> chartPlugin = this.chartPluginManager.get(pluginId);
@ -228,7 +246,11 @@ public class ChartController extends AbstractController
if (icon == null)
throw new FileNotFoundException();
response.setContentType("image/png");
long lastModified = icon.getLastModified();
if (webRequest.checkNotModified(lastModified))
return;
response.setContentType("image/" + icon.getType());
OutputStream out = response.getOutputStream();
InputStream iconIn = null;

View File

@ -10,8 +10,10 @@ import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.datagear.analysis.RenderStyle;
import org.datagear.analysis.support.TemplateDashboardWidgetResManager;
import org.datagear.analysis.support.html.DefaultHtmlRenderContext;
import org.datagear.analysis.support.html.HtmlRenderAttributes;
import org.datagear.analysis.support.html.HtmlRenderContext;
import org.datagear.analysis.support.html.HtmlTplDashboardWidget;
import org.datagear.management.domain.HtmlTplDashboardWidgetEntity;
@ -20,6 +22,7 @@ import org.datagear.management.service.HtmlTplDashboardWidgetEntityService;
import org.datagear.persistence.PagingData;
import org.datagear.persistence.PagingQuery;
import org.datagear.util.IDUtil;
import org.datagear.util.StringUtil;
import org.datagear.web.OperationMessage;
import org.datagear.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -99,16 +102,19 @@ public class DashboardController extends AbstractController
HtmlTplDashboardWidgetEntity dashboard, @RequestParam("templateContent") String templateContent)
throws Exception
{
User user = WebUtils.getUser(request, response);
dashboard.setTemplate(HtmlTplDashboardWidgetEntity.DEFAULT_TEMPLATE);
checkSaveEntity(dashboard);
dashboard.setId(IDUtil.uuid());
dashboard.setCreateUser(WebUtils.getUser(request, response));
dashboard.setCreateUser(user);
this.htmlTplDashboardWidgetEntityService.add(dashboard);
boolean add = this.htmlTplDashboardWidgetEntityService.add(user, dashboard);
saveTemplateContent(dashboard, templateContent);
if (add)
saveTemplateContent(dashboard, templateContent);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@ -117,7 +123,12 @@ public class DashboardController extends AbstractController
public String edit(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id) throws Exception
{
HtmlTplDashboardWidgetEntity dashboard = this.htmlTplDashboardWidgetEntityService.getById(id);
User user = WebUtils.getUser(request, response);
HtmlTplDashboardWidgetEntity dashboard = this.htmlTplDashboardWidgetEntityService.getByIdForEdit(user, id);
if (dashboard == null)
throw new RecordNotFoundException();
model.addAttribute("dashboard", dashboard);
readAndSetTemplateContent(dashboard, model);
@ -133,13 +144,16 @@ public class DashboardController extends AbstractController
HtmlTplDashboardWidgetEntity dashboard, @RequestParam("templateContent") String templateContent)
throws Exception
{
User user = WebUtils.getUser(request, response);
dashboard.setTemplate(HtmlTplDashboardWidgetEntity.DEFAULT_TEMPLATE);
checkSaveEntity(dashboard);
this.htmlTplDashboardWidgetEntityService.update(dashboard);
boolean updated = this.htmlTplDashboardWidgetEntityService.update(user, dashboard);
saveTemplateContent(dashboard, templateContent);
if (updated)
saveTemplateContent(dashboard, templateContent);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@ -148,7 +162,9 @@ public class DashboardController extends AbstractController
public String view(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id) throws Exception
{
HtmlTplDashboardWidgetEntity dashboard = this.htmlTplDashboardWidgetEntityService.getById(id);
User user = WebUtils.getUser(request, response);
HtmlTplDashboardWidgetEntity dashboard = this.htmlTplDashboardWidgetEntityService.getById(user, id);
if (dashboard == null)
throw new RecordNotFoundException();
@ -166,7 +182,13 @@ public class DashboardController extends AbstractController
public ResponseEntity<OperationMessage> delete(HttpServletRequest request, HttpServletResponse response,
@RequestParam("id") String[] ids)
{
this.htmlTplDashboardWidgetEntityService.deleteByIds(ids);
User user = WebUtils.getUser(request, response);
for (int i = 0; i < ids.length; i++)
{
String id = ids[i];
this.htmlTplDashboardWidgetEntityService.deleteById(user, id);
}
return buildOperationMessageDeleteSuccessResponseEntity(request);
}
@ -207,8 +229,13 @@ public class DashboardController extends AbstractController
public void show(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@PathVariable("id") String id) throws Exception
{
User user = WebUtils.getUser(request, response);
HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget = this.htmlTplDashboardWidgetEntityService
.getHtmlTplDashboardWidget(id);
.getHtmlTplDashboardWidget(user, id);
if (dashboardWidget == null)
throw new RecordNotFoundException();
response.setCharacterEncoding(
this.htmlTplDashboardWidgetEntityService.getHtmlTplDashboardWidgetRenderer().getWriterEncoding());
@ -217,10 +244,26 @@ public class DashboardController extends AbstractController
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
renderContext.setContextPath(request.getContextPath());
HtmlRenderAttributes.setRenderStyle(renderContext, resolveRenderStyle(request));
dashboardWidget.render(renderContext);
}
protected RenderStyle resolveRenderStyle(HttpServletRequest request) throws Exception
{
String theme = WebUtils.getTheme(request);
if (StringUtil.isEmpty(theme))
return RenderStyle.LIGHT;
theme = theme.toLowerCase();
if (theme.indexOf("dark") > -1)
return RenderStyle.DARK;
return RenderStyle.LIGHT;
}
protected void checkSaveEntity(HtmlTplDashboardWidgetEntity dashboard)
{
if (isBlank(dashboard.getName()))

View File

@ -73,12 +73,14 @@ public class DataSetController extends AbstractController
public ResponseEntity<OperationMessage> saveAdd(HttpServletRequest request, HttpServletResponse response,
SqlDataSetFactoryEntity dataSet)
{
User user = WebUtils.getUser(request, response);
checkSaveEntity(dataSet);
dataSet.setId(IDUtil.uuid());
dataSet.setCreateUser(WebUtils.getUser(request, response));
dataSet.setCreateUser(user);
this.sqlDataSetFactoryEntityService.add(dataSet);
this.sqlDataSetFactoryEntityService.add(user, dataSet);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@ -87,7 +89,12 @@ public class DataSetController extends AbstractController
public String edit(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id)
{
SqlDataSetFactoryEntity dataSet = this.sqlDataSetFactoryEntityService.getById(id);
User user = WebUtils.getUser(request, response);
SqlDataSetFactoryEntity dataSet = this.sqlDataSetFactoryEntityService.getByIdForEdit(user, id);
if (dataSet == null)
throw new RecordNotFoundException();
model.addAttribute("dataSet", dataSet);
model.addAttribute(KEY_TITLE_MESSAGE_KEY, "dataSet.editDataSet");
@ -101,9 +108,11 @@ public class DataSetController extends AbstractController
public ResponseEntity<OperationMessage> saveEdit(HttpServletRequest request, HttpServletResponse response,
SqlDataSetFactoryEntity dataSet)
{
User user = WebUtils.getUser(request, response);
checkSaveEntity(dataSet);
this.sqlDataSetFactoryEntityService.update(dataSet);
this.sqlDataSetFactoryEntityService.update(user, dataSet);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@ -112,7 +121,9 @@ public class DataSetController extends AbstractController
public String view(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id)
{
SqlDataSetFactoryEntity dataSet = this.sqlDataSetFactoryEntityService.getById(id);
User user = WebUtils.getUser(request, response);
SqlDataSetFactoryEntity dataSet = this.sqlDataSetFactoryEntityService.getById(user, id);
if (dataSet == null)
throw new RecordNotFoundException();
@ -129,7 +140,13 @@ public class DataSetController extends AbstractController
public ResponseEntity<OperationMessage> delete(HttpServletRequest request, HttpServletResponse response,
@RequestParam("id") String[] ids)
{
this.sqlDataSetFactoryEntityService.deleteByIds(ids);
User user = WebUtils.getUser(request, response);
for (int i = 0; i < ids.length; i++)
{
String id = ids[i];
this.sqlDataSetFactoryEntityService.deleteById(user, id);
}
return buildOperationMessageDeleteSuccessResponseEntity(request);
}

View File

@ -11,7 +11,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ThemeResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
/**
@ -52,11 +51,8 @@ public class EnumThemeChangeInterceptor extends ThemeChangeInterceptor
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException
{
ThemeResolver themeResolver = RequestContextUtils.getThemeResolver(request);
if (themeResolver == null)
{
throw new IllegalStateException("No ThemeResolver found: not in a DispatcherServlet request?");
}
ThemeResolver themeResolver = WebUtils.getThemeResolver(request);
String newTheme = request.getParameter(getParamName());
if (newTheme != null)
{

View File

@ -19,6 +19,8 @@ import org.datagear.web.security.AuthUser;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.ThemeResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
/**
* Web工具集
@ -180,71 +182,32 @@ public class WebUtils
}
/**
* 转义HTML字符串
* 获取当前主题
*
* @param s
* @param request
* @return
* @throws IllegalStateException
*/
public static String escapeHtml(String s)
public static String getTheme(HttpServletRequest request) throws IllegalStateException
{
if (s == null || s.isEmpty())
return s;
StringBuilder sb = new StringBuilder();
char[] cs = s.toCharArray();
for (char c : cs)
{
if (c == '<')
sb.append("&lt;");
else if (c == '>')
sb.append("&gt;");
else if (c == '&')
sb.append("&amp;");
else if (c == '"')
sb.append("&quot;");
else
sb.append(c);
}
return sb.toString();
return getThemeResolver(request).resolveThemeName(request);
}
/**
* 转换为JavaScript语法的字符串
* 获取当前{@linkplain ThemeResolver}没有则抛出{@linkplain IllegalStateException}异常
*
* @param s
* @param request
* @return
* @throws IllegalStateException
*/
public static String escapeJavaScriptStringValue(String s)
public static ThemeResolver getThemeResolver(HttpServletRequest request) throws IllegalStateException
{
if (s == null)
return "";
ThemeResolver themeResolver = RequestContextUtils.getThemeResolver(request);
StringBuilder sb = new StringBuilder();
if (themeResolver == null)
throw new IllegalStateException("No ThemeResolver found: not in a DispatcherServlet request?");
char[] cs = s.toCharArray();
for (char c : cs)
{
if (c == '\\')
sb.append("\\\\");
else if (c == '\'')
sb.append("\\\'");
else if (c == '"')
sb.append("\\\"");
else if (c == '\t')
sb.append("\\\t");
else if (c == '\n')
sb.append("\\\n");
else if (c == '\r')
sb.append("\\\r");
else
sb.append(c);
}
return sb.toString();
return themeResolver;
}
/**

View File

@ -147,7 +147,7 @@ selectonly 是否选择操作允许为null
</#if>
var tableColumns = [
$.buildDataTablesColumnSimpleOption("<@spring.message code='id' />", "id", true),
$.buildDataTablesColumnSimpleOption("<@spring.message code='id' />", "id"),
$.buildDataTablesColumnSimpleOption($.buildDataTablesColumnTitleSearchable("<@spring.message code='chart.name' />"), "name"),
$.buildDataTablesColumnSimpleOption("<@spring.message code='chart.htmlChartPlugin' />", "htmlChartPlugin.id"),
$.buildDataTablesColumnSimpleOption($.buildDataTablesColumnTitleSearchable("<@spring.message code='chart.createUser' />"), "createUser.realName"),

View File

@ -32,7 +32,7 @@ readonly 是否只读操作允许为null
<label><@spring.message code='dashboard.template' /></label>
</div>
<div class="form-item-value">
<textarea name="templateContent">${templateContent!''?html}</textarea>
<textarea name="templateContent" class="ui-widget ui-widget-content">${templateContent!''?html}</textarea>
</div>
</div>
</div>

View File

@ -112,7 +112,7 @@ selectonly 是否选择操作允许为null
{
po.executeOnSelect(function(row)
{
po.open(po.url("show/"+row.id),{ target : "_blank"});
window.open(po.url("show/"+row.id), row.id);
});
});