Using Java Enumerations With Domino
Recently I found myself writing a Java-based Agent in Domino for the first time in a year or more and found myself doing things I'd not thought possible the last time I did.
Until two or three years ago the extent of my "programming" was that I could write Agents which contained simple where, while and if statements. Inside there I'd be calling some .replaceItemValue() and .save() methods. That was about as complicated as it got.
Things only ever got any more complex than that if I stepped away from LotusScript and in to Java Agents. I'd do this only when I needed to. When I was creating PDFs, Zip files or generating images on the fly. Things got a bit more complicated then but all I'd ever be doing is figuring out how to use an existing API. Again, not what you'd call programming.
I never felt like I did any actual programming until I stepped outside Domino and in to C# and ASP.NET development a few years back. Since using C# and reading a few books I'm starting to gain a better understanding and appreciation of the finer aspects of coding.
One of the things I did in the Domino Java Agent was use as enumeration (enum). As an example let's use one to define the various workflow statuses a Notes document can pass through.
Here's the enum definition:
private enum WorkflowStatus { UNKNOWN("Unknown", "The document hasn't yet entered an approval cycle"), IN_PROCESS("Awaiting Approval", "There are still approvers in the loop"), APPROVED("Approved", "This document has been approved"), DECLINED("Declined", "This document was declined"); private final String value; private final String detail; private WorkflowStatus(String value, String detail) { this.value = value; this.detail = detail; } public static WorkflowStatus findByValue(String value) { if(value != null) { for(WorkflowStatus status : values()) { if(status.value.equals(value)) { return status; } } } return WorkflowStatus.UNKNOWN; } /** * @return the value */ public String getFieldValue() { return value; } /** * @return the detail */ public String getDetail() { return detail; } }
You can use it in a WQS Agent's Java code like this:
public class JavaAgent extends AgentBase { public void NotesMain() { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); Database database = session.getCurrentDatabase(); Document document = agentContext.getDocumentContext(); WorkflowStatus status = WorkflowStatus.findByValue( document.getItemValueString("Status") ); switch (status){ case IN_PROCESS: if (document.getItemValueString("AwaitingApprovalBy").equals("")){ status = WorkflowStatus.APPROVED; } break; case APPROVED: status = WorkflowStatus.DECLINED; break; case UNKNOWN: status = WorkflowStatus.IN_PROCESS; break; } document.replaceItemValue("Status", status.getFieldValue()); } }
Obviously this isn't real code (it makes no sense to decline an approved document!). It's just to show how the code can utilise the enum.
You could take this further and store a integer value in the backend document, so that you never actually store a string as the status. If you then need to change the definition of a status it becomes a lot easier.
To a degree I've never known whether avoiding hard-coding is really worth it with Domino? More often than not a document is only ever saved and processed using the same WQS Agent. It's only when there's code in multiple places that something like the above enum becomes worth it.
But still, it's all good practise. Using the code above feels a whole lot better than the alternative of scattering string representations of your statuses all over the code.
Another thing I did in the Java Agent was move all strings to the top of the code (things like messages displayed to the user) and defined them as static constants. This way it's easier for me (and future developers) to come and make quick changes without having to sift through all the code.
It's entirely possible I've misplaced half my brain today, so bear with me.
It looks to me like you're using an enum as an object / class. My (perhaps limited) understanding of the reasons for and uses of enums were limited to a list (enumeration) of related bits of information.
eg
private enum Connection
int port = 80;
int ssl = 443;
String domain = "codestore.net";
String uri = "";
end enum
Thus providing a convenient container and nothing more. So it's interesting to me that your enum has methods. I suppose there's nothing saying they can't but it seems then an odd choice of pattern over use of a class.
Reply
Must be peculiar to Java I guess. I used them a lot in C# but only in a simple way like you example.
Reply
Show the rest of this thread
Been doing a lot of Domino Java work lately, too -- this I learned today: ".equals("")"
Been using !isEmpty() up until now. :P
Reply
See Peter Haggar's commentary on .equals, ==, ===, etc. in Practical Java. Good read on the subject.
Reply
shouldn't "return TransactionStatus.UNKNOWN;"
be "return WorkflowStatus.UNKNOWN;" ?
Reply
Woops. Yeah, you're right. That's what happens when you re-write code in a text editor. Will fix now.
Reply
oops,
shouldn't "return TransactionStatus.UNKNOWN;"
be "return status.UNKNOWN;" ?
I find the in line definition of variables in Java to be somewhat off putting..
Reply
Nope. You were right first time.
Reply
I've used the blessings of Java in Domino development for quite a while. About two years ago we faced a complex requirement we had to implement a solution for. The attempted approach cried for a event broker / event bus implementation which is truly a pain in the .... to implement in LotusScript.
So we switched to Java and used Reflection to register any objects that need to be notified whenever an event is posted on the broker / bus. Always remember, however, to alter the java.policy file on the server to enable use of Reflection.
The coupling of Formula / LotusScript frontend - Java Backend was kind of quirky at first, but when we got Webservice Providers and Consumers within Lotus Domino it worked like a charm implementing the Java (server) side as provider and the LotusScript (client) end as consumer. This way the bridge between the two languages is provided by Notes/Domino. Works very well.
Ever since this experience I try to implement as much as I can in Java, it's just so much easier and direct to work with. The only thing I don't like at all is having to recycle every single Domino object you created in order to avoid memory leaking.
Reply
Recycling in java is always required though right, not just in Domino?
Reply
Show the rest of this thread