2021SC@SDUSC
sitemap-impl文件夹分析(1)
本次代码主要解析的是sitemap-impl文件夹下的components文件夹
AbstractInterpreter.java
1、总结
- Cocoon 用于流量控制的各种脚本语言的抽象超类。 定义一些有用的行为,例如在脚本文件被修改时重新加载脚本文件的能力(在进行开发时很有用),并将控制权传递给 Cocoon 的站点地图以生成结果页面
- 属于不同站点地图的流解释器应该被隔离。 为了实现这一点,类实现了 SingleThreaded。 由于站点地图引擎在站点地图构建时查找流程解释器一次,这确保每个站点地图将使用此类的不同实例。 但是该实例将处理给定站点地图的所有流调用,因此必须是线程安全的
- 继承自org.apache.cocoon.util.AbstractLogEnabled
实现了Serviceable, Contextualizable, org.apache.cocoon.components.flow.Interpreter, SingleThreaded, Configurable, Disposable接口
2、主要属性:
//此解释器的实例 ID,用于标识用户范围
private String instanceID;
//是否应该重新加载脚本。 通过 flow.xmap 中的“reload-scripts”属性指定
protected boolean reloadScripts;
//两次检查修改过的脚本文件之间的间隔。 通过 flow.xmap 中的“check-time”XML 属性指定
protected long checkTime;
//需要解析的源位置列表
protected ArrayList needResolve = new ArrayList();
3、方法
public void setInterpreterID(String interpreterID)
- 设置此解释器的唯一 ID,可用于区分附加到会话的用户值范围
public void register(String source) {
synchronized (this) {
needResolve.add(source);
}
}
- 向解释器注册一个源文件。 使用此方法,实现会跟踪所有已编译的脚本文件。 这允许他们重新加载在文件系统上修改的脚本文件
- 解释器对脚本文件的解析/编译分两个阶段进行。 在第一阶段,文件的位置在needResolve 数组中注册。
- 只有当 Cocoon 环境传递给解释器时,第二种才有可能。 这允许使用 Cocoon 的 SourceFactory 类来解析文件位置
- 一旦可以解析文件的位置,就会将其从 needResolve 数组中删除并放入脚本哈希表中。 这个哈希表中的键是文件位置字符串,值是一个 DelayedRefreshSourceWrapper 实例,用于跟踪文件何时需要重新读取
- 参数source:脚本的位置
public synchronized final void refresh() {
this.nextCheckTime = System.currentTimeMillis() + this.delay;
// 调用refresh(),刷新可修改源
this.source.refresh();
// 保留上次修改日期
this.lastModified = source.getLastModified();
}
- 强制刷新包装的 Source ,即使刷新期未结束,并开始新的时期
- 此方法是线程安全的,即使底层 Source不是
ContinuationsManagerImpl.java
1、总结
ContinuationsManager 的默认实现,有两种工作模式:
- 标准模式 - 延续存储在单个持有人中。没有安全性应用于继续查找,任何人都可以只知道 ID 来调用延续。 将“session-bound-continuations”配置选项设置为 false 以激活此模式
- 安全模式 - 每个会话都有自己的延续持有者。延续仅对为其创建的同一会话有效,会话失效也会导致所有绑定的延续失效。将此设置用于 Web 应用程序。 将“session-bound-continuations”配置选项设置为 true 以激活此模式
继承自org.apache.cocoon.util.AbstractLogEnabled
实现了 Configurable, ThreadSafe, Serviceable, Contextualizable接口
2、主要属性
//用于创建连续 ID 的随机数生成器
protected SecureRandom random;
protected byte[] bytes;
//自上次访问以来,内存中的延续存在时间。时间以毫秒为单位,默认为 1 小时
protected int defaultTimeToLive;
//维护 WebContinuation 树的森林
//此集合仅用于 displayAllContinuations()方法的调试
protected Set forest = Collections.synchronizedSet(new HashSet());
//主要延续持有人,除非延续存储在用户会话中,否则使用
protected WebContinuationsHolder continuationsHolder;
//WebContinuation 实例的排序集,基于它们的到期时间,后台线程使用它来使延续无效
protected SortedSet expirations = Collections.synchronizedSortedSet(new TreeSet());
protected boolean bindContinuationsToSession;
protected long expirationCheckInterval;
3、方法
protected void handleLeafContinuationExpiration(WebContinuation wk)
- 当在
createWebContinuation(Object, WebContinuation, int, String, ContinuationsDisposer)
中创建新的延续时,它会注册到到期集中,以便由失效机制进行评估
protected void handleParentContinuationExpiration(WebContinuation parent)
- 当在
createWebContinuation(Object, WebContinuation, int, String, ContinuationsDisposer)
中创建新的延续时,其父延续将从到期集中删除。这样,只有叶子延续是到期集的一部分
protected WebContinuation generateContinuation(Object kont,
WebContinuation parent,
int ttl,
String interpreterId,
ContinuationsDisposer disposer) {
char[] result = new char[bytes.length * 2];
WebContinuation wk;
WebContinuationsHolder continuationsHolder = lookupWebContinuationsHolder(true);
while (true) {
random.nextBytes(bytes);
for (int i = 0; i < CONTINUATION_ID_LENGTH; i++) {
byte ch = bytes[i];
result[2 * i] = Character.forDigit(Math.abs(ch >> 4), 16);
result[2 * i + 1] = Character.forDigit(Math.abs(ch & 0x0f), 16);
}
final String id = new String(result);
synchronized (continuationsHolder) {
if (!continuationsHolder.contains(id)) {
if (this.bindContinuationsToSession)
wk = new HolderAwareWebContinuation(id, kont, parent,
ttl, interpreterId, disposer,
continuationsHolder);
else
wk = new WebContinuation(id, kont, parent, ttl,
interpreterId, disposer);
continuationsHolder.addContinuation(wk);
break;
}
}
}
wk.setLogger(getLogger());
return wk;
}
- 创建 WebContinuation 并为其生成唯一标识符。 标识符是使用加密算法生成的,以防止人们生成自己的标识符
- 它具有将延续对象插入到 idToWebCont 哈希表中的副作用
- 参数kont:表示延续的 Object 值
- 参数parent:表示父 WebContinuation 的值
- 参数ttl:WebContinuation的生存时间
- 参数interpreterId:调用连续创建的解释器的 id
- 参数disposer:用于清理延续的 ContinuationsDisposer 实例
- 返回:生成的具有唯一标识符的 WebContinuation
protected void removeContinuation(WebContinuationsHolder continuationsHolder,
WebContinuation wk) {
if (wk.getChildren().size() != 0) {
return;
}
// 删除对这个 contination 的访问
disposeContinuation(continuationsHolder, wk);
_detach(wk);
if (getLogger().isDebugEnabled()) {
getLogger().debug("WK: Deleted continuation: " + wk.getId());
}
// 现在检查是否需要删除父级
WebContinuation parent = wk.getParentContinuation();
if (null != parent && parent.hasExpired()) {
//父级必须具有相同的延续持有者,不需要查找 removeContinuation(continuationsHolder, parent);
}
}
- 从其延续树中删除过期的叶子 WebContinuation 节点,如果它们已过期且没有(其他)子节点,则递归删除其父节点
- 调用
_detach()
将此延续与父级分离。此方法从森林集合中删除连续性,或者,如果它有父级,则从父级的子级集合中删除 - 调用
disposeContinuation(continuationsHolder, wk
)使继续无法访问以进行查找,并通过 ContinuationsDisposer 接口触发可能需要的清理代码
protected void invalidateContinuations(WebContinuationsHolder continuationsHolder)
- WebContinuationsHolder 用于通知 continuation 管理器有关会话失效的方法。 使传递的 continuationsHolder 持有的所有延续无效
- 该方法中避免了 ConcurrentModificationException,这仍然不是最好的解决方案,应该改变
4、构造器
public HolderAwareWebContinuation(String id,
Object continuation,
WebContinuation parentContinuation,
int timeToLive,
String interpreterId,
ContinuationsDisposer disposer,
WebContinuationsHolder continuationsHolder) {
super(id, continuation, parentContinuation, timeToLive, interpreterId, disposer);
this.continuationsHolder = continuationsHolder;
}
FlowHelper.java
1、总结
提供流控制器层和视图层之间的接口
视图可以获取流脚本发送的上下文对象和当前的 Web 延续(如果有)
2、主要属性
定义对象模型中用于存储各种对象的键的常量。 这些常量是私有的,因此对这些对象的访问只能通过下面提供的访问器
这些对象存储在对象模型中而不是作为请求属性存储,因为对象模型是为子请求克隆的(请参阅 EnvironmentWrapper),而请求属性在“真实”请求及其所有子请求之间共享
//用于存储流上下文的请求属性名称
private static final String CONTEXT_OBJECT = "cocoon.flow.context";
//用于存储流延续的请求属性名称
private static final String CONTINUATION_OBJECT = "cocoon.flow.continuation";
3、方法
public final static Object getContextObject(Map objectModel)
- 获取与当前请求关联的流上下文对象
- 参数objectModel:Cocoon 环境的对象模型
public final static void setContextObject(Map objectModel, ObjectModel newObjectModel, Object obj)
- 设置与当前请求关联的流上下文对象
- 参数objectModel:Cocoon 环境的对象模型
- 参数obj:上下文对象