2 * Copyright 2017 BOCO Corporation. CMCC Technologies Co., Ltd
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.onap.vfc.nfvo.emsdriver.collector;
18 import java.io.BufferedOutputStream;
19 import java.io.BufferedReader;
21 import java.io.FileInputStream;
22 import java.io.FileNotFoundException;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Date;
31 import java.util.HashMap;
32 import java.util.Hashtable;
33 import java.util.LinkedHashMap;
34 import java.util.List;
35 import java.util.Properties;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
39 import javax.xml.stream.XMLInputFactory;
40 import javax.xml.stream.XMLStreamConstants;
41 import javax.xml.stream.XMLStreamReader;
43 import org.apache.commons.io.FileUtils;
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46 import org.onap.vfc.nfvo.emsdriver.commons.constant.Constant;
47 import org.onap.vfc.nfvo.emsdriver.commons.ftp.AFtpRemoteFile;
48 import org.onap.vfc.nfvo.emsdriver.commons.ftp.FTPInterface;
49 import org.onap.vfc.nfvo.emsdriver.commons.ftp.FTPSrv;
50 import org.onap.vfc.nfvo.emsdriver.commons.model.CollectMsg;
51 import org.onap.vfc.nfvo.emsdriver.commons.model.CollectVo;
52 import org.onap.vfc.nfvo.emsdriver.commons.utils.DateUtil;
53 import org.onap.vfc.nfvo.emsdriver.commons.utils.Gunzip;
54 import org.onap.vfc.nfvo.emsdriver.commons.utils.StringUtil;
55 import org.onap.vfc.nfvo.emsdriver.commons.utils.UnZip;
56 import org.onap.vfc.nfvo.emsdriver.commons.utils.VarExprParser;
57 import org.onap.vfc.nfvo.emsdriver.commons.utils.Zip;
58 import org.onap.vfc.nfvo.emsdriver.configmgr.ConfigurationImp;
59 import org.onap.vfc.nfvo.emsdriver.configmgr.ConfigurationInterface;
60 import org.onap.vfc.nfvo.emsdriver.messagemgr.MessageChannel;
61 import org.onap.vfc.nfvo.emsdriver.messagemgr.MessageChannelFactory;
64 public class TaskThread implements Runnable{
66 public Log log = LogFactory.getLog(TaskThread.class);
68 private MessageChannel cmResultChannel;
69 public MessageChannel pmResultChannel;
71 private CollectMsg data;
73 private ConfigurationInterface configurationInterface = new ConfigurationImp();
75 private String localPath = Constant.SYS_DATA_TEMP;
76 private String resultPath = Constant.SYS_DATA_RESULT;
78 private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
80 private SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
82 // private String csvpathAndFileName;
83 // private String xmlPathAndFileName;
84 // private int countNum = 0 ;
86 public TaskThread(CollectMsg data) {
96 cmResultChannel = MessageChannelFactory.getMessageChannel(Constant.COLLECT_RESULT_CHANNEL_KEY);
97 pmResultChannel = MessageChannelFactory.getMessageChannel(Constant.COLLECT_CHANNEL_KEY);
99 collectMsgHandle(data);
100 } catch (Exception e) {
105 private void collectMsgHandle(CollectMsg collectMsg) {
106 String emsName = collectMsg.getEmsName();
107 String type = collectMsg.getType();
108 CollectVo collectVo = configurationInterface.getCollectVoByEmsNameAndType(emsName, type);
111 List<String> downloadfiles = this.ftpDownload(collectVo);
112 //paser ftp update message send
113 for(String fileName :downloadfiles){
114 this.parseFtpAndSendMessage(fileName,collectVo);
118 public void parseFtpAndSendMessage(String fileName, CollectVo collectVo) {
120 List<File> filelist = decompressed(fileName);
122 for (File tempfile : filelist) {
124 String unfileName = tempfile.getName();
126 Pattern pa = Pattern.compile(".*-(.*)-\\w{2}-");
127 Matcher ma = pa.matcher(unfileName);
130 String nename = ma.group(1);
131 boolean parseResult = false;
132 if("ems-resource".equalsIgnoreCase(collectVo.getType())){
133 parseResult = processCMXml(tempfile, nename,"CM");
135 if(unfileName.indexOf(".csv") > 0){
136 parseResult = processPMCsv(tempfile);
138 parseResult = processPMCsv(tempfile);
143 log.info("parser "+tempfile+" sucess");
145 log.info("parser "+tempfile+" fail");
151 public boolean processPMCsv(File tempfile) {
153 FileInputStream brs = null;
154 InputStreamReader isr = null;
155 BufferedReader br = null;
157 List<String> columnNames = new ArrayList<String>();
158 List<String> commonValues = new ArrayList<String>();
161 brs = new FileInputStream(tempfile);
162 isr = new InputStreamReader(brs, Constant.ENCODING_UTF8);
163 br = new BufferedReader(isr);
165 String commonField = br.readLine();
166 String[] fields = commonField.split("\\|",-1);
167 for(String com : fields){
168 String[] comNameAndValue = com.split("=",2);
169 columnNames.add(comNameAndValue[0].trim());
170 commonValues.add(comNameAndValue[1]);
173 String columnName = br.readLine();
174 String[] names = columnName.split("\\|",-1);
175 for(String name : names){
176 columnNames.add(name);
179 // xmlPathAndFileName = this.setColumnNames(nename, columnNames,type);
181 String valueLine = "";
182 List<String> valuelist = new ArrayList<String>();
184 while ((valueLine = br.readLine()) != null) {
185 if (valueLine.trim().equals("")) {
189 String [] values = valueLine.split("\\|",-1);
191 valuelist.addAll(commonValues);
192 for(String value : values){
193 valuelist.add(value);
195 // this.appendLine(valuelist, bos);
197 HashMap<String,String> resultMap = this.resultMap(columnNames,valuelist);
199 pmResultChannel.put(resultMap);
200 } catch (InterruptedException e) {
201 log.error("collectResultChannel.put(resultMap) error ",e);
205 } catch (IOException e) {
206 log.error("processPMCsv is fail ",e);
217 } catch (Exception e){
225 private HashMap<String,String> resultMap(List<String> columnNames, List<String> valuelist) {
227 HashMap<String,String> resultMap = new HashMap<String,String>();
228 if(columnNames.size() == valuelist.size()){
229 for(int i =0;i<columnNames.size();i++){
230 resultMap.put(columnNames.get(i), valuelist.get(i));
237 private boolean processCMXml(File tempfile, String nename, String type) {
239 String csvpath = localPath+nename+"/"+type+"/";
240 File csvpathfile = new File(csvpath);
241 if(!csvpathfile.exists()){
242 csvpathfile.mkdirs();
244 String csvFileName = nename +dateFormat.format(new Date())+ System.nanoTime();
245 String csvpathAndFileName = csvpath+csvFileName+".csv";
246 BufferedOutputStream bos = null;
247 FileOutputStream fos = null;
249 fos = new FileOutputStream(csvpathAndFileName,false);
250 bos = new BufferedOutputStream(fos, 10240);
251 } catch (FileNotFoundException e1) {
252 log.error("FileNotFoundException "+StringUtil.getStackTrace(e1));
255 boolean FieldNameFlag = false;
256 boolean FieldValueFlag = false;
259 String xmlPathAndFileName = null;
260 String localName = null;
261 String endLocalName = null;
264 ArrayList<String> names = new ArrayList<String>();// colname
265 LinkedHashMap<String, String> nameAndValue = new LinkedHashMap<String, String>();
268 FileInputStream fis = null;
269 InputStreamReader isr = null;
270 XMLStreamReader reader = null;
272 fis = new FileInputStream(tempfile);
273 isr = new InputStreamReader(fis, Constant.ENCODING_UTF8);
274 XMLInputFactory fac = XMLInputFactory.newInstance();
275 reader = fac.createXMLStreamReader(isr);
277 boolean setcolum = true;
278 while (reader.hasNext()){
280 event = reader.next();
282 case XMLStreamConstants.START_ELEMENT:
283 localName = reader.getLocalName();
284 if ("FieldName".equalsIgnoreCase(localName)){
285 FieldNameFlag = true;
288 if ("N".equalsIgnoreCase(localName)){
289 String colName = reader.getElementText().trim();
293 if ("FieldValue".equalsIgnoreCase(localName)){
294 FieldValueFlag = true;
299 xmlPathAndFileName = this.setColumnNames(nename, names,type);
303 if ("Object".equalsIgnoreCase(localName)){
304 int ac = reader.getAttributeCount();
305 for (int i = 0; i < ac; i++){
306 if ("rmUID".equalsIgnoreCase(reader.getAttributeLocalName(i))){
307 rmUID = reader.getAttributeValue(i).trim();
310 nameAndValue.put("rmUID", rmUID);
312 if ("V".equalsIgnoreCase(localName)) {
313 index = Integer.parseInt(reader
314 .getAttributeValue(0)) - 1;
315 String currentName = names.get(index);
316 String v = reader.getElementText().trim();
317 nameAndValue.put(currentName, v);
321 case XMLStreamConstants.CHARACTERS:
323 case XMLStreamConstants.END_ELEMENT:
324 endLocalName = reader.getLocalName();
326 if ("FieldName".equalsIgnoreCase(endLocalName)){
327 FieldNameFlag = false;
329 if ("FieldValue".equalsIgnoreCase(endLocalName)){
330 FieldValueFlag = false;
332 if ("Object".equalsIgnoreCase(endLocalName)){
334 this.appendLine(nameAndValue,bos);
335 nameAndValue.clear();
339 } catch (Exception e)
341 log.error(""+StringUtil.getStackTrace(e));
342 event = reader.next();
356 String[] fileKeys = this.createZipFile(csvpathAndFileName,xmlPathAndFileName,nename);
358 Properties ftpPro = configurationInterface.getProperties();
359 String ip = ftpPro.getProperty("ftp_ip");
360 String port = ftpPro.getProperty("ftp_port");
361 String ftp_user = ftpPro.getProperty("ftp_user");
362 String ftp_password = ftpPro.getProperty("ftp_password");
364 String ftp_passive = ftpPro.getProperty("ftp_passive");
365 String ftp_type = ftpPro.getProperty("ftp_type");
366 String remoteFile = ftpPro.getProperty("ftp_remote_path");
367 this.ftpStore(fileKeys,ip,port,ftp_user,ftp_password,ftp_passive,ftp_type,remoteFile);
369 String message = this.createMessage(fileKeys[1], ftp_user, ftp_password, ip, port, countNum,nename);
372 this.setMessage(message);
373 } catch (Exception e){
374 log.error(""+StringUtil.getStackTrace(e));
394 } catch (Exception e){
401 private void setMessage(String message) {
404 cmResultChannel.put(message);
405 } catch (Exception e) {
406 log.error("collectResultChannel.put(message) is error "+StringUtil.getStackTrace(e));
410 public String createMessage(String zipName,String user,String pwd,String ip, String port,int countNum, String nename) {
412 StringBuffer strBuffer = new StringBuffer();
414 .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
415 + "<FILE_DATA_READY_UL xmlns:xsi=\" http://www.w3.org/2001/XMLSchema-instance\">"
416 + "<Header SessionID=\"");
417 strBuffer.append("");
418 strBuffer.append("\" LicenceID=\"");
419 strBuffer.append("");
420 strBuffer.append("\" SystemID=\"");
421 strBuffer.append("");
422 strBuffer.append("\" Time=\"");
423 strBuffer.append( dateFormat2.format(new Date()));
424 strBuffer.append("\" PolicyID=\"");
425 strBuffer.append("");
426 strBuffer.append("\"/><Body>");
427 strBuffer.append("<DataCatalog>");
428 strBuffer.append("");
429 strBuffer.append("</DataCatalog><GroupID>");
430 strBuffer.append(nename);
431 strBuffer.append("</GroupID><DataSourceName>");
432 strBuffer.append("");
433 strBuffer.append("</DataSourceName><InstanceID>");
434 strBuffer.append("");
435 strBuffer.append("</InstanceID><FileFormat>");
436 strBuffer.append("csv");
437 strBuffer.append("</FileFormat><CharSet>");
438 strBuffer.append("gbk");
439 strBuffer.append("</CharSet><FieldSeparator>");
440 strBuffer.append("|");
441 strBuffer.append("</FieldSeparator><IsCompressed>");
442 strBuffer.append("true");
443 strBuffer.append("</IsCompressed><StartTime>");
444 strBuffer.append(dateFormat2.format(new Date()));
445 strBuffer.append("</StartTime><EndTime>");
446 strBuffer.append("");
447 strBuffer.append("</EndTime><FileList>");
448 strBuffer.append(zipName);
449 strBuffer.append("</FileList><ConnectionString>");
450 strBuffer.append("ftp://" + user + ":" + pwd + "@" + ip + ":" + port);
451 strBuffer.append("</ConnectionString>");
452 strBuffer.append("<DataCount>");
453 strBuffer.append(countNum);
454 strBuffer.append("</DataCount>");
456 strBuffer.append("<FileSize>").append("").append("</FileSize>");
457 strBuffer.append("<DataGranularity>").append("").append("</DataGranularity>");
460 strBuffer.append("</Body></FILE_DATA_READY_UL>");
461 return strBuffer.toString();
465 private void ftpStore(String[] fileKeys, String ip, String port, String ftp_user, String ftp_password,
466 String ftp_passive, String ftp_type, String remoteFile) {
467 String zipFilePath = fileKeys[0];
470 FTPInterface ftpClient;
471 ftpClient = new FTPSrv();
474 ftpClient.login(ip, Integer.parseInt(port), ftp_user, ftp_password, "GBK", Boolean.parseBoolean(ftp_passive), 5*60*1000);
475 } catch (Exception e) {
476 log.error("login fail,ip=["+ip+"] port=["+port+"] user=["+ftp_user+"]pwd=["+ftp_password+"]"+StringUtil.getStackTrace(e));
479 // ftpClient.store(zipFilePath, remoteFile);
480 log.debug("store ["+zipFilePath+"]to["+remoteFile+"]");
482 FileUtils.deleteQuietly(new File(zipFilePath));
487 private String[] createZipFile(String csvpathAndFileName,String xmlPathAndFileName,String nename) {
489 String zipPath = resultPath+nename +dateFormat.format(new Date())+"_"+System.nanoTime();
491 File destDir = new File(zipPath);
495 FileUtils.copyFileToDirectory(new File(csvpathAndFileName), destDir);
496 FileUtils.copyFileToDirectory(new File(xmlPathAndFileName), destDir);
497 } catch (IOException e) {
501 String destFilePath = zipPath + ".zip";
503 Zip zip = new Zip(destDir.getAbsolutePath(), destFilePath);
504 zip.setCompressLevel(9);
507 FileUtils.deleteDirectory(destDir);
508 } catch (IOException e) {
509 log.error("zip.compress() is fail "+StringUtil.getStackTrace(e));
511 return new String[] { destFilePath, zipPath + ".zip"};
515 private String setColumnNames(String nename, List<String> names,String type) {
517 String xmlpath = localPath+nename +"/"+type+"/";
518 File xmlpathfile = new File(xmlpath);
519 if(!xmlpathfile.exists()){
520 xmlpathfile.mkdirs();
522 String xmlFileName = nename +dateFormat.format(new Date())+ System.nanoTime();
523 String fieldLine = "";
524 for (int i = 0; i < names.size(); i++) {
525 String field = "\t<Field>\r\n" + "\t\t<FieldNo>" + i
526 + "</FieldNo>\r\n" + "\t\t<FieldName>"
527 + names.get(i) + "</FieldName>\r\n"
528 + "\t\t<FieldType>" + names.get(i)
530 + "\t\t<FieldNameOther>" + names.get(i)
531 + "</FieldNameOther>\r\n" +
533 fieldLine = fieldLine + field;
536 String str = "<?xml version=\"1.0\" encoding=\"gbk\"?>\r\n"
537 + "<xml>\r\n" + "<FILE_STRUCTURE>\r\n" + fieldLine
538 + "</FILE_STRUCTURE>\r\n" + "</xml>\r\n";
539 String xmlPathAndFileName = xmlpath+xmlFileName+".xml";
541 this.writeDetail(xmlPathAndFileName,str);
542 } catch (Exception e) {
543 log.error("writeDetail is fail ,xmlFileName="+xmlFileName +StringUtil.getStackTrace(e));
546 return xmlPathAndFileName;
549 private void writeDetail(String detailFileName,String str) throws Exception {
550 OutputStreamWriter writer = null;
551 OutputStream readOut = null;
553 readOut = new FileOutputStream(new File(detailFileName), false);
554 writer = new OutputStreamWriter(readOut);
571 private void appendLine(LinkedHashMap<String, String> nameAndValue,BufferedOutputStream bos) {
572 StringBuilder lineDatas = new StringBuilder();
574 for (String key : nameAndValue.keySet()) {
575 lineDatas.append(nameAndValue.get(key)).append("|");
578 bos.write(lineDatas.toString().getBytes());
579 bos.write("\n".getBytes());
580 } catch (IOException e) {
581 log.error("appendLine error "+StringUtil.getStackTrace(e));
585 // private void appendLine(List<String> values,BufferedOutputStream bos) {
586 // StringBuilder lineDatas = new StringBuilder();
588 // for (String value : values) {
589 // lineDatas.append(value).append("|");
592 // bos.write(lineDatas.toString().getBytes());
593 // bos.write("\n".getBytes());
594 // } catch (IOException e) {
595 // log.error("appendLine error "+StringUtil.getStackTrace(e));
599 public List<File> decompressed(String fileName){
600 List<File> filelist = new ArrayList<File>();
602 if (fileName.indexOf(".gz") > 1)
605 File decompressFile = deGz(fileName);
606 filelist.add(decompressFile);
607 } catch (IOException e) {
608 log.error("decompressed is fail "+StringUtil.getStackTrace(e));
610 } else if (fileName.indexOf(".zip") > 1)
613 File[] files = deZip(new File(fileName));
614 for(File temp :files){
617 } catch (Exception e) {
618 log.error("decompressed is fail "+StringUtil.getStackTrace(e));
622 filelist.add(new File(fileName));
628 private File deGz(String gzFileName) throws IOException {
629 Gunzip gunzip = new Gunzip();
630 String orgFile = gzFileName.replace(".gz", "");
631 gunzip.unCompress(gzFileName, orgFile);
632 return new File(orgFile);
635 public File[] deZip(File file) throws Exception{
637 String regx = "(.*).zip";
638 Pattern p = Pattern.compile(regx);
639 Matcher m = p.matcher(file.getName());
642 String orgFile = localPath + m.group(1) + "/";
643 UnZip unzip = new UnZip(file.getAbsolutePath(), orgFile);
645 file = new File(orgFile);
647 File[] files = file.listFiles();
653 private List<String> ftpDownload(CollectVo collectVo) {
655 List<String> fileList = new ArrayList<String>();
657 String ip = collectVo.getIP();
659 String port = collectVo.getPort();
661 String user = collectVo.getUser();
663 String password = collectVo.getPassword();
665 String passivemode = collectVo.getPassive();
667 FTPInterface ftpClient = new FTPSrv();
671 ftpClient.login(ip, Integer.parseInt(port), user, password, "GBK", Boolean.parseBoolean(passivemode), 5*60*1000);
672 } catch (Exception e) {
673 log.error("login fail,ip=["+ip+"] port=["+port+"] user=["+user+"]password=["+password+"]"+StringUtil.getStackTrace(e));
678 String dir = collectVo.getRemotepath();
679 List<String> searchExprList = new ArrayList<String>();
680 String []FPath = dir.split(";");
681 for(int i=0;i<FPath.length;i++){
682 int oldSize = searchExprList.size();
683 String conpath = FPath[i];
684 Hashtable<String,String> varMap = new Hashtable<String,String>();
685 long[] d = DateUtil.getScanScope(new Date(), 900);
686 searchExprList.add(VarExprParser.replaceVar(conpath,d[0],d[1]));
690 log.info("["+conpath+"],result["+(searchExprList.size()-oldSize)+"] path");
693 searchExprList =getLocalPathNoRegular(searchExprList);
694 List<AFtpRemoteFile> remoteFiles = new ArrayList<AFtpRemoteFile>();
695 for(String expr :searchExprList){
696 String keys[] = parseExprKeys(expr);
697 String ftpRegular = keys[1];
698 String ftpDir = keys[0];
700 boolean cdsucess = ftpClient.chdir(expr);
702 AFtpRemoteFile[] arf = (AFtpRemoteFile[]) ftpClient.list();
703 log.info(" list ["+ftpDir+"],result["+(arf==null?"null":arf.length)+"] files");
706 rfileFilter(remoteFiles,arf,ftpRegular);
709 ftpRegular=ftpDir = null;
711 for(AFtpRemoteFile ftpRemoteFile: remoteFiles){
712 if(!new File(localPath).exists()){
714 new File(localPath).mkdir();
715 } catch (Exception e) {
716 log.error("create localPath is fail localPath="+localPath+" "+StringUtil.getStackTrace(e));
720 if(!new File(localPath).exists()){
721 new File(localPath).mkdirs();
724 String localFileName = localPath + ftpRemoteFile.getFileName();
725 File loaclFile = new File(localFileName);
726 if (loaclFile.exists()) {
730 boolean flag = ftpClient.downloadFile(ftpRemoteFile.getAbsFileName(), localFileName);
733 fileList.add(localFileName);
735 log.error("download file fail fileName="+ftpRemoteFile.getAbsFileName());
740 log.error("chdir is faill dir =["+dir+"]");
749 private void rfileFilter(List<AFtpRemoteFile> fileContainer, AFtpRemoteFile[] arfs, String ftpRegular) {
750 if (ftpRegular!=null && ftpRegular.length()>0) {
751 Pattern pattern = null;
753 pattern = Pattern.compile(ftpRegular, Pattern.CASE_INSENSITIVE);
754 } catch (Exception e) {
755 log.info("["+ftpRegular+"]Pattern.compile exception:"+e.getMessage());
757 int hisSize = fileContainer.size();
758 for (int j=0; arfs!=null&&j<arfs.length; j++) {
759 String fileName = parseFileName(arfs[j].getFileName());
760 Matcher matcher = pattern.matcher(fileName);
762 fileContainer.add(arfs[j]);
764 log.info("["+ftpRegular+"]filter["+(fileContainer.size()-hisSize)+"]filse");
767 for (int j=0; arfs!=null&&j<arfs.length; j++)
768 fileContainer.add(arfs[j]);
773 private String parseFileName(String fileName) {
774 int idx = fileName.lastIndexOf("/");
777 return fileName.substring(idx+1, fileName.length());
780 private String[] parseExprKeys(String source) {
782 if(source.indexOf(";") > -1){
783 source = source.substring(0, source.indexOf(";"));
785 if (source.endsWith("/"))
786 return new String[]{source,""};
788 int idx = source.lastIndexOf("/");
789 String[] dirkeys = new String[2];
790 dirkeys[0] = source.substring(0, idx+1);
791 dirkeys[1] = source.substring(idx+1, source.length());
795 public List<String> getLocalPathNoRegular(List<String> searchExprList){
796 boolean isregular = false;
797 List<String> regularList = new ArrayList<String>();
798 for(String regular : searchExprList){
799 Pattern lpattern = null;
801 lpattern = Pattern.compile("(.*/)<([^/]+)>(/.*)");
802 }catch (Exception e) {
803 log.info("["+regular+"]compile fails:"+e.getMessage());
806 Matcher matcher = lpattern.matcher(regular);
809 String parpath = matcher.group(1);
810 File[] arryFile = new File(parpath).listFiles();
811 for(File file :arryFile){
812 if(file.isDirectory()&&file.getName().matches(matcher.group(2))){
813 regularList.add(matcher.group(1)+file.getName()+matcher.group(3));
817 regularList.add(regular);
822 getLocalPathNoRegular(regularList);