ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021SC@SDUSC【软件工程应用与实践】Cocoon项目9-分析core文件夹(八)

2021-11-06 11:03:37  阅读:140  来源: 互联网

标签:core 2021SC void private boolean 线程 Cocoon public String


2021SC@SDUSC

分析core文件夹(八)

IncludeTransformer.java(下)

这篇博客中我将继续分析IncludeTransformer.java里的两个内部类class IncludeElementclass IncludeXMLPipe

class IncludeElement

1.属性:

//参数控制递归包括处理。
private boolean recursive;
//参数控制并行(在多个线程)包括处理。
private boolean parallel;
//参数控制并行(在多个线程)包括处理递归。
private boolean recursiveParallel;
//源URI。
private String base;
//include元素的src属性中声明的要包含的源URI。
protected String source;
//指示源内容是否必须解析为XML或包含为文本的标志。
protected boolean parse;
//mime类型提示。
protected String mimeType;
//指示是否剥离根元素的标志。
protected boolean stripRoot;
//缓冲区收集回退内容。
protected SaxBuffer fallback;
//提供给包含的源的参数的Map。
protected Map parameters;
//当前捕获的参数名。
protected String parameter;
//当前参数值(作为StringBuffer)。
protected StringBuffer value;

2.方法:

构造函数:

  • 创建include元素。
  • 传入的参数有:String base, boolean parallel, boolean recursive, boolean recursiveParallel

成员函数:

  • public void process(SaxBuffer buffer)
    • 处理元素进入缓冲区。
    • 这不能被共享缓冲区,因为如果调用回退,它必须被清理。
    • 直接调用process0(buffer, buffer);
  • public void process(ContentHandler contentHandler, LexicalHandler lexicalHandler)
    • 重载上一个成员函数。
    • 将URI加载到提供的处理程序中,处理回退。
    • 如果有回退,就调用process(buffer);,否则调用process0(contentHandler, lexicalHandler);
  • private void process0(ContentHandler contentHandler, LexicalHandler lexicalHandler)
    • 将URI加载到提供的处理程序中。
    • 设置这个线程的环境。
      • 通过判断base是否为空,来决定resolver.resolveURI()的参数。
      • 如果validity不为空,就进行同步处理。
      • 如果parse和recursive均存在,则直接调用toSAX()函数;如果只有parse存在,则创建一个IncludeXMLConsumer对象,设置setIgnoreRootElement,最后调用toSAX()函数;否则,就直接将source转换为utf-8的字符。
      • 最后是一些异常的处理,包括IOException,ProcessingException等。

class IncludeXMLPipe

1.属性:

配置:

//表示这是根管道(由变转换器拥有)还是嵌套管道。
private final boolean root;
//参数控制递归包括处理。
private boolean recursive;
//参数控制并行(在多个线程)包括处理。
private boolean parallel;
//参数控制并行(在多个线程)包括处理递归。
private boolean recursiveParallel;

当前状态:

//XMLConsumers栈。
private final Stack consumers = new Stack();
//include命名空间中嵌套元素的当前深度。
private int depth;
//用于解析包含源的Base URI。
private String base;
//在include元素中声明的要被包含的源。
private IncludeElement element;
//如果启用并行处理,则这个布尔值告诉我们是否已经开始缓冲。
private boolean buffering;
//在打开并行处理时,用于缓冲事件的IncludeBuffer。
//此对象也用作线程计数器线程的锁。
private SaxBuffer buffer;
//包含线程/任务计数器(如果并行执行)。
private int threads;

2.方法:

构造函数:

public IncludeXMLPipe() {
    root = true;
}

public IncludeXMLPipe(ContentHandler contentHandler, LexicalHandler lexicalHandler,boolean recursive, boolean parallel, boolean recursiveParallel) {
    root = false;
    setContentHandler(contentHandler);
    setLexicalHandler(lexicalHandler);
    this.recursive = recursive;
    this.parallel = parallel;
    this.recursiveParallel = recursiveParallel;
}

创建一个新的IncludeXMLPipe实例。

