yangys
2025-09-20 fcee672452c02cc29e0e17ebc27a8c51698c6d0d
优化程序注释
已修改11个文件
262 ■■■■■ 文件已修改
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/contants/RegExpConstants.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/TaskDispatchService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/ReceiveFileCheckService.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/MdmProgramImportService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeAutoCreateService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeHisService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/FanucProcessor.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/commons/contants/RegExpConstantsTest.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/contants/RegExpConstants.java
@@ -8,4 +8,7 @@
     * 程序文件名 正则
     */
    public static final Pattern PROGRAM_FILE_PATTERN = Pattern.compile("^[0-9a-zA-Z_\\-]+\\-[0-9a-zA-Z]+-[0-9a-zA-Z]+\\-\\d+\\-\\d+\\.*[a-zA-Z]*$");
    //public static final Pattern PROGRAM_PACKAGE_PATTERN = Pattern.compile("[\\w\\-]+\\-\\w+\\-\\w+");
    public static final Pattern PROGRAM_PACKAGE_PATTERN = Pattern.compile("([\\w\\-]+)\\-\\w+\\-\\w+");
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java
@@ -131,7 +131,7 @@
        if(vars.getOrDefault(FlowVariableConstant.IS_TEMP_FLOW, FlowConstant.N).equals(FlowConstant.Y)){
            myProcessName = "试切补充流程";
        }else if(StringUtils.isNotBlank(startVO.getDeviation()) ){
            myProcessName = "偏离单";
            myProcessName = "临时更改单";
        }else if(vars.getOrDefault(FlowVariableConstant.HAS_CURED_PROGRAM, FlowConstant.N).equals(FlowConstant.Y)){
            myProcessName = "固化下发流程";
        }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/TaskDispatchService.java
