这是我在ToolTip Performance in XPages上一篇文章的后续内容。我已经编写了代码(未经过测试),所以我似乎无法让我的Managed Bean得到正确的调用。我的配置包含以下内容:
<managed-bean id="ToolTip">
<managed-bean-name>WFSToolTip</managed-bean-name>
<managed-bean-class>ca.workflo.wfsToolTip.ToolTipText</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
我已将代码剥离到最低限度:
package ca.workflo.wfsToolTip;
public class ToolTipText {
public String getToolTipText(String key){
return key;
}
}
我的班级在构建路径中。我有一个简单的XPage,其中有一个提交,并为该字段的工具提示。工具提示的代码是:
<xe:tooltip id="tooltip1" for="inputText1">
<xe:this.label>
<![CDATA[#{javascript:WFSToolTip.getToolTipText("More Stuff");}]]>
</xe:this.label>
</xe:tooltip>
当我在浏览器中加载测试XPage时,出现错误:
执行JavaScript计算表达式时出错 脚本解释器错误,line = 1,col = 12:在java类上调用方法'getToolTipText(string)'时出错'ca.workflo.wfsToolTip.ToolTipText'
JavaScript代码
1:WFSToolTip.getToolTipText(“更多东西”);
我无法弄清楚为什么对getToolTipText的调用会失败。
任何人都可以看到我出错的地方。这是我的第一个Managed Bean,目前它正在管理我而不是相反。
感谢。
答案 0 :(得分:5)
你需要: - 实现Serializable,归结为陈述并提供版本 - 实施地图......多做一点工作
然后使用表达式语言而不是SSJS。它看起来像#{WFSToolTip["More Stuff"]}
这就是这样一个类的样子。你需要:
WFSToolTip.clear();
(在SSJS中)。该示例不会延迟加载,因为通过视图导航器运行一次非常快。没有必要做所有这些查找。
你走了:
package com.notessensei.xpages;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import lotus.domino.Base;
import lotus.domino.Database;
import lotus.domino.NotesException;
import lotus.domino.View;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
import com.ibm.xsp.extlib.util.ExtLibUtil;
public class Parameters implements Serializable, Map<String, String> {
private final static String CONFIG_VIEW = "keywords";
private static final long serialVersionUID = 1L;
private final Map<String, String> internalMap = new HashMap<String, String>();
public Parameters() {
this.populateParameters(internalMap);
}
private void populateParameters(Map<String, String> theMap) {
Database d = ExtLibUtil.getCurrentDatabase();
try {
View v = d.getView(CONFIG_VIEW);
ViewEntryCollection vec = v.getAllEntries();
ViewEntry ve = vec.getFirstEntry();
ViewEntry nextVe = null;
while (ve != null) {
nextVe = vec.getNextEntry(ve);
// Load the parameters, column 0 is the key, column 0 the value
Vector colVal = ve.getColumnValues();
theMap.put(colVal.get(0).toString(), colVal.get(1).toString());
// Cleanup
this.shred(ve);
ve = nextVe;
}
// recycle, but not the current database!!!
this.shred(ve, nextVe, vec, v);
} catch (NotesException e) {
e.printStackTrace();
}
}
public void clear() {
this.internalMap.clear();
this.populateParameters(this.internalMap);
}
public boolean containsKey(Object key) {
return this.internalMap.containsKey(key);
}
public boolean containsValue(Object value) {
return this.internalMap.containsValue(value);
}
public Set<java.util.Map.Entry<String, String>> entrySet() {
return this.internalMap.entrySet();
}
public String get(Object key) {
return this.internalMap.get(key);
}
public boolean isEmpty() {
return this.internalMap.isEmpty();
}
public Set<String> keySet() {
return this.internalMap.keySet();
}
public String put(String key, String value) {
return this.internalMap.put(key, value);
}
public void putAll(Map<? extends String, ? extends String> m) {
this.internalMap.putAll(m);
}
public String remove(Object key) {
return this.internalMap.remove(key);
}
public int size() {
return this.internalMap.size();
}
public Collection<String> values() {
return this.internalMap.values();
}
private void shred(Base... morituri) {
for (Base obsoleteObject : morituri) {
if (obsoleteObject != null) {
try {
obsoleteObject.recycle();
} catch (NotesException e) {
// We don't care we want go get
// rid of it anyway
} finally {
obsoleteObject = null;
}
}
}
}
}
与常规HashMap的区别仅在于填充它的构造函数。希望澄清它。
答案 1 :(得分:0)
我从未见过那个id属性.. faces-config中的我的bean看起来像这样:
<managed-bean>
<managed-bean-name>CurrentJob</managed-bean-name>
<managed-bean-class>com.domain.inventory.Job</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
技术上托管的bean应该实现Serializable并且具有空白构造函数。所以你应该在里面有这样的东西:
public ToolTipText() {
}
我认为你可以在没有Serializable的情况下逃脱...我总是实现但是我确定你需要没有参数的构造函数。
答案 2 :(得分:0)
感谢所有回应和帮助的人,特别是Stephan Wissel。我以为我会发布我的Stephan代码版本,几乎一样。将类设置为ApplicationScope存在问题,因为您需要关闭HTTP任务以刷新并重新加载Class。我所做的是在自定义控件中添加了一个按钮,我在工具提示的视图中执行CRUD操作,在按钮中执行WFSToolTip()。clear()并重建地图。很简约。我的下一个任务是尝试使用JAVA进行CRUD并直接更新地图。目前虽然我需要继续我的下一个任务。 我的下一个任务围绕一个非常相似的类。我有一个包含所有基本设计和代码的主数据库。然后我有一个或多个使用该代码的应用程序,并将文档存储在自己的数据库中,该数据库包含该特定应用程序的表单和视图。在master中我创建了一个或多个应用程序文档。这些文档中的每一个都包含AppName(键值),然后Map值是一个数组(Vector),其中包含应用程序数据库的ReplicaID和一些其他信息。我的类为每个应用程序加载一个Map条目,并从几个地方收集有关应用程序的一堆其他信息,并将它们存储在Map Value中。此时我可以设置Database db = thisClass.getDatabase(“App Name”)。因此,单个自定义控件可用于任何/所有应用程序。很酷。我想我可以这样。 无论如何,这里是我用于工具提示的代码 - 顺便说一句,它已经使用了大约175个字段和100多个工具提示的XPage,从痛苦缓慢到可接受。关于它的好处是XPage正在创建一个流程配置文件,一旦创建它就不会经常被修改为管理操作 - 而不是日常用户操作。 请随意指出代码中的错误,提示或建议:
package ca.workflo.wfsToolTip;
import lotus.domino.Base;
import lotus.domino.Session;
import lotus.domino.Database;
import lotus.domino.View;
import lotus.domino.NotesException;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import com.ibm.xsp.extlib.util.ExtLibUtil;
public class ToolTipText implements Serializable, Map<String, String> {
private static final long serialVersionUID = 1L;
private Session s;
private String repID;
private Database db;
private Database helpDB;
private View helpView;
private ViewEntry ve;
private ViewEntry tVE;
private ViewEntryCollection veCol;
private final Map<String, String> internalMap = new HashMap<String, String>();
public ToolTipText() {
this.populateMap(internalMap);
}
private void populateMap(Map<String, String> theMap) {
try {
s = ExtLibUtil.getCurrentSession();
db = s.getCurrentDatabase();
repID = db.getProfileDocument("frmConfigProfile", "").getItemValue(
"WFSHelpRepID").firstElement().toString();
helpDB = s.getDbDirectory(null).openDatabaseByReplicaID(repID);
helpView = helpDB.getView("vwWFSToolTipHelp");
veCol = helpView.getAllEntries();
ve = veCol.getFirstEntry();
ViewEntry tVE = null;
while (ve != null) {
tVE = veCol.getNextEntry(ve);
Vector colVal = ve.getColumnValues();
theMap.put(colVal.get(0).toString(), colVal.get(1).toString());
recycleObjects(ve);
ve = tVE;
}
} catch (NotesException e) {
System.out.println(e.toString());
}finally{
recycleObjects(ve, tVE, veCol, helpView, helpDB);
}
}
public void clear() {
this.internalMap.clear();
this.populateMap(this.internalMap);
}
public boolean containsKey(Object key) {
return this.internalMap.containsKey(key);
}
public boolean containsValue(Object value) {
return this.internalMap.containsValue(value);
}
public Set<java.util.Map.Entry<String, String>> entrySet() {
return this.internalMap.entrySet();
}
public String get(Object key) {
try {
if (this.internalMap.containsKey(key)) {
return this.internalMap.get(key);
} else {
return "There is no Tooltip Help for " + key;
}
} catch (Exception e) {
return "error in tooltip get Object ";
}
}
public boolean isEmpty() {
return this.internalMap.isEmpty();
}
public Set<String> keySet() {
return this.internalMap.keySet();
}
public String put(String key, String value) {
return this.internalMap.put(key, value);
}
public void putAll(Map<? extends String, ? extends String> m) {
this.internalMap.putAll(m);
}
public String remove(Object key) {
return this.internalMap.remove(key);
}
public int size() {
return this.internalMap.size();
}
public Collection<String> values() {
return this.internalMap.values();
}
public static void recycleObjects(Object... args) {
for (Object o : args) {
if (o != null) {
if (o instanceof Base) {
try {
((Base) o).recycle();
} catch (Throwable t) {
// who cares?
}
}
}
}
}
}