Developers are bigots.
Developers have certain ways of doing something, and they seek to control things just as much as anyone else. They agitate for their favorite languages. They oppose anything that sniffs of what they've had bad experiences with. And well, they can hurt their own software's usefulness by doing so.
I can recount the number of times (and I'm about to date myself) I've heard in the Domino market, how everything should be done from the C API, or the C++ API, then integrating libraries, DDE, OLE, then LotusScript (ie, BASIC), HTML/Javascript, Java, IIOP, SOAP, Web Services, Xpages, Javascript, XPath ... and Java again. Decades ago I used to agree.
Now I don't. That first sentence, it applies to me. Beware when I recommend a language is exclusively the right thing for a job.
I'm about to recommend a language. But I don't intend to make it exclusive. Quite the opposite, actually.
Formula language has been around ... a long time. In Domino it was originally intended to provide a kind of "Excel-like formula" language for the venerable Lotus Notes app. The language leaves something of a permanent footprint on every application. It's list-oriented, it's fast, it's a pretty limited-scope ... well, language. And it really is a lot like what you'd find in an Excel cell formula.
It turns out though, that in Excel, it's rather difficult to run a cell formula from say, VBA. It is not hard to do this at all in Domino.
Yesterday I wrote about how you could write a formula in a profile, and then run it in a form.
Well you can do that in an agent as well. BASIC's "Evaluate" call can launch a formula. Java's "Session.evaluate" will do the same, and Javascript can perform the same by calling it. In fact, even Formula language will ... run a formula, if that sounds redundant. "@Eval". Formula is really ubiquitous in your programming environment.
That's intended. Formula is quite capable of putting your code in touch with the fields and documents available to your code.
Now, many people will stop here and tell you, that Formula is not a good way to use, hard-coded into your Javascript, or Java, or BASIC. And it's true. "@ReplaceSubstring" should really be replaced with equivalent Javascript or Java, and not left there.
But as with Excel, there are reasons to let your users create their own formulas. The biggest reason is flexibility. Your application needs to be flexible, and handle changes to the organization without rewriting your code. Put in the right place, Formula allows you to give an application this power.
Put a formula in calculating a group name -- you can thank me later -- and you won't worry again about an office being merged, or a division being split, or a new division being added. It's because the bit of formula can change the everyday business rule for selecting the office. And when the rules change, the formula changes.
But, ugh, that Formula is in your code! Or is it? Check back yesterday. I put Formula into a profile. It's in the profile. Your admin could change the profile. Or you could. The point being, it doesn't cost another rollout, or regression test, or refactor, or recoding. It's simply a configuration change. It avoids all of the added testing and requirements definition and development. If you can make your code flexible, then your code becomes more reliable, requires less maintenance, and your customer is much happier. He's bought something more profitable.
And that profit is likely to come back to you, building more applications, and automating more of his business.
Developers have certain ways of doing something, and they seek to control things just as much as anyone else. They agitate for their favorite languages. They oppose anything that sniffs of what they've had bad experiences with. And well, they can hurt their own software's usefulness by doing so.
I can recount the number of times (and I'm about to date myself) I've heard in the Domino market, how everything should be done from the C API, or the C++ API, then integrating libraries, DDE, OLE, then LotusScript (ie, BASIC), HTML/Javascript, Java, IIOP, SOAP, Web Services, Xpages, Javascript, XPath ... and Java again. Decades ago I used to agree.
Now I don't. That first sentence, it applies to me. Beware when I recommend a language is exclusively the right thing for a job.
I'm about to recommend a language. But I don't intend to make it exclusive. Quite the opposite, actually.
Formula language has been around ... a long time. In Domino it was originally intended to provide a kind of "Excel-like formula" language for the venerable Lotus Notes app. The language leaves something of a permanent footprint on every application. It's list-oriented, it's fast, it's a pretty limited-scope ... well, language. And it really is a lot like what you'd find in an Excel cell formula.
It turns out though, that in Excel, it's rather difficult to run a cell formula from say, VBA. It is not hard to do this at all in Domino.
Yesterday I wrote about how you could write a formula in a profile, and then run it in a form.
Well you can do that in an agent as well. BASIC's "Evaluate" call can launch a formula. Java's "Session.evaluate" will do the same, and Javascript can perform the same by calling it. In fact, even Formula language will ... run a formula, if that sounds redundant. "@Eval". Formula is really ubiquitous in your programming environment.
That's intended. Formula is quite capable of putting your code in touch with the fields and documents available to your code.
Now, many people will stop here and tell you, that Formula is not a good way to use, hard-coded into your Javascript, or Java, or BASIC. And it's true. "@ReplaceSubstring" should really be replaced with equivalent Javascript or Java, and not left there.
But as with Excel, there are reasons to let your users create their own formulas. The biggest reason is flexibility. Your application needs to be flexible, and handle changes to the organization without rewriting your code. Put in the right place, Formula allows you to give an application this power.
Put a formula in calculating a group name -- you can thank me later -- and you won't worry again about an office being merged, or a division being split, or a new division being added. It's because the bit of formula can change the everyday business rule for selecting the office. And when the rules change, the formula changes.
But, ugh, that Formula is in your code! Or is it? Check back yesterday. I put Formula into a profile. It's in the profile. Your admin could change the profile. Or you could. The point being, it doesn't cost another rollout, or regression test, or refactor, or recoding. It's simply a configuration change. It avoids all of the added testing and requirements definition and development. If you can make your code flexible, then your code becomes more reliable, requires less maintenance, and your customer is much happier. He's bought something more profitable.
And that profit is likely to come back to you, building more applications, and automating more of his business.
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database db;
Document profile = session.getCurrentDatabase().getProfileDocument("profile", null);
//use the profiled entries to find the view configured
db = session.getDatabase(session.getCurrentDatabase().getServer(), profile.getItemValueString("dbpath"));
if(profile.getItemValueString("viewname") == "") return;
View vw = db.getView(profile.getItemValueString("viewname"));
if (profile.getItemValueString("keyformula") == "") return;
//Evaluate the key formula to determine what to search for
DocumentCollection coll = agentContext.getUnprocessedDocuments();
Document doc = coll.getFirstDocument();
Vector vkey = session.evaluate(profile.getItemValueString("keyformula"), doc);
//now get the keyed documents
ViewEntryCollection vec = vw.getAllEntriesByKey(vkey, true);
//cycle through the results
Vector valuearray = null;
ViewEntry ve = vec.getFirstEntry();
while (ve != null) {
Document curdoc = ve.getDocument();
if (curdoc.hasItem(profile.getItemValueString("fieldname"))) {
//accumulate the data requested by the configuration
if (valuearray == null) {
valuearray = curdoc.getItemValue(profile.getItemValueString("fieldname"));
} else {
valuearray.add(curdoc.getItemValue(profile.getItemValueString("fieldname")));
}
}
ViewEntry venext = vec.getNextEntry(ve);
ve.recycle();
ve = venext;
curdoc.recycle();
}
//list out the array
if (valuearray != null) {
int ii;
for (ii = 0; ii < valuearray.size(); ++ii) {
System.out.print(valuearray.toString());
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database db;
Document profile = session.getCurrentDatabase().getProfileDocument("profile", null);
//use the profiled entries to find the view configured
db = session.getDatabase(session.getCurrentDatabase().getServer(), profile.getItemValueString("dbpath"));
if(profile.getItemValueString("viewname") == "") return;
View vw = db.getView(profile.getItemValueString("viewname"));
if (profile.getItemValueString("keyformula") == "") return;
//Evaluate the key formula to determine what to search for
DocumentCollection coll = agentContext.getUnprocessedDocuments();
Document doc = coll.getFirstDocument();
Vector vkey = session.evaluate(profile.getItemValueString("keyformula"), doc);
//now get the keyed documents
ViewEntryCollection vec = vw.getAllEntriesByKey(vkey, true);
//cycle through the results
Vector valuearray = null;
ViewEntry ve = vec.getFirstEntry();
while (ve != null) {
Document curdoc = ve.getDocument();
if (curdoc.hasItem(profile.getItemValueString("fieldname"))) {
//accumulate the data requested by the configuration
if (valuearray == null) {
valuearray = curdoc.getItemValue(profile.getItemValueString("fieldname"));
} else {
valuearray.add(curdoc.getItemValue(profile.getItemValueString("fieldname")));
}
}
ViewEntry venext = vec.getNextEntry(ve);
ve.recycle();
ve = venext;
curdoc.recycle();
}
//list out the array
if (valuearray != null) {
int ii;
for (ii = 0; ii < valuearray.size(); ++ii) {
System.out.print(valuearray.toString());
}
}
} catch(Exception e) {
e.printStackTrace();
}
}