@@ -4,12 +4,15 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.flow.entity.TaskDispatch;
import org.springblade.mdm.flow.mapper.TaskDispatchMapper;
import org.springblade.mdm.flow.vo.TaskAssignVO;
import org.springblade.mdm.program.entity.DrawingNos;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.entity.NcNodeHis;
import org.springblade.mdm.program.mapper.DrawingNosMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -134,7 +137,30 @@
        return opt.orElse(null);
    }
    /**
     * 根据程序内部编号获取实体
     * @param programNo 内部编号
     * @return 实体
     */
    public TaskDispatch getByProgramNo(String programNo) {
        return lambdaQuery().eq(TaskDispatch::getProgramNo, programNo).one();
    }
    /**
     * 查询偏离单的序号
     * @param programNo 偏离单的程序包名节点
     * @return 序号
     */
    public long getDeviationSerial(String programNo) {
        TaskDispatch dispatch = this.getByProgramNo(programNo);
        return lambdaQuery()
            .eq(TaskDispatch::getDrawingNo,dispatch.getDrawingNo())
            .eq(TaskDispatch::getProcessNo,dispatch.getProcessNo())
            .eq(TaskDispatch::getProcessEdition,dispatch.getProcessEdition())
            .eq(TaskDispatch::getDeviation,dispatch.getDeviation())
            .le(TaskDispatch::getCreateTime,dispatch.getCreateTime())  //时间小于等于当前节点
            .count();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/ReceiveFileCheckService.java
@@ -108,14 +108,22 @@
                            byteStream.reset();
                            //AnnotationProcessor processor = annoProcessHelper.getProcessor(machine.getControlSystem());
                            String lgLine = FileContentUtil.readLineAt(byteStream,annoProps.getDeviationLineIndex());
                            String textWithoutAnno = AnnotationUtil.removeAnnotation(machine.getControlSystem(),lgLine,programAnnotationService.getAnnotionDictList());
                            String[] strArr = Func.split(textWithoutAnno,":");//临时更改单是冒号分隔,后面是单号
                            String planStatusLine = AnnotationUtil.removeAnnotation(machine.getControlSystem(),FileContentUtil.readLineAt(byteStream,annoProps.getStatusLineIndex()),programAnnotationService.getAnnotionDictList());
                            String lgNo;//更改单号
                            if(AnnotationUtil.LG.equals(planStatusLine)) {//是更改单
                                String lgLine = FileContentUtil.readLineAt(byteStream, annoProps.getDeviationLineIndex());
                                lgNo = AnnotationUtil.removeAnnotation(machine.getControlSystem(), lgLine, programAnnotationService.getAnnotionDictList());
                            }else{
                                lgNo = null;
                            }
                            long progOnMachineCount = programOnMachineService.lambdaQuery()
                                .eq(ProgramOnMachine::getDrawingNo,progNameVO.getDrawingNo())
                                .eq(ProgramOnMachine::getProcessNo,progNameVO.getProcessNo())
                                .eq(ProgramOnMachine::getProcessEdition,progNameVO.getProcessEdition())
                                .eq(strArr.length==2,ProgramOnMachine::getDeviation,strArr[1])//临时更改单匹配
                                .eq(lgNo != null,ProgramOnMachine::getDeviation,lgNo)//临时更改单匹配
                                .eq(ProgramOnMachine::getMachineCode,machineFile.getMachineCode()).count();
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java
@@ -18,6 +18,9 @@
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.producedivision.entity.QinzheFgb;
import org.springblade.mdm.basesetting.producedivision.service.QinzheFgbService;
import org.springblade.mdm.commons.contants.RegExpConstants;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.service.CureFlowService;
@@ -31,6 +34,7 @@
import org.springblade.mdm.program.vo.DncSendBackFile;
import org.springblade.mdm.program.vo.ProgramAnnotation;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.mdm.utils.ProgramFileNameParser;
import org.springblade.mdm.utils.ZipTextFileContentUtil;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.stereotype.Service;
@@ -43,6 +47,8 @@
import java.nio.file.StandardOpenOption;
import java.time.Duration;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -56,7 +62,7 @@
@AllArgsConstructor
public class DNCSendBackService extends BizServiceImpl<NcProgramExchangeMapper, NcProgramExchange> {
    private final CureFlowService cureFlowService;
    private final ProgramAnnotationService programAnnotationService;
    private final QinzheFgbService qinzheFbgService;
    private final NcNodeService ncNodeService;
    private final OssTemplate ossTemplate;
    private final BladeRedis bladeRedis;
@@ -130,28 +136,28 @@
                }
            }
            List<DictBiz> annotionDictList = programAnnotationService.getAnnotionDictList();
            NcNode programPackageNode;
            //目录列表,即程序包列表
            for(String entryName : dirEntryNameList){
                DncSendBackData progData = new DncSendBackData();
                String packageName = StringUtils.removeEnd(entryName,"/");
                progData.setProgramName(packageName);
                Optional<String> optFilename = fileEntryNameList.stream().filter(n -> n.startsWith(entryName)).findFirst();
                if(optFilename.isPresent()){
                    entry = zipFile.getEntry(optFilename.get());
                    InputStream ins = zipFile.getInputStream(entry);
                    ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.toByteArray(ins));;
                    ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(IOUtils.toByteArray(ins));
                    //解析机床
                    progData.setFileBackTime(DateUtil.fromInstant(entry.getLastModifiedTime().toInstant()));
                    AnnotationProperties defAnnoProperties =AnnotationProperties.getDefault();
                    String statusLine = FileContentUtil.readLineAt(bais,defAnnoProperties.getStatusLineIndex());//状态注释行
                    bais.reset();
                    String sendPathLine = FileContentUtil.readLineAt(bais,defAnnoProperties.getSendPathLineIndex());//状态注释行
                    bais.reset();
                    String statusLine = FileContentUtil.readLineAt(byteArrayIns,defAnnoProperties.getStatusLineIndex());//状态注释行
                    byteArrayIns.reset();
                    String sendPathLine = FileContentUtil.readLineAt(byteArrayIns,defAnnoProperties.getSendPathLineIndex());//状态注释行
                    byteArrayIns.reset();
                    if(statusLine.contains("GH")){
                    if(statusLine.contains(AnnotationUtil.GH)){
                        //固化,不应回传,忽略
                        log.warn("状态{},不应回传,忽略",statusLine);
                        continue;
@@ -161,6 +167,8 @@
                    if(machine == null){
                        throw new ServiceException("根据下发路径未找到程序对应的机床:"+sendPathLine);
                    }
                    progData.setProgramName(packageName);
                    if(statusLine.contains(AnnotationUtil.SQ)){
                        //试切
@@ -201,25 +209,35 @@
    }
    /**
     * 从文件夹名解析出程序包名和和工序版次
     * @param folderName 文件夹名
     * @return 结构数据
     * 修复程序包名,fanuc不识别下划线,下发时转换为了-,这里需要确认。应该是从导出记录中查找修改后的包名,但是现场编制的没有咋办?
     * @param packageNameInZip
     * @return
     */
    /*
    PackageAndProcessEdition parseProgramPackageFromFolderName(String folderName){
        int index = StringUtils.lastIndexOf(folderName,'-');
        String processEditon = "";
        String packageName = "";
        if(index != -1){
            processEditon = folderName.substring(index+1);
            packageName = folderName.substring(0,index);
    private String fixProgramPackageName(String packageNameInZip) {
        Matcher matcher = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher(packageNameInZip);
        String drawingNo = null;
        if(matcher.find()) {
            drawingNo = matcher.group(1);
        }
        String processNo = null;
        if(matcher.find()) {
            processNo = matcher.group(2);
        }
        PackageAndProcessEdition result = new PackageAndProcessEdition();;
        result.setProgramPackageName(packageName);
        result.setProcessEdition(processEditon);
        return result;
    }*/
        String processEdition = null;
        if(matcher.find()) {
            processEdition = matcher.group(3);
        }
        if(drawingNo != null && processNo != null && processEdition != null) {
            if(drawingNo.contains("_")) {
            }
        }
        return packageNameInZip;
    }
    */
    /**
     * 入库回传文件,并启动固化流程
@@ -371,37 +389,6 @@
        String zipFileName = bladeRedis.get(getFileKey());
        return ZipTextFileContentUtil.getTextContent(this.ossTemplate.statFileStream(zipFileName),entryName);
        /*
        try(InputStream inputStream = this.ossTemplate.statFileStream(zipFileName);){
            Path tempZipFile = createTempFile(inputStream);
            ZipEntry entry;
            try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(tempZipFile.toFile())) {
                Enumeration<? extends ZipEntry> entries = zipFile.entries();
                while (entries.hasMoreElements()) {
                    entry = entries.nextElement();
                    if (!entryName.equals(entry.getName())) {
                        continue;
                    }
                    try (InputStream fileIns = zipFile.getInputStream(zipFile.getEntry(entryName))) {
                        ByteArrayInputStream bos = new ByteArrayInputStream(fileIns.readAllBytes());
                        boolean isText = StringUtils.endsWithIgnoreCase(entryName,".txt") || StringUtils.endsWithIgnoreCase(entryName,".nc")|| StringUtils.endsWithIgnoreCase(entryName,".xml");
                        if(!isText) {
                            isText = FileContentUtil.isTextFile(bos);
                        }
                        if (isText) {
                            bos.reset();
                            result = FileContentUtil.getContentFromStream(bos);
                        } else {
                            result = "<非文本文件>";
                        }
                    }
                }
            }
        }
        return result;*/
    }
}
@@ -415,3 +402,4 @@
        return programPackageName+"-"+processEdition;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/MdmProgramImportService.java
