ICode9

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

2021SC@SDUSC【软件工程应用与实践】Cocoon代码分析(十三)

2021-12-13 20:02:33  阅读:131  来源: 互联网

标签:return 2021SC SDUSC new path Cocoon null final String


2021SC@SDUSC

这是我的第十三篇博客,分析的代码还是sitemap-impl文件夹下的内容,这一次我选择了三个文件夹,第一个是classloader文件夹,顾名思义这可能与类的加载有关;另一个文件夹——matching进行分析,这个文件夹里有3个抽象的类;最后一个是objectmodel文件夹。由于考虑到分析代码要选择重要的分析,所以我可能会挑选部分代码进行分析。

文章目录

classloader

AbstractClassLoaderFactory.java

这个java类文件实现了ClassLoaderFactory接口的抽象实现。它同时接受类目录和jar目录配置。还可以指定通配符模式来包含或排除要在类加载器中加载的某些类。在这种情况下,类直接从父类加载器加载。默认是包含所有类。

主要有四个方法:

1.createClassLoader()——重载,创建类加载器

public ClassLoader createClassLoader(ClassLoader              parent,
                                     ClassLoaderConfiguration config,
                                     ServletContext           servletContext)
throws Exception {
    final List urlList = new ArrayList();
    Iterator i;
    i = config.getClassDirectories().iterator();
    while ( i.hasNext() ) {
        final String directory = (String)i.next();
        URL url = this.getUrl(servletContext, directory);
        if ( url == null ) {
            throw new Exception("Directory not found for classpath: " + directory);
        }
        if ( !url.toExternalForm().endsWith("/") ) {
            url = new URL(url.toExternalForm() + "/");
        }
        urlList.add(url);
    }
    i = config.getLibDirectories().iterator();
    while ( i.hasNext() ) {
        final String directory = (String)i.next();
        final File libDir = this.getFile(directory);
        if ( libDir != null ) {
            if ( !libDir.exists() ) {
                throw new Exception("Directory for lib class path does not exists: " + libDir);
            }
            if ( !libDir.isDirectory() ) {
                throw new Exception("Configuration for lib class path is not a directory: " + libDir);
            }
            File[] libraries = libDir.listFiles(new JarFileFilter());
            Arrays.sort(libraries);
            for (int m = 0; m < libraries.length; m++) {
                final URL lib = libraries[m].toURL();
                urlList.add(lib);
            }                
        } else {
            if ( directory.indexOf(":/") > 0 ) {
                throw new Exception("Can't handle absolute url as lib class path: " + directory);
            }
            final String contextPath = this.getContextPath(directory);
            final Set resources = servletContext.getResourcePaths(contextPath + '/');
            if ( resources != null ) {
                final List temporaryList = new ArrayList();
                final Iterator iter = resources.iterator();
                while ( iter.hasNext() ) {
                    final String path = (String)iter.next();
                    if (path.endsWith(".jar") || path.endsWith(".zip")) {
temporaryList.add(servletContext.getResource(path));
                    }
                }
                Collections.sort(temporaryList, new UrlComparator());
                urlList.addAll(temporaryList);
            }
        }
    }
    URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);    
    return this.createClassLoader(urls, config.getIncludes(), config.getExcludes(), parent);
}
//重载
protected abstract ClassLoader createClassLoader(URL[] urls, List includePatterns, List excludePatterns, ClassLoader parent);

2.getContextPath()——得到上下文的路径

protected String getContextPath(String path) {
    if ( path.startsWith("context://") ) {
        return path.substring(9);
    }
    return "/" + path;        
}

3.getFile()——通过路径得到文件

protected File getFile(String path) 
throws MalformedURLException {
    if ( path.startsWith("file:") ) {
        return new File(path.substring(5));
    }
    if ( path.startsWith("/") || (path.length() > 2 && path.charAt(1) == ':' )) {
        return new File(path);
    }
    return null;
}

4.grtURL()——方法内调用了getFile()方法,用于获得URL

protected URL getUrl(ServletContext servletContext, String path) 
throws MalformedURLException {
    final File file = this.getFile(path);
    if ( file != null ) {
        return file.toURL();
    }
    if ( path.indexOf(":/") > 0 ) {
        return new URL(path);
    }
    return servletContext.getResource(this.getContextPath(path));
}

DefaultClassLoader.java

这个类加载器反转类的搜索顺序。它在检查它的父类之前检查这个类装入器。此外,还可以配置包含和排除。

重要方法:

1.addDirectory()——用于添加类文件目录:

public final void addDirectory(File file) throws IOException {
    this.addURL(file.getCanonicalFile().toURL());
}

2.addURL()用于添加一个新的URL:

public void addURL(URL url) {
    super.addURL(url);
}

3.getResource()——用于从这个类加载器获取资源:

从这个ClassLoader中获取资源。如果这个资源不存在,我们就检查父资源。请注意,这与ClassLoader规范完全相反,我们使用它来处理来自第三方供应商的不一致的类装入器。

public final URL getResource(final String name) {
    URL resource = findResource(name);
    ClassLoader parent = this.getParent();
    if (resource == null && parent != null) {
        resource = parent.getResource(name);
    }

    return resource;
}

