The enemy of my enemy is my customer

Posted in Stu Stern on December 4th, 2008 by Stu Stern

Stu Stern originally posted this on Big Gorilla - Stu Stern's Blog.

If you're new here, this post is part of a more-or-less continuous train-of-thought that begins here.

Today we continue looking at query expressions, which I introduced with much hullabaloo last time, but have thus far only given you the smallest taste. The glutinous among you are surely clamoring for more. So let's eat. But please stop using that use case diagram as a napkin. (Javadoc is much more absorbent).

Sarge has for the first time invited us to the headquarters of Arms4Less.com. After our blindfolds have been removed and our hands untied, we find ourselves seated around a large conference table in a windowless room. Charts around the wall show sales projections and troop strength estimates for the various markets Arms4Less is targeting over the next twelve months.

Last time we looked at how we can derive a value (isTrusted) using a query expression. Let's consider another such example. Sarge explains to us that Arms4Less prides itself on its high ethical standards. "Like if we sell a particular model of tank to one guy, for a small surcharge of 10%, we won't sell the same kinda tank to any of his enemies." We consider this requirement and realize that we need to prevent a customer from ordering any product that has been previously ordered by any of the customer's enemies. Now many of you are probably wonder how the heck we can express something like this on a lowly class diagram. Doesn't this require a more procedurally-oriented specification? Something with a little more get-up-and-go than a class diagram? Class diagrams just lay there, you say. We need something that moves, don't we?

Ha! I laugh at you (with all due respect of course). Do you think I would have wasted this much time blogging about this crap if we could go no further? Consider our latest version of the precision model, below:



We have added a new association, enemies, to keep track of a customer's enemies, and we have added a derived association called enemyProducts that references all the products purchased by a customer's enemies. Let me clarify a few things about "derived associations". First, you may be scratching your head about why we're calling enemyProducts an association at all, since it's not represented by a line on our class diagram. Notice however the type of the enemyProducts attribute. It's a Product. (In fact, as we'll discuss another time, it's a list of Products.)

There are multiple ways of representing associations in UML. For example, the following two representations are virtually equivalent.






On top, we see that the Employee has a BattleInjury reference called injuries. We see exactly the same thing with the Employee representation on the bottom, which contains a BattleInjury reference as well. The only difference is the notation being used. On the top we depict the reference with a composite association named injuries, whereas on the bottom, we decpict the reference with a nested attribute, also called injuries.

A derived association then is simply a derived attribute whose formula evaluates to a list of entities of some type. Let's look at the derivation expression for enemyProducts:

enemies.orders.items[isExclusive].product

In evaluating the value of this expression for a particular customer, we navigate through the customer's associated enemies, to their orders and then to the order's associated items. We then subset (query) the orders to select out those for which enemies have opted for an exclusive deal, and then we navigate from this resulting set to their associated products. The resulting list of products are the ones that we can't sell to the Customer.