@@ -299,13 +299,15 @@
        List<String> idList = Func.toStrList(ids);
        String dictStr = bladeRedis.get(getFileKey());
        if(dictStr == null){
            throw new ServiceException("");
        }
        Path extractDir = Paths.get(dictStr);
        List<MdmProgramImportVO> list = readTempDir(extractDir);
        String destFileFull;
        for(String str : idList){
            //System.out.println(str);
            for(MdmProgramImportVO vo : list){
                if(StringUtils.equals(vo.getFullPath(),str)){
                    destFileFull = vo.getSendPath()+File.separator+vo.getFilename();
@@ -324,8 +326,5 @@
            }
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeAutoCreateService.java
@@ -34,7 +34,7 @@
    public static final String TRY_NAME = "试切";
    public static final String CURE_NAME = "固化";
    public static final String DEVIATION_NAME = "偏离";
    public static final String DEVIATION_NAME = "临时更改单";
    /**
     * 创建树到机床级别
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeHisService.java
@@ -54,23 +54,7 @@
        ncNodeService.deleteOldEditionNodeData();
    }
    /**
     * 查询偏离单的序号
     * @param programPkgNode 偏离单的程序包名节点
     * @return 序号
     */
    public long getDeviationSerialForNode(NcNodeHis programPkgNode) {
        return lambdaQuery().eq(NcNodeHis::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNodeHis::getName,programPkgNode.getName())
            .eq(NcNodeHis::getDrawingNo,programPkgNode.getDrawingNo())
            .eq(NcNodeHis::getProcessNo,programPkgNode.getProcessNo())
            .eq(NcNodeHis::getProcessEdition,programPkgNode.getProcessEdition())
            .isNotNull(NcNodeHis::getDeviation)
            .le(NcNodeHis::getCreateTime,programPkgNode.getCreateTime())  //时间小于等于当前节点
            .count();
    }
    /**
     * 查询节点的历史列表(节点的上级节点”程序包名“因为存在多个版本,所以历史记录也需要根据不同版本程序包名进行查询)
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java
@@ -16,6 +16,7 @@
import org.springblade.mdm.flow.constants.FlowConstant;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.service.FlowProgramFileService;
import org.springblade.mdm.flow.service.TaskDispatchService;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.entity.NcNodeHis;
import org.springblade.mdm.program.entity.NcProgramApproved;
@@ -48,8 +49,10 @@
    private final OssTemplate ossTemplate;
    private final FlowProgramFileService flowProgramFileService;
    private final HistoryService historyService;
    private final TaskDispatchService taskDispatchService;
    private final MachineAnnotationConfig annotationConfig;
    private final AnnotationProcessorHelper annotationProcessorHelper;
    /**
     * 导出dnc压缩包
     * @param approvedIdArray 待导出审批表id数组
@@ -100,7 +103,6 @@
        Machine machine = machineService.getByCode(packageNodeHis.getMachineCode());//程序包节点,获取注释用
        //List<NcNode> programNodes = ncNodeService.lambdaQuery().eq(NcNode::getIsLastEdition,1).eq(NcNode::getParentId, approved.getNcNodeId()).list();
        List<NcNodeHis> programNodes = ncNodeHisService.lambdaQuery().eq(NcNodeHis::getParentId, approved.getNcNodeId()).list();
        FlowProgramFile programFile;
@@ -113,10 +115,9 @@
        }
        long deviationSerial = -1;//偏离单序号 ,-1为非偏离单,不需要加入
        if(packageNodeHis.isDeviationProgram()) {
            deviationSerial = ncNodeHisService.getDeviationSerialForNode(packageNodeHis);
            deviationSerial = taskDispatchService.getDeviationSerial(packageNodeHis.getProgramNo());
        }
        //List<DictBiz> annotationDictList= programAnnotationService.getAnnotionDictList();
        for (NcNodeHis node : programNodes) {
            String filePathInZip = genFilePathInZip(packageFolder,node,deviationSerial);
            programFile = this.flowProgramFileService.getById(node.getFlowProgramFileId());
@@ -124,7 +125,8 @@
                InputStream inputStream = ossTemplate.statFileStream(programFile.getOssName());
                String sendDir = machine.getProgSendDir()==null? StringUtil.EMPTY:machine.getProgSendDir();
                AnnotationProcessor annoProcessor = ProcessorHelper.getProcessor(machine.getControlSystem(),annotationConfig);
                //AnnotationProcessor annoProcessor = ProcessorHelper.getProcessor(machine.getControlSystem(),annotationConfig);
                AnnotationProcessor annoProcessor = this.annotationProcessorHelper.getProcessor(machine.getControlSystem());
                AnnotationData annoData = new AnnotationData();
                annoData.setSendPath(sendDir);
                annoData.setProgramStatus(status);
@@ -133,15 +135,7 @@
                InputStream addedInsFinal = annoProcessor.putAnnotation(annoData,inputStream);
                addedInsFinal.reset();
                /*
                InputStream addedInsFinal;
                InputStream addedIns2 = programAnnotationService.setSendDirAndStatusAnnotation(sendDir,status,inputStream,machine.getControlSystem());
                if(StringUtils.isNotBlank(programPackageNode.getDeviation())) {
                    //偏离单,增加偏离单号
                    addedInsFinal = programAnnotationService.setPldAnnotation(programPackageNode.getDeviation(),addedIns2, machine.getControlSystem(), annotationDictList);;
                }else{
                    addedInsFinal = addedIns2;
                }*/
                this.addInputStreamToZip(zipOut, addedInsFinal, filePathInZip);
            }
        }