4.loadClass()——用于从这个类加载器加载类:

从这个ClassLoader中加载类。如果这个类不存在,我们就检查父类。请注意,这与ClassLoader规范完全相反,我们使用它来处理来自第三方供应商的不一致的类装入器。

public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
    //首先检查它是否已经加载
    Class clazz = findLoadedClass(name);
    if (clazz == null) {      
        final ClassLoader parent = getParent();
        if (tryClassHere(name)) {
            try {
                clazz = this.getClass(name);
            } catch (ClassNotFoundException cnfe) {
                if (parent == null) {
                    //传播异常
                    throw cnfe;                        
                }
            }
        }
        if (clazz == null) {
            if (parent == null) {
                throw new ClassNotFoundException(name);
            } else {
                //将抛出一个ClassNotFoundException异常如果没有在父类中发现
                clazz = parent.loadClass(name);
            }
        }
    }
    if (resolve) {
        resolveClass(clazz);
    }
    return clazz;
}

NotifyingResourceStore.java

这是classloader文件夹下的reloading文件夹里的一个java类文件。

将配置的所有存储打包到站点地图类加载器中,以便将通知事件分派给树处理程序,并强制在cocoon TODO Extend TransactionalResourceStore中重新加载组件(如果存储不是私有的)。

matching

类的名称类的说明
AbstractPreparableMatcher一个匹配器,可以在站点地图设置期间准备模式,以便在请求时更快地匹配。
AbstractRegexpMatcher使用正则表达式模式的所有匹配器的基类。
AbstractWildcardMatcher通配符匹配器的基类

AbstractPreparableMatcher.java

这也是一个常规的匹配器,这意味着站点地图可以决定是准备模式还是匹配请求时评估的模式。

里面写了一个唯一的方法——match()通过准备模式并匹配准备好的模式来匹配模式。

public Map match (String pattern, Map objectModel, Parameters parameters)
throws PatternException {
    return preparedMatch(preparePattern(pattern), objectModel, parameters);
}

AbstractRegexpMatcher.java

在这个类文件里,主要有3个方法。

1.preparePattern()——将准备好的模式与getMatchString(Map, Parameters)返回的值进行匹配。

public Object preparePattern(String pattern) throws PatternException {
    //如果pattern为空,返回null以允许在preparedMatch()中抛出定位异常
    if (pattern == null) {
        return null;
    }
    if (pattern.length() == 0) {
        pattern = "^$";
        if (getLogger().isWarnEnabled()) {
            getLogger().warn("The empty pattern string was rewritten to '^$'" + " to match for empty strings.  If you intended"+ " to match all strings, please change your"+ " pattern to '.*'");
}
    }
    try {
        RECompiler compiler = new RECompiler();
        REProgram program = compiler.compile(pattern);
        return program;
    } catch (RESyntaxException rse) {
        getLogger().debug("Failed to compile the pattern '" + pattern + "'", rse);
        throw new PatternException(rse.getMessage(), rse);
    }
}

2.preparedMatch()——根据getMatchString(Map, Parameters)返回的值匹配准备好的模式。

public Map preparedMatch(Object preparedPattern, Map objectModel, Parameters parameters) throws PatternException {
    if(preparedPattern == null) {
        throw new PatternException("A pattern is needed at " + SitemapParameters.getLocation(parameters));
    }
    RE re = new RE((REProgram)preparedPattern);
    String match = getMatchString(objectModel, parameters);
    if (match == null)
        return null;
    if(re.match(match)) {
        int parenCount = re.getParenCount();
        Map map = new HashMap();
        for (int paren = 0; paren <= parenCount; paren++) {
            map.put(Integer.toString(paren), re.getParen(paren));
        }
        return map;
    }
    return null;
}

3.getMatchString()——根据正则表达式获得要测试的字符串。由具体的子类定义。

protected abstract String getMatchString(Map objectModel, Parameters parameters);

AbstractWildcardMatcher.java

主要有两个比较重要的方法:

1.match()——将准备好的模式与getMatchString(Map, Parameters)的结果进行匹配。

public Map match(String pattern, Map objectModel, Parameters parameters) throws PatternException {
    if (pattern == null) {
        throw new PatternException("A pattern is needed at " + SitemapParameters.getLocation(parameters));
    }
    final String match = getMatchString(objectModel, parameters);
    if (match == null) {
        return null;
    }
    return WildcardMatcherHelper.match(pattern, match);
}

2.getMatchString()——根据通配符表达式获取要测试的字符串。

protected abstract String getMatchString(Map objectModel, Parameters parameters);

objectmodel

objectmodel文件夹内一共有两个文件夹,一个是helpe,另一个是impl。这两个文件内各有一个java文件,分别为ParametersMap.java和CocoonEntryObjectModelProvider.java

类的名称类的说明
ParametersMap.java通过Map接口公开参数的Parameters类的包装器类。如果想在ObjectModel中放置参数,请使用此包装器。
CocoonEntryObjectModelProvider.java这是提供Concoon的入口文件。

标签:return,2021SC,SDUSC,new,path,Cocoon,null,final,String
来源: https://blog.csdn.net/weixin_47933850/article/details/121906924

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

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

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

ICode9版权所有