The astute reader (or at least most who weren't out drinking last night) will have noticed we're essentially navigating multiple paths in parallel when we navigate enemies.orders.items since a customer can have many enemies, each in turn having many orders, and each of those orders having many items. The expression "unions" the results of navigating these parallel paths.

Now, you may recall earlier in this tirade we talked about the importance of precision. In fact, recall that all these techniques we're using comprise a methodology called Precision Modeling. You can rest assured that I'm not just whipping out arbitrary syntax for each of the formulas we've used. All of them are expressed with a formal expression language that are part of what we call Gorilla UML (GUML).

GUML not only has formal syntax definition. It executes! (Sarge says, "Cool! I execute too!") More on execution later. In our next little visit together, we'll actually look at using GUML to specify constraints. Using constraints we can complete our specification of Sarge's business rule preventing a product being sold to a customer's enemies.

The Axis of e-Ville

Posted in Stu Stern on December 2nd, 2008 by Stu Stern

Stu Stern originally posted this on Big Gorilla - Stu Stern's Blog.

Having looked at how we can use derived and conditional expressions in our class diagrams, we are now ready to consider a construct so powerful that I shudder to think of what could happen if Iran, North Korea, or Microsoft should get hold of it. In fact, I'm taking a huge risk in revealing it here today. If this is my last post, it's a good bet that I'm in the hands of foreign agents trying to force me into assisting with a diabolical plot involving germs, radiation, and Tomcat 5.5.

Yes, today you are ready to learn about (cue some suitably momentous music) query expressions! Wait! Where are you going? Come back. I'm tellin' ya. Query expressions are some serious mojo!

Let us feel their power together by returning again to our consideration of the Arms4Less online superstore ("where you don't need to spend a lot to destroy a lot"). Sarge explains to us that they don't sell to just anybody. "For the really good stuff, you gotta be somebody we trust -- either somebody we know, or a friend of at least two people we know." We easily capture this notion of who's trusted as follows.



We add a Customer entity with an association, friends, referencing customers who are a customer's friends. We give Customer a boolean attribute, isSomebodyWeKnow, and as well as a derived attribute, isTrusted. The value of isTrusted is derived from the expression:

isSomebodyWeKnow or #friends[isSomebodyWeKnow] >= 2

The []-brackets enclose a selection expression. friends[isSomebodyWeKnow] selects all of the friends of some customer where isSomebodyWeKnow is true. The #-sign is a shorthand for "count". So, we can see that isTrusted will evaluate to true if the customer is somebody we know or if they have at least 2 friends we know.

When next we meet, we'll delve into the notion of query expressions more fully. In the meantime, beware of North Koreans toting pirated UML editors....

Tomcat and Eclipse on Ubuntu

Posted in Bob Hedlund on December 1st, 2008 by admin

admin originally posted this on Eldorado Software.

The following is a quick review of the steps I took to get eclipse and tomcat up and running and playing well together. Replace "user" with your local user name. I probably opened things up a bit wide security wise. It works. 
  • Download the tar.gz files for linux from the respective web sites. 
  • gunzip the files 
  • tar xvf the files. 
  • Move Tomcat to /usr/share/tomcat
  • sudo chown -R user:user tomcat
  • sudo chmod -R a+rwx tomcat
  • sudo chmod +x `sudo find tomcat -type d`
  • Move eclipse to /opt
  • sudo chown -R  user:user eclipse
  • sudo chmod -R a+rwx eclipse
  • sudo chmod +x `sudo find eclipse  -type d`
The net affect of the above is that the applications are deployed to their respective locations and the user "user" may run them. I was able to run each separately, but was having issues with eclipse trying to run tomcat. These errors were due restrictions in writing logs and deploying to tomcat directories due to permission issues. The above commands allow all users to write to these directories. 

Next, you can create an executable that specifies an ECLIPSE+HOME variable: 
Create an executable for eclipse in usr/bin called eclipse
  • #!/bin/sh
  • export ECLIPSE_HOME="/opt/eclipse"
  • $ECLIPSE_HOME/ECLIPSE $*
Save the file and run clean: 
/opt/eclipse/eclipse -clean

Add the two applications to the menu via System>Preferences>Main Menu. 

In eclipse, add Tomcat as a server, and in the tomcat configuration, under "server Locations", choose "Use Tomcat Installation" radio button and save. 



SQLDeveloper on Ubuntu

Posted in Bob Hedlund on December 1st, 2008 by admin

admin originally posted this on Eldorado Software.

To Install SQLDeveloper, download the application from http://www.oracle.com/technology/software/products/sql/index.html. Unzip the archive and move it to the directory of choice. I chose /usr/share. Change the file to be executable: 

  • unzip sqldeveloper.zip
  • sudo mv sqldeveloper /usr/share/sqldeveloper
  • sudo chmod +x /usr/share/sqldeveloper/sqldeveloper.sh 
Then invoke the sqldeveloper.sh : 
  • sh sqldeveloper.sh
You will be asked to specify the path to the java home. You are up and running. 

To add SQLDeveloper to your menu, Go to System?Preferences>Main Menu. Add SQLDeveloper to the menu of choice. The Application is now executable from your menu the next time you log in. 

Conditional Love

Posted in Stu Stern on December 1st, 2008 by Stu Stern

Stu Stern originally posted this on Big Gorilla - Stu Stern's Blog.

Let's consider some other amusing things we can do with class diagrams. With a little tape, some string, and a pair of scissors, we can of course convert most class diagrams into a ceremonial tribal mask or a pirate hat. Another fun thing we can do is derive attribute values using conditional expressions.

Let's return to our example of the Arms4Less online superstore. We're having lunch with our SME, Sarge, and he's just finished telling us a funny story about a coup he helped stage a few years back. "So Johnny turns to me and says, whadaya mean, where's the king? Who do we got tied up in the back of your car?" We laugh appreciatively, and then turn the conversation back to the requirements for the store. Sarge explains how they want to offer various sales incentives, "like 20% off for quantities over 50". We can easily modify our model to reflect this requirement, by adding a new derived attribute called discount to OrderItem, and then modifying the derivation expression on total to reflect any discounting to be applied. We must also add the necessary non-derived attributes, discountQty and discount, to the Product, as shown.

Hopefully, you are beginning to see how much more you could be getting out of your class diagrams if you would just spend a little more time drawing pictures and a little less time writing code. I know how that can be tough with all the pressure you're getting from religious eXtremists, but as we shall soon see, Precision Requirements Modeling fits very nicely into an Agile approach that even the religious right can love.

In our next installment we'll really get this party started when we consider how to derive values from query expressions. I know the anticipation will be killing you between now and then, and I'd love to show you right now, but I gotta go write some code.

Install Samba on Ubuntu

Posted in Bob Hedlund on December 1st, 2008 by admin

admin originally posted this on Eldorado Software.

I have a vm on my Mac running as a guest with Ubuntu as the OS. In order to access files on the vm guest, I added Samba - a file and print server. To install Samba,  and edit the configuration: 
  • sudo apt-get install samba smbfs (Installs Samba)
  • sudo gedit /etc/samba/smb.conf (Edits the config file)
Then, go to the "Share Definitions" section of the config file that is open in your editor: 

find the lines:
  • ; [homes]
  • ; comment = Home Directories
  • ; browseable = yes

Remove the ";" to uncomment these. This allows you to access the home directories on the guest.  Then find the following line that specifies the read only attribute. It is set for yes by default. To be able to write to your directories, change this to "no" and uncomment it. 
 
  • read only=no  (if you want to be able to write to the directory)

Next you need to find the line "; security = user". Replace it with the following 2 lines: 
  • security = user
  • username map = /etc/samba/smbusers
This specifies that users may authenticate, and that the users are specified in the /etc/samba/smbusers file.  Next we need to add entries to the users file. 
  • sudo gedit /etc/samba/smbusers
The file will be empty. If you want to access your local profile, and lets say the login name is Gus, then add the following line to smbusers: 

  • Gus="Gus" 
Save the file and from the command line create a Samba password: 
  • sudo smbpasswd -a Gus
You will be prompted to enter and confirm the password for this user. Thats it , you are done with the install of Samba. 


To stop | start | restart Samba: 
  • /etc/init.d/samba stop | start | restart
The config file allows you to change the behaviour of the samba server. There are comments in the file that point you to resources for evolving the file and perhaps opening up you system to domains. 

To Access the samba server, go to : 
  • smb://computer_name/Gus
On a Mac, this is under Finder>Go>Connect to Server>.  You will be prompted for a authentication with the password you specified to smbpasswd. If authentication works, the disk will mount on your desktop, and you will be able to browse within your profile on the remote machine.