成员函数:

  • public void recycle()
    • 完成处理。
  • private void push(XMLConsumer consumer)
    • 将当前用户推入堆栈,用新的用户替换。
  • private void pop()
    • 从堆栈中取出用户,替换当前用户。
  • public void setDocumentLocator(Locator locator)
    • 设置文档定位器。
    • 能够解析文档基本URI。
  • public void startDocument()
    • 接收XML文档开始的通知。
  • public void endDocument()
    • 接收XML文档结束的通知。
    • 这是该行的结束——处理缓冲事件。
  • public void startElement(String uri, String localName, String qName, Attributes atts)
    • 接收元素开始的通知。
    • 检查名称空间声明。
      • 如果相等,则include命名空间中嵌套元素的当前深度减1。
      • if (INCLUDE_ELEMENT.equals(localName) && depth == 0)
        • 包含不会在这里发生,但当我们关闭这个标签时。
        • 在包含之前进行检查(我们不想要嵌套的东西),记住我们试图包含的源代码。
        • 然后进行处理,默认为“xml”,默认为“text / xml”/,默认为false。
        • 忽略嵌套的内容,最后结束。
      • if (FALLBACK_ELEMENT.equals(localName) && depth == 1)
        • 如果这是一个回退参数,则捕获它的内容。
        • 检查我们是否在正确的上下文中,缓冲区回退,完成。
      • if (PARAMETER_ELEMENT.equals(localName) && depth == 1)
        • 如果这是一个参数,那么确保我们准备好了。
        • 检查我们是否在正确的上下文中。
        • 获取并处理参数名,完成。
      • if (depth < 2)
        • 错误的元素。
  • public void endElement(String uri, String localName, String qName)
    • 接收元素结束的通知。
    • 检查名称空间声明。
      • 如果相等,则include命名空间中嵌套元素的当前深度减1。
      • if (INCLUDE_ELEMENT.equals(localName) && depth == 0)
      • 当我们关闭include元素时,包含将在这里发生。
        • 结束忽略嵌套内容。
        • 获取打开元素和include时发现的源代码。
        • 并行处理检查,然后结束。
      • if (FALLBACK_ELEMENT.equals(localName) && depth == 1)
        • 结束缓冲回退内容,该元素已完成。
      • if (PARAMETER_ELEMENT.equals(localName) && depth == 1)
        • 存储参数名称和值,参数名和值是URL编码的,所以像"&“或”="(有特殊含义)这样的奇怪字符可以完美地传递,完成。
    • 如果不是我们的名称空间,请继续传递事件。
  • public void characters(char[] data, int offset, int length)
    • 接收字符通知。
    • 如果我们有一个要添加的参数值,让我们添加这个块。
  • 线程管理:
    • int incrementThreads()
      • 活动线程递增计数器。
    • void decrementThreads()
      • 活动线程递减计数器。
    • private void waitForThreads()
      • 等待直到没有活跃线程。
      • 如果线程数目大于0,就在日志里进行记录,并等待。

3.其他说明:

一个在内部类里的内部类:

在单独的线程中加载包含源的缓冲区。只有当源完全加载时,才可能对加载的缓冲区进行流处理。如果加载未完成,toSAX方法将阻塞。

private class IncludeBuffer extends SaxBuffer implements Runnable {
    private IncludeElement element;
    private int thread;
    private boolean finished;
    private SAXException e;
    //构造函数
    public IncludeBuffer(IncludeElement element) {
        this.element = element;
        RunnableManager runnable = null;
        try {
            runnable = (RunnableManager) IncludeTransformer.this.manager.lookup(RunnableManager.ROLE);
            runnable.execute(IncludeTransformer.this.threadPool, this);
        } catch (final ServiceException e) {
            //以防我们无法生成一个线程
            throw new CascadingRuntimeException(e.getMessage(), e);
        } finally {
            IncludeTransformer.this.manager.release(runnable);
        }
        //递增活动线程计数器
        this.thread = incrementThreads();
    }
    //将源的内容加载到这个缓冲区中。
    public void run() {
        try {
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Thread #" + thread + " loading <" + element.source + ">");
            }
            //设置这个线程的环境
            RequestContextHolder.setRequestAttributes(attributes);
            EnvironmentHelper.enterProcessor(processor, environment);
            try {
                element.process(this);

            } catch (SAXException e) {
                this.e = e;

            } finally {
                EnvironmentHelper.leaveProcessor();
                RequestContextHolder.resetRequestAttributes();
            }
        } catch (ProcessingException e) {
            //无法设置线程的环境
            this.e = new SAXException(e);
        } finally {
            synchronized (this) {
                this.finished = true;
                notify();
            }
            //确保活动线程计数器是递减的
            decrementThreads();
        }
        if (getLogger().isDebugEnabled()) {
            if (this.e == null) {
                getLogger().debug("Thread #" + thread + " loaded <" + element.source + ">");
            } else {
                getLogger().debug("Thread #" + thread + " failed to load <" + element.source + ">", this.e);
            }
        }
    }
    //该缓冲区的流内容时,它是完全加载。如果加载未完成,此方法将阻塞。
    public void toSAX(ContentHandler contentHandler)
    throws SAXException {
        synchronized (this) {
            if (!this.finished) {
                try {
                    wait();
                } catch (InterruptedException e) { /* ignored */ }
                // Don't continue waiting if interrupted.
            }
        }
        if (this.e != null) {
            throw this.e;
        }
        super.toSAX(contentHandler);
    }
}

4.关键字synchronized

synchronized是Java中的关键字,被Java原生支持,是一种最基本的同步锁。
它修饰的对象有以下几种:

1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象。
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象。
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

标签:core,2021SC,void,private,boolean,线程,Cocoon,public,String
来源: https://blog.csdn.net/weixin_47933850/article/details/121175833

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有