Copy TpltEvwProvFtry.java to BBoardProvFtry.java
Change the copy's class name to BBoardProvFtry
We'll change global comments now, and the rest as we change the code.
Remove imports we won't be using:
Remove methods in the BBoardProvFtry main class:
Remove methods in the BBoardProvImp inner class:
Remove the MsgSender inner class
Remove fields in the BBoardProvFtry main class:
Remove fields in the BBoardProvImp inner class:
(There are a few other fields we'll remove later, but we'll keep them as place markers for now.)
When a service provider shares a service connector with other service providers, no two providers can use the same tag-value combination for the first pair in incoming messages. If they do, only one of the providers will get those messages.
BBoard will have three incoming messages, and each message will consist of a single tag-value pair.
Incoming Messages | |
---|---|
Tag | Value |
RqstRsrc | BBPosts |
AddBBPost | (Post text) |
RemBBPost | (Post ID) |
BBoard will have one outgoing message, it will have a header tag and two tag value pairs. The two tag value pairs are repeated, once for each bulletin board post.
Outgoing Message | ||||||
---|---|---|---|---|---|---|
Header | Post Block | Additional Post Blocks | ||||
Tag | Value | Tag | Value | Tag | Value | ... |
BBPosts | (empty) | BBPostID | (Post ID) | BBPost | (Post text) | (Repeat BBPostID,BBPost as needed) |
AddBBPost and RemBBPost are unique to BBoard, so the associated values can be anything we want, RqstRsrc is used by many providers, but we will only use it with a value of BBPosts, which is unique to BBoard.
Change the Tag-value constants to the ones we will be using
TAG_ADD_BB_POST = "AddBBPost"
TAG_REM_BB_POST = "RemBBPost"
TAG_BB_POSTS = "BBPosts"
TAG_BB_POST_ID = "BBPostID"
TAG_BB_POST = "BBPost"
Update tagList and rsrcList fields
Update getSupportedValues method
insert a case for the_ADD_BB_POST and TAG_REM_BB_POST tags
if (tag.equalsIgnoreCase(TAG_ADD_BB_POST) || tag.equalsIgnoreCase(TAG_REM_BB_POST))
return new TreeSet(Arrays.asList("*"));
Adjust the other SelfDescribing values
For getSupportedMedia we will keep the existing values.
For getMaxMsgSize we will increase the message size.
The BBPosts message could be fairly large, and we can't predict exactly how
large it might be. We'll set it to 16K and we can adjust it after we have used
BBProv for a while if we need to.
MAX_MSG_SIZE = 1024 * 16;
For suggestActivityTimeout we will increase the timeout.
A user might want to keep the bulletin board up for a while,
so we'll increase the timeout to 15 minutes. Again, we can adjust the value later if we
need to.
PREF_ACTIVITY_TMO = 900000;
init: The initial version of BBoard has no special initialization requirements, so we can leave init as it is.
newClient: No changes are needed.
quiesce: The initial version of BBoardProvImp doesn't start any threads
or hold any resources open, so no quiesce action is needed.
Remove the code that stopped the MsgSender threads in the template.
if (!activeImps.isEmpty())
block of code with
a // No action needed
comment and remove the imps and idx
variables.Adjust the constructor
activeImps.add(this);
line
Adjust the handleDisconnect method
BBoardProvImp instances don't hold any resources, so no action is needed
when a client disconnects.
if (debugging)
block// No action needed
commentAdjust the dispatchRqst method
toClient = chnl;
lineelse if (rqstPair[0].equalsIgnoreCase(TAG_ADD_BB_POST)) { }
else if (rqstPair[0].equalsIgnoreCase(TAG_REM_BB_POST)) { }
At this point our new class compiles without fatal errors, but it doesn't actually do anything. Most of the work we have left is implementing the actual BBoard function.
These fields will be accessed by all BBoardProvImp instances, so we have to guard against concurrent modification problems. (The SelfDescribing fields don't need to be protected because after the init method completes they never change.)
Create a global field to hold our bulletin board posts
We'll use a TreeMap of
testCount
field (and it's javadoc comment) withprivate SortedMap bbPosts =
Collections.synchronizedSortedMap(new TreeMap());
Create a global field to hold The last post ID that was created
We'll use a timestamp for post id's. If we decide we want to display post time
or remove posts after period of time, the ID allows us to do that.
We'll use this field to hold the last post ID generated.
It's a long integer, so we can't use a synchronized type to hold it.
We'll use a synchronized method to access it.
private long lastPostId = 0;
lineAdd a synchronized getNewId method to the BBoardProvFtry main class;
private synchronized String getNewId()
This method will use System.currentTimeMillis()
to get a
timestamp, and return it's value as a String.
There is also some code to handle the possibility that two timestamps are
generated in the same clock cycle. The new timestamp is compared with
lastPostId
and if it isn't greater it's changed to
lastPostId + 1
. There's also some code to handle the
even more unlikely case where a flood of timestamps are requested in the
same clock cycle.
Create a method to handle TAG_RQST_RSRC - TAG_BB_POSTS requests
public TvList getPostsMsg() { ... }
This method copies the contents of bbPosts
into the BBPosts
tag-value list that is returned the client. It's sorted last post first,
so the most recent posts appear at the top in the bulletin board.
Create a method to handle TAG_ADD_BB_POST requests
public void addPost(String postText) { ... }
This method gets a new post ID and adds the post
to the bbPosts
map, indexed by the id.
Create a method to handle TAG_REM_BB_POST requests
public void removePost(String postId) { ... }
This method removes the post identified by postId
from the
bbPosts
map.
Add calls to to the BBoardProvImp methods to the dispatchRqst method
chnl.putRec(getPostsMsg());
addPost(rqstPair[1]);
removePost(rqstPair[1]);
The code for addPost and removePost is so trivial we could have put it in the dispatchRqst method and avoided creating separate methods. We used separate methods because it separates the EventWeb code from the bulletin board code. Also, creating separate public methods allows other services in the same JRE to use direct function calls to access the bulletin board. (We may not need that for this serivce, but there are times when it's a useful feature.)
As it is, BBoardProvFtry lacks some features we'd like to have, but lets create the web client, deploy the application, and see it work before we add more features.