@@ -152,7 +146,7 @@
     * 生成在zip中的文件路径
     * @param packageFolder zip中的文件夹
     * @param programNode 程序节点
     * @param deviationSerial 偏离单序号
     * @param deviationSerial 临时更改单序号
     * @return zip中的文件路径
     */
    String genFilePathInZip(String packageFolder,NcNodeHis programNode,long deviationSerial){
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/FanucProcessor.java
@@ -19,27 +19,39 @@
    @Autowired
    private ProgramAnnotationService programAnnotationService;
    private String controlSystem;
    private Pattern PATTERN = Pattern.compile("^[oO]\\d{4}");
    private final int O_LINE = 1;
    static final Pattern PATTERN = Pattern.compile("^[oO]\\d{4}.*");
    //private final int O_LINE = 1;
    @Override
    public InputStream putAnnotation(AnnotationData annoData, InputStream inputStream) throws IOException {
        //在O0001 这种文字后面增加文件名(不带扩展名)
        ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
        String line = FileContentUtil.readLineAt(bais,O_LINE);
        bais.reset();
        ByteArrayInputStream byteStream = new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
        //String line = FileContentUtil.readLineAt(byteStream,O_LINE);
        String line = FileContentUtil.readLineAt(byteStream,getAnnotationProperties().getProgramNameLineIndex());
        byteStream.reset();
        boolean oMatched = PATTERN.matcher(line).matches();
        InputStream ins1;
        if(oMatched){
            List<DictBiz> annoDicts = programAnnotationService.getAnnotionDictList();
            String newline =  line + AnnotationUtil.generateAnnotation(FilenameUtils.removeExtension(annoData.getFilename()),getControlSystem(),annoDicts);
            ins1 = FileContentUtil.replaceAtLine(bais,O_LINE,newline);
            String programAnno =  AnnotationUtil.generateAnnotation(FilenameUtils.removeExtension(annoData.getFilename()),getControlSystem(),annoDicts);
            ins1 = FileContentUtil.replaceAtLine(byteStream,getAnnotationProperties().getProgramNameLineIndex(),genProgramNameLine(line,programAnno));
        }else{
            ins1 = bais;
            ins1 = byteStream;
        }
        return super.putAnnotation(annoData, ins1);
    }
    /**
     * 生成程序名称注释行,O[4位数字](程序名) ,需要将用户自己的程序名去或其他注释掉放后面
     * @param oriLine 原始行文本
     * @param programNameAnno 程序注释文本:(程序名)
     * @return Oxxxx+程序注释文本
     */
    String genProgramNameLine(String oriLine,String programNameAnno){
        return oriLine.substring(0,5)+programNameAnno;
    }
    @Override
    public void setControlSystem(String controlSystemDictVal) {
blade-service/blade-mdm/src/test/java/org/springblade/mdm/commons/contants/RegExpConstantsTest.java
@@ -47,4 +47,42 @@
        m = RegExpConstants.PROGRAM_FILE_PATTERN.matcher("J_YDT290-10-02B-35-A-1-e.TXT");
        Assertions.assertFalse(m.find());
    }
    @Test
    public void testProgramPackagePattern(){
        Matcher m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("J_YDT290-10-02B-35-A");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("J-YDT290-10-02B-35-A1");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("CP3-1-1-1");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("CP3-1-A-B");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("CP3X296-A-B");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("CP3X296-A-B");
        String drawingNo = null;
        if(m.find()) {
            drawingNo = m.group(1);
            Assertions.assertEquals("CP3X296",drawingNo );
        }
        String processNo = null;
        if(m.find()) {
            processNo = m.group(2);
            Assertions.assertEquals("A",processNo );
        }
        String processEdition = null;
        if(m.find()) {
            processEdition = m.group(3);
            Assertions.assertEquals("B",processEdition );
        }
    }
}