WordCount

码云上的项目地址:https://gitee.com/heypin/WordCount

本次作业的链接地址:https://edu.cnblogs.com/campus/xnsy/Test/homework/2203

设计思路

  首先配置下面图片中的options.xml文件,然后读取文件信息将这些支持的命令行封装到Apache CLI库的Options类中,再通过CLI库解析命令行解析出输入了哪些Option以及他们的值,如果配置文件写的有多个参数,将获取到多个参数。
  然后对每个命令行参数都建立一个类,每个类实现一个命令行参数的功能,如LineCount类实现-l命令,WordCount实现-w命令,OutputGraph实现-x命令,除了递归命令-s的实现类Recursion,其他命令对应的类都实现了IStatis接口。
  最后通过java的反射机制,这里是用的spring的库来反射,将解析到的命令对应的类循环实例化,调用这些类的共同接口IStatis的statis方法执行相应的功能,statis方法的参数由main函数和StatisUtil工具类负责将解析到的参数传给它们。

 解析命令行主要代码

public class StatisUtil {    
    public static Element getOptionConfigRoot() throws DocumentException 
    {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new StatisUtil()
                .getClass().getClassLoader().getResource("options.xml"));        
        return document.getRootElement();       
    }
    public static Options getAllOptions() throws DocumentException
    {
        Options options=new Options();
        Iterator<Element> it = getOptionConfigRoot().elementIterator();
        while( it.hasNext())
        {
            Element element = it.next();
            Option option=Option.builder(element.attributeValue("opt"))
                    .hasArg(Boolean.parseBoolean(element.attributeValue("hasArg")))
                    .argName(element.attributeValue("argName"))
                    .numberOfArgs(Integer.parseInt(element.attributeValue("numberOfArgs")))
                    .optionalArg(Boolean.parseBoolean(element.attributeValue("optionalArg")))
                    .build();                       
            options.addOption(option);           
        }
        return options;
    }
    public static String getCommonParam(Option[] cmdOptions)    
    {        
        String commonParam=null;
        for(int i=0;i<cmdOptions.length;++i)
        {
            if(cmdOptions[i].hasArg()&&cmdOptions[i].hasOptionalArg()
                    &&cmdOptions[i].getValue()!=null){
                commonParam=cmdOptions[i].getValue();
            }
        }
        return commonParam;
    }
    public static Option[] optionsToArray(Options options) 
    {
        Collection<Option> opts=options.getOptions();
        Option[] optArray=new Option[opts.size()];
        opts.toArray(optArray);
        return optArray;
    }
    public static Options getMatchOptions(Options options,String matchArgName)
    {
        Options matchOptions=new Options();
        Collection<Option> opts=options.getOptions();
        for(Option option:opts){
            if(option.getArgName().contains(matchArgName)){
                matchOptions.addOption(option);
            }
        }
        return matchOptions;
    }
    public static void executeCommandLine(Option[] cmdOptions,StringWriter writer)
    {                
        @SuppressWarnings("resource")
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");        
        String commonParam=getCommonParam(cmdOptions);
        for(int i=0;i<cmdOptions.length;++i) {
            IStatis statis=(IStatis) context.getBean(cmdOptions[i].getOpt());
            if(cmdOptions[i].hasArgs()) {
                statis.statis(writer,cmdOptions[i].getValues());
            }
            else  {
                if(cmdOptions[i].hasOptionalArg()&&cmdOptions[i].getValue()==null)
                    statis.statis(writer,commonParam);
                else
                    statis.statis(writer,cmdOptions[i].getValue());
            }                                    
        }                
    }
    
    public static String executeOptions(Option[] options,String fileName) throws IOException
    {
        @SuppressWarnings("resource")
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        StringWriter writer=new StringWriter();    
        for(int i=0;i<options.length;++i) {
            IStatis statis=(IStatis) context.getBean(options[i].getOpt());                    
            statis.statis(writer,fileName);
        }
        writer.close();
        return writer.getBuffer().toString();
    }

}

 

public class MainClass {
    public static CommandLine cmd=null;
    public static void main(String[] args) {        
            CommandLineParser parser=new DefaultParser();
            cmd= parser.parse(StatisUtil.getAllOptions(), args);
            if(!cmd.hasOption("s"))
            {
                StringWriter writer=new StringWriter();
                StatisUtil.executeCommandLine(cmd.getOptions(),writer);
                if(!cmd.hasOption("o"))//有输出到文件命令时不打印
                    System.out.println(writer.getBuffer().toString());
                writer.close();
            }
            else
            {
                List<File> matchFile=new Recursion().recursion(StatisUtil.getCommonParam(cmd.getOptions()));
                CommandLine newCmd=parser.parse(StatisUtil.getMatchOptions(StatisUtil.getAllOptions(),"recursion"), args);
                if(matchFile.size()==0)
                    System.out.println("无匹配的文件");
                for(File file:matchFile)
                    System.out.println(StatisUtil.executeOptions(newCmd.getOptions(), file.getAbsolutePath()));                
            }            
                  
    }

运行结果

静态代码检查情况

使用PMD工具进行静态代码检查,经检查代码检查无较大问题,主要提示规则CommentRequired,因代码暂未写注释,而有些地方最好添加注释。

单元测试情况

采用JUnit5进行单元测试,主要对统计行数、字符数、代码行数等进行单元测试,单元测试的代码如下:

package com.statis.impl.test;
import static org.junit.jupiter.api.Assertions.*;
import java.io.StringWriter;
import org.junit.jupiter.api.Test;
import com.statis.impl.CharCount;
import com.statis.impl.CodeCount;
import com.statis.impl.LineCount;
import com.statis.impl.WordCount;

class CountTest {

    public String fileName="C:\\Users\\22443\\Desktop\\test.txt";
    @Test
    void charCountTest()
    {
        StringWriter writer=new StringWriter();
        new CharCount().statis(writer, fileName);
        String result=fileName+",字符数为:133\n";
        assertTrue(result.equals(writer.getBuffer().toString()));
    }
    @Test
    void LineCountTest()
    {
        StringWriter writer=new StringWriter();
        new LineCount().statis(writer, fileName);
        String result=fileName+",行数为:11\n";
        assertTrue(result.equals(writer.getBuffer().toString()));
    }
    @Test
    void WordCount()
    {
        StringWriter writer=new StringWriter();
        new WordCount().statis(writer, fileName);
        String result=fileName+",词数为:18\n";
        assertTrue(result.equals(writer.getBuffer().toString()));
    }
    @Test
    void codeCountTest()
    {
        StringWriter writer=new StringWriter();
        new CodeCount().statis(writer, fileName);
        String result=fileName+",空行数为:3\n"
                +fileName+",注释行数为:5\n"
                +fileName+",代码行数为:3\n";
        assertTrue(result.equals(writer.getBuffer().toString()));
    }
}

测试文本:

单元测试结果:  单元测试全部通过

 

posted @ 2018-10-21 14:08  heypin  阅读(219)  评论(0)    收藏  举报