Author Archive
Twitter Weekly Updates for 2010-03-07
by Frank Kim on Mar.07, 2010, under Miscellaneous
- Ignore Files and Directories in Subversion. A little bit of a pain but it works. http://bit.ly/99GLxk #
- How to Achieve Painless Registration. Getting people to register is always bedeviling for web application developers. http://bit.ly/9AJqmg #
Ignore Files and Directories in Subversion
by Frank Kim on Mar.01, 2010, under Subversion
In the course of a project there are always files and directories that you don’t want to check in but which Subversion complains it doesn’t know anything about them. So it makes sense to tell Subversion to ignore them, in other words, keep quiet.
The mechanism for doing this works okay but I wouldn’t say it’s perfect.
This is how I do it one.
- Go to the directory where want to ignore a file or subdirectory.
- Issue the command
svn propedit svn:ignore .
- Your editor then will be launched and you can enter one line at a time those files and/or subdirectories you want to ignore.
some_file some_directory
- Commit your changes.
svn commit -–depth empty
Two things to notice.
-
--depth empty argument
only commit the propedit changes
- Committing your changes means everyone will end up ignoring these files and/or directories so make sure you are ignoring the right ones.
-
- If you don’t want to commit your changes you can revert them.
svn revert .
For further reading please see Ignore Files and Directories in Subversion.
Tweets for 2010-01 and 2010-02
by Frank Kim on Feb.28, 2010, under Miscellaneous
Ruby on Rails
- Numeric data types and zerofill. Explains what all those int(11) columns are in your Ruby on Rails tables. http://bit.ly/9Tcf7q #
- undefined local variable or method "acts_as_list"? – Ruby Forum. Do ruby script/plugin install acts_as_list http://bit.ly/9kFWbG #
- ruby on rails : adding child records to an existing parent without visiting the parent – Stack Overflow http://bit.ly/cQiGSP #
- Multi-Table Inheritance in Rails – When two tables are one… This is not easy and I wish it was. http://bit.ly/9fbzgk #
- has_many :through – count vs length vs size. Use count if u don’t want to load the contents of association into memory. http://bit.ly/dtqXe1 #
- A gentle reminder about pluralizations. config/initializers/inflections.rb to customize pluralizations in Ruby on Rails http://bit.ly/bN9GO5 #
- Ruby on Rails – Rails Migrations Cheatsheet – Dizzy. Pretty helpful. http://bit.ly/9wNvRx #
- RailsGuides Migrations. Nice guide, especially about explaining the naming convention which I don’t like. http://bit.ly/cjZ7aB #
ATG
- Configuring ATG to Send Email via Comcast SMTP – betweenGo. Configuring your ATG app to use your ISP’s SMTP server. http://bit.ly/7M5bhx #
- Enabling non-XA Resources in JBoss 4.2 with ATG – betweenGo. http://bit.ly/aDN3Po #
- Combining XML in ATG – betweenGo. Combining XML files not as straight-forward as w/ properties files but more flexible. http://bit.ly/8kVwvA Jan 12 12:00 PM
Eclipse
- Debugging Applications in IBM Rational Application Developer. Page 12 for how to set up server for debugging. http://bit.ly/aaYUHb #
JavaScript
- How can I submit a form along with some parameters using JavaScript? (JSF forum at JavaRanch). Answer #3 was helpful. http://bit.ly/b17ymm #
JSP
- Testing Which Page Loaded your JSP Page Fragment – betweenGo. Simple enough to do w/ JSTL but I always forget how.
http://bit.ly/cEh7IZ #
Miscellaneous
- Cygwin 1.7.x, mounts and /etc/fstab – betweenGo. Mounts are no longer saved from session to session in Cygwin 1.7. http://bit.ly/bmaYEu #
- Git in 5 Minutes http://bit.ly/bSt3dd and Git for the lazy – Spheriki http://bit.ly/aefD17 #
- The Thing About Git. Nice article describing how flexible Git is, especially compared to SVN. I may never use SVN again http://bit.ly/bD0tuS #
- I use DreamHost and am shamelessly plugging them both for a referral and to try to win an iPad. Honestly they’re great. http://bit.ly/ctYv3Z #
Cygwin 1.7.x, mounts and /etc/fstab
by Frank Kim on Feb.08, 2010, under Cygwin
Sunrise Heron Silhouette by Brandon Godfrey
A few days I installed Cygwin on a new laptop. I saw the warnings that Cygwin 1.7.x is new but I chose to ignore it for now.
I soon noticed that Cygwin was not remembering my mounts. After reading this on the Cygwin front page I realized I needed to do some more research.
… the mount point storage has been moved out of the registry into files. User mount points are NOT copied into the new user-specific /etc/fstab.d/$USER file. Rather, every user has to call the /bin/copy-user-registry-fstab shell script once after the update.
Next I looked at the /etc/fstab file which pointed me to the Cygwin Mount Table documentation. Using this documentation I did the following steps so that my mounts are always remembered.
- Manually mounted the C: drive.
$ mount c: /c
- Ran mount to determine what to add to my /etc/fstab.
$ mount C:/cygwin/bin on /usr/bin type ntfs (binary,auto) C:/cygwin/lib on /usr/lib type ntfs (binary,auto) C:/cygwin on / type ntfs (binary,auto) C: on /c type ntfs (binary,user)
- Based on the output of mount I added this line to my /etc/fstab.
C: /c ntfs binary,user
- Closed the Cygwin shell, opened a new one and verified the C: drive was properly mounted.
Testing Which Page Loaded your JSP Page Fragment
by Frank Kim on Feb.01, 2010, under JSTL
Sometimes you want to check in your JSP page fragment which page loaded it. Fortunately this is simple with JSTL.
<c:if test="${fn:indexOf(pageContext.request.requestURI,'foo.jsp') != -1}">
The request URI ${pageContext.request.requestURI} contains foo.jsp.
</c:if>
Simple but something I always forget how to do.
Enabling non-XA Resources in JBoss 4.2 with ATG
by Frank Kim on Jan.28, 2010, under Configuration
(Photo: a dog and it’s boss by Pixel Addict)
ATG documents how to enable non-XA resources in JBoss 4.2 for SOLID. We ended up following the same instructions to work with Oracle.
JBoss Note: JBoss 4.2 by default assumes XA drivers, which some ATG applications use; however, there are no XA drivers for SOLID. To enable multiple non-XA resources in JBoss 4.2, add the property in bold text to the jbossjta-properties.xml file, under the <property depends="arjuna" name="jta"> tag:
<property depends="arjuna" name="jta"> <property name="com.arjuna.ats.jta.allowMultipleLastResources" value="true"/>You may still see warnings in your log file, but ATG applications will run correctly. To suppress these warnings, add the following to your jboss-log4j.xml file:
<category name="com.arjuna.atg.jta.logging"> <priority value="ERROR"/> </category>
For further reading please see Starting the SOLID SQL Database document in the Running Nucleus-Based Applications section of the ATG Installation and Configuration Guide.
Configuring ATG to Send Email via Comcast SMTP
by Frank Kim on Jan.25, 2010, under Configuration
(Photo: Comcast still sucks by dmuth)
When you are developing at home you will probably need to configure your ATG application to send email via your ISP’s SMTP server. Here is how I configured ATG to send email via Comcast’s SMTP server.
First you need to update ATG’s configuration to point to the Comcast SMTP server by modifying {ATG}/home/localconfig/atg/dynamo/Configuration.properties.
emailHandlerHost=smtp.comcast.net emailHandlerPort=587
Typically you don’t need to set the emailHandlerPort, it is by default set to port 25. But Comcast has recently been switching over to use port 587 because email viruses use port 25 on infected computers.
Next you need to update ATG’s SMTP Email service configuration by modifying {ATG}/home/localconfig/atg/dynamo/service/SMTPEmail.properties.
defaultFrom=betweengo@comcast.net username=betweengo password=betweengo
These values used to be optional but now are required because Comcast requires authentication as part of its increased security.
Specifying One-to-Many Relationship in ATG Repositories
by Frank Kim on Jan.21, 2010, under Repository
(Photo: Monta driving by Yogma)
Specifying one-to-many relationships is ridiculously easy in Ruby on Rails. Unfortunately it’s not so straight-forward in ATG repositories.
First you specify the “belongs to” relationship. In this example the player belongs to a team.
<item-descriptor name="player">
<table name="team_players" type="auxiliary" id-column-names="team_id" shared-table-sequence="1">
<property name="team" column-name="team_id" item-type="team" />
</table>
</item-descriptor>
Then you specify the “has many” relationship. In this example the team has many players.
<item-descriptor name="team">
<table name="team_players" type="multi" id-column-names="player_id" shared-table-sequence="2">
<property name="players" column-name="player_id" data-type="set" component-item-type="player" />
</table>
</item-descriptor>
Note the trick is specifying the “shared-table-sequence.”
Here is the SQL for the table that specifies this relationship in our example.
CREATE TABLE team_players ( team_id VARCHAR2(40) NOT NULL, player_id VARCHAR2(40) NOT NULL, CONSTRAINT team_players_pk PRIMARY KEY (team_id, player_id), CONSTRAINT team_players_players_fk foreign key (player_id) references players (id), CONSTRAINT team_players_team_fk foreign key (team_id) references teams (id) );
SQL Insert in One Table Based on Values in Another Table
by Frank Kim on Jan.18, 2010, under Oracle
(Photo: Love’s Old Sweet Song by linda yvonne)
The syntax for doing this is similar to doing an update in one table based on values in another table yet simpler.
INSERT INTO suppliers (name) SELECT customers.name FROM customers WHERE customers.id = suppliers.id);
If you want to add constant values into the insert you can do something like this.
INSERT INTO suppliers (name, city) SELECT customers.name, 'Toronto' FROM customers WHERE customers.id = suppliers.id);
For further reading please see SQL INSERT INTO.
Limiting the Quantity Added to a Cart
by Frank Kim on Jan.14, 2010, under Commerce
(Photo: Speed Limit 14 MPH by bredgur)
Sometimes the client will ask that the quantity of items you can add to the cart be limited to some number, say 14 like in the photo above.
Often people will implement this by putting in checks throughout the JSP. But this is not the best solution because it is more labor intensive and you may miss something.
Another solution is to deal with the issue in the CartModifierFormHandler by extending the doAddItemsToOrder method. Simply check the quantity of each AddCommerceItemInfo item and make sure that its quantity plus the quantity of the same item already in the cart does not go over the limit. If it does modify the quantity in the AddCommerceItemInfo item appropriately.
Here is how I implemented this.
@Override
protected void doAddItemsToOrder(DynamoHttpServletRequest pRequest,
DynamoHttpServletResponse pResponse) throws ServletException,
IOException {
// fetch the order
Order order = getOrder();
if (order == null) {
String msg = formatUserMessage(MSG_NO_ORDER_TO_MODIFY, pRequest,
pResponse);
throw new ServletException(msg);
}
// iterate through the add commerce item infos, making sure that adding
// any of them will not result in a quantity greater than LIMIT
AddCommerceItemInfo[] addCommerceItemInfos = getItems();
for (int ii = 0; ii < addCommerceItemInfos.length; ii++) {
// see if there is a commerce item already in the order for the next
// add commerce item info
AddCommerceItemInfo addCommerceItemInfo = addCommerceItemInfos[ii];
String catalogRefId = addCommerceItemInfo.getCatalogRefId();
CommerceItem commerceItem = findCommerceItemByCatalogRefId(order,
catalogRefId);
if (commerceItem == null) {
continue;
}
// check that the quantity we add won't result in a total quantity
// greater than LIMIT
long addQty = addCommerceItemInfo.getQuantity();
long qty = commerceItem.getQuantity();
if (qty >= LIMIT) {
addCommerceItemInfo.setQuantity(0);
} else if (qty + addQty > LIMIT) {
long newAddQty = LIMIT - qty;
addCommerceItemInfo.setQuantity(newAddQty);
}
}
super.doAddItemsToOrder(pRequest, pResponse);
}
protected CommerceItem findCommerceItemByCatalogRefId(Order pOrder,
String pCatalogRefId) {
for (int ii = 0; ii < numCommerceItems; ii++) {
CommerceItem commerceItem = (CommerceItem) commerceItems.get(ii);
String catalogRefId = commerceItem.getCatalogRefId();
if (catalogRefId.equals(pCatalogRefId))
return commerceItem;
}
return null;
}



