smartSegment

简介

smartSegment,是一个代码片段自动处理工具。在日常的开发工作中,我们常常需要全文分析文件内容,对满足要求的代码片段进行替换,包裹,追加等功能。

smartSegment正是这样的工具,扫描文件或者整个工程,进行内容扫描分析,然后进行内容处理。smartSegment基于molicode的进行流程编排,然后用groovy脚本进行代码片段查找过滤,以及片段处理保存。

groovy脚本接口

smartSegment 通过选中一个gsp(groovy template)脚本文件进行接口适配。利用groovy的动态编译特性和闭包的方便定义于使用。

groovy脚本需要实现的4个闭包:

segmentStartFinder 代码片段开始标记查询器;

segmentEndFinder 代码片段结束标记查询器;

segmentFilter 代码片段过滤器;

segmentProcess 代码片段处理器;

已有的智能代码片段

https://gitee.com/zhangshibin1987/molicode-smart-segment

这个代码为什么要存储到gitee 里面? 听说了么, github 受美国政府管控,哪天说不定不能访问了呢? 所以新仓库都移到 gitee里面去了。

示例代码

<%
    /**
     * 可以直接使用的内置对象:
     * jsonConfig 为前台录入的json参数转换后的对象;可以以json的方式直接读取;
     * scriptContext 为和molicode进行脚本传递的上下文;所有闭包必须在最后传递到scriptContext里面;
     * 工具类:
     * JSON(FastJSON 工具类)
     * StringUtils(apache commons 3), CollectionUtils(apache collections 4)
     * PubUtils, tableNameUtil 系统自带;
     */

    def jsonConfigLocal = jsonConfig;

    /**
     * 必须实现
     *
     * 代码片段开始查找器,返回true,意味着找到了开始行
     * 以行为单位逐行进行查找,参数为:
     * (String line, List<String> lineContentList, int lineIndex)
     * 其中 line 为当前行内容, lineContentList 为所有行内容, lineIndex 为行标(0开始)
     *
     */
    def segmentStartFinder = { line, lineContentList, lineIndex ->
        return line.contains(jsonConfigLocal['segmentStart']);
    }

    /**
     * 必须实现
     *
     * 代码片段结束查找器,返回true,意味着找到了结束行
     * 以行为单位逐行进行查找,参数为:
     * (String line, List<String> lineContentList, int lineIndex)
     * 其中 line 为当前行内容, lineContentList 为所有行内容, lineIndex 为行标(0开始)
     *
     */
    def segmentEndFinder = { line, lineContentList, lineIndex ->
        return line.contains(jsonConfigLocal['segmentEnd']);
    }

    /**
     * 可选实现,如果没有过滤器,只要在开始结束范围内的,均为满足条件的代码片段
     *
     * 代码片段过滤器,返回true,意味匹配,false以为不匹配;
     *
     * 参数为: (SegmentInfoBo segmentInfoBo)
     * SegmentInfoBo 对象暂未提供说明,请看原始代码;
     *
     */
    def segmentFilter = { segmentInfoBo ->
        def segmentContains = jsonConfigLocal['segmentContains'];
        if (segmentContains == null || segmentContains == '') {
            return true;
        }
        def originContent = segmentInfoBo.getOriginSegmentContent("")
        return originContent.contains(segmentContains);
    }

    /**
     * 必须实现
     *
     * 代码片段处理执行器,会按返回结果替换掉原来的代码片段;
     *
     * (SegmentInfoBo segmentInfoBo)
     * SegmentInfoBo 对象暂未提供说明,请看原始代码;
     *
     */
    def segmentProcess = { segmentInfoBo ->
        def originContent = segmentInfoBo.getOriginSegmentContent("")
        def replaceMap = jsonConfigLocal['replaceMap'];
        if (replaceMap == null || replaceMap.isEmpty()) {
            return originContent;
        }
        replaceMap.each { key, value ->
            originContent.replaceAll(key, value);
        }
        return originContent;
    }

    /**
     * 将以上处理器传递给molicode进行运算处理;
     */
    scriptContext['segmentStartFinder'] = segmentStartFinder;
    scriptContext['segmentEndFinder'] = segmentEndFinder;
    scriptContext['segmentFilter'] = segmentFilter;
    scriptContext['segmentProcess'] = segmentProcess;

%>
说明:用于进行常用的文本替换功能。smartSegment脚本初始化成功!
需要配合jsonConfig使用;
author: david
version: 1.0

segmentInfoBo 对象说明

这个作者很懒,不想码那么多字,所以这里直接show code了,能干啥自己看看代码吧。

package com.shareyi.molicode.common.bo

import com.google.common.collect.Lists
import com.shareyi.molicode.sdk.dto.ExtAttrDto

/**
 * 片段信息业务对象
 */
class SegmentInfoBo extends ExtAttrDto{

    /**
     * 片段line堆栈
     */
    List<String> segmentLineStack = Lists.newArrayList();

    /**
     * 全部文件的文档内容,指向对象
     */
    transient List<String> lineContentList;
    /**
     * 片段开始的行号
     */
    int startLineIndex;
    /**
     * 片段结束的行号
     */
    int endLineIndex;

    /**
     * 获取原样字符串
     * @param prepend
     * @return
     */
    String getOriginSegmentContent(String prepend) {
        def sb = new StringBuilder();
        for (int index = 0; index < segmentLineStack.size(); index++) {
            String line = segmentLineStack.get(index);
            if (index != 0) {
                sb.append("\n");
            }
            //前置内容
            if (prepend != null && prepend.length() > 0) {
                sb.append(prepend);
            }
            sb.append(line);
        }
        return sb.toString();
    }

    /**
     * 通过行下标获取原文档中的内容
     * @param lineIndex
     * @return
     */
    String getOriginContentByLine(int lineIndex) {
        if (lineIndex >= lineContentList.size()) {
            return null;
        }
        return lineContentList.get(lineIndex);
    }

    /**
     * 通过相对坐标获取内容
     *
     * @param relativeIndex
     * @return
     */
    String getLineByRelativeIndex(int relativeIndex) {
        int lineIndex = 0;
        //不能取当前行
        if (relativeIndex == 0) {
            return null;
        }
        if (relativeIndex < 0) {
            lineIndex = startLineIndex + relativeIndex;
        } else {
            lineIndex = endLineIndex + relativeIndex;
        }

        if (lineIndex >= 0 && lineIndex < lineContentList.size()) {
            return lineContentList.get(lineIndex);
        }
        return null;
    }

    /**
     * 构建
     * @param strings
     * @param i
     * @return
     */
    static SegmentInfoBo create(List<String> lineContentList, int startLineIndex) {
        SegmentInfoBo segmentInfoBo = new SegmentInfoBo();
        segmentInfoBo.lineContentList = lineContentList;
        segmentInfoBo.startLineIndex = startLineIndex;
        return segmentInfoBo
    }


}