Grails Tip # 2: Hibernate Session


A different object with the same identifier value was already associated with the session

The Domain

Say we are managing a store with shelves full of items. Whenever an
item on a shelf is empty, we need to create a restock order form.
Lets represent this as 3 domain classes: Shelf, Item, RestockOrder

The Code

A restock order is created when an existing item on a shelf runs out,
BUT, a order is also created for brand new items. The client has requested
that when creating new items, restock orders can also be created.

The Shelf domain object:

			package com.ex
			
			class Shelf {
				int number
				static hasMany = [items:Item, restockOrders:RestockOrder]
			}
		

The Item domain object:

			package com.ex
			
			class Item {
				String name
				String description
				double price
			}
		

The RestockOrder domain object:

			package com.ex
			
			Item item
			static belongsTo =[shelf:Shelf]
			static mapping = {
				item cascade:'save-update'
			}	
		

The editing of a Shelf takes place over several pages, similar
to a web-flow, thus the Shelf object is created and stored in
the HTTP session (therefore detached from the Hibernate session).
On subsequent HTTP requests, the user adds more data to this
object in the session. Finally, after filling out the last
page, we are able to persist the domain object to the session.

On the last page, if the user made important changes to Shelf,
the user is showing a confirmation page comparing the old values
with the current one. This was done by simply populating
the model with the current version in the session and also
re-loading the same model from the database. If the user did not
make any changes that require confirmation, we save right away.

<%= image_tag "articles/grailstip2/flow.png" %>
In ShelfController:
The index() method loads the required shelf and puts it into the
HTTP session, detaching it from Hibernate session.

		    def index = {	
				Shelf s = Shelf.findByNumber(1)
				session.putValue("shelf", s)
			}
		

The save controller

			def save = {
				// get from sesion
				def shelfUnderEdit = session.getAt("shelf")
				
				// bind update
				shelfUnderEdit.parameters = params
				
				Shelf originalShelf = Shelf.findByNumber(1)
				
				// user hasn't confirmed, might have to show confirmation page.
				if (showConfirmation(shelf, original) && params.noComfirmation){
					render("showUpdates", model:[shelfUnderEdit:shelfUnderEdit, originalShelf:originalShelf])
					return
				}
				
				// save
				shelfUnderEdit.save(failOnError:true)
			}
		

However, when we try to run the code above, we get the
“A different object with the same identifier value was already associated with the session”
error.

The Problem

Hibernate tries to keep one instance of a persisted object
in the session at one time. In this example, for any “Shelf”
in the database, Hibernate tries to make sure only 1 instance
of a Shelf object represents that Shelf.

The problem resides in the save(), there is the original Shelf we
detached and put into the HTTP session. When we try to re-attach
it, Hibernate finds that another one is found in the session.
This second object was created when we loaded the same Shelf from
the database to do our comparison. Two objects representing the
same Shelf now resides in the session and much to the dislike to
Hibernate.

The Solution

Though there are several ways to solve this problem, the method
we took was to discard the re-load Shelf object that was used
for the comparison. Therefore, when save() is called on the
Shelf that is under edit, it is reattached to the Hibernate
session and is the only object representing that particular
Shelf in the database. Thus Hibernate is able to persist the
changes without error.

			def save = {
				// get from sesion
				def shelfUnderEdit = session.getAt("shelf")
				
				// bind update
				shelfUnderEdit.parameters = params
				
				Shelf originalShelf = Shelf.findByNumber(1)
				
				// user hasn't confirmed, might have to show confirmation page.
				if (showConfirmation(shelf, original) && params.noComfirmation){
					render("showUpdates", model:[shelfUnderEdit:shelfUnderEdit, originalShelf:originalShelf])
					return
				}
				
				originalShelf.discard()
				
				// save
				shelfUnderEdit.save(failOnError:true)
			}
		

References

Grails Tip # 1: Transient Values


Not Null Property References A Null Or Transient Value

Introduction

I recently started working on Grails applications and as expected, I’ve seen the same problems come up over and over again. So, I thought it would be a good idea to accumulate the common (and some uncommon) problems we”ve seen and write about them. The domain objects and code used in the posts are purpose built examples simulating the actual problems that we’ve seen developing with Grails.

The goal is not to explain the full underlying details of GORM and Hibernate, but instead, show examples of what caused issues for me and hopefully can save you time in solving your problems. Here we go with tip number 1:

org.hibernate.PropertyValueException: not-null property references a null or transient value

Example 1

The Domain

Say we are managing a store with shelves full of items. Whenever an item on a shelf is empty, we need to create a restock order form. Lets represent this as 3 domain classes: Shelf, Item, RestockOrder

The Code

A restock order is created when an existing item on a shelf runs out, BUT, a order is also created for brand new items. The client has requested that when creating new items, restock orders can also be created.

The Shelf domain object:

		package com.ex
		
		class Shelf {
			int number
			static hasMany = [items:Item]
		}
	

The Item domain object:

		package com.ex
		
		class Item {
			String name
			String description
			double price
		}
	

The RestockOrder domain object:

		package com.ex
		
		class RestockOrder {	
			Item item
			Shelf shelf
		}
	

A Shelf has a list of items and is represented by the hasMnay relationship to Items. A restock order needs an Item, it just doesn’t make sense without one. But an Item does not belong to a restock order. Thus, we do not have a belongsTo RestockOrder relationship on Item. If a restock order is deleted, we certainly do not want to delete the Item record.

The Problem

Somewhere in our RestockController, we have the following code. It creates an instance of a RestockOrder and Item. It assigns the item to the restock order.

		def createOrder = {
				.
				.
				.
				RestockOrder ord = new RestockOrder()
				ord.shelf = currentShelf
				ord.item =  new Item(name:name, description:desc, price:price)
				ord.save(failOnError:true)
			}
		}
	

When the RestockOrder is saved, we get the following error:

          not-null property references a null or transient value: com.ex.RestockOrder.item

and the only way to resolve it is to create AND save an instance of Item and then assign it to RestockOrder. This might be confusing because, you can create and assign an instance of Item to a Shelf, like the following:

			Shelf shelf = new Shelf(number:1)
			shelf.addToItems(new Item(name:name, description:desc, price:price))
			shelf.save(failOnError:true)
		

without any error.

The Solution

A transient object is an object that has been instantiated but is not yet associated to the Hibernate session. When you associate this object to a property of a object that is associated to the session and try to save, Hibernate will complain and give you the
“Not Null Property References A Null Or Transient Value error”

This problem has to do with how GROM (Hibernate) cascades saves. Saves are automatically cascaded from parent to child when there is a hasMany relationship. This is why you can add a new Item to Shelf and save the shelf without explicitly saving the Item first. The save cascades from Shelf to Item via the hasMany relationship.

With RestockOrder, there is no such relationship and Hibernate will not do the cascading automatically. You have two solutions:

1 ) Explicitly save the Item before assigning.

		Item itm = new Item(name:name, description:desc, price:price)
		itm.save(failOnError:true)
		
		RestockOrder ord = new RestockOrder()
		ord.shelf = currentShelf
		ord.item =  itm
		ord.save(failOnError:true)
	

2) Configure the cascading behavior for Item in RestockOrder.

Here we set a save-update cascading behaviour.

		package com.ex
		
		class RestockOrder {	
			Item item
			Shelf shelf
		}
		
		static mapping = {
			item cascade:'save-update'
		}
	

Conclusion

Though this error is relatively simple (especially for this example) problem, it is very problem and can be difficult to track down as your domain model grows. Thus it is extremely helpful to have a understanding when these errors occur so you know what to look for in your application.


Example 2


The Domain

In this example, we’ll use the same domain as in Example 1. The domain objects are slightly diffrent however.

The Code


We’ll use the same domain objects as Example 1, but with slight modifications:
The Shelf domain object:

		package com.ex
		
		class Shelf {
			int number
			static hasMany = [items:Item, restockOrders:RestockOrder]
		}
	

The Item domain object:

		package com.ex
		
		class Item {
			String name
			String description
			double price
		}
	

The RestockOrder domain object:

		package com.ex
		
		Item item
		static belongsTo =[shelf:Shelf]
		static mapping = {
			item cascade:'save-update'
		}	
	

The Problem


We need to allow the user to create a new shelf but during this process we also allow them to assign restock orders to the newly created shelf. To do this, we create a new RestockOrder domain object and assign it’s parent as the newly created shelf.

Somewhere in a controller we have the following code:

		RestockOrder ord = new RestockOrder()
		ord.shelf = newShelf
		ord.item =  new Item(name:name, description:desc, price:price)
		
		newShelf.save(failOnError:true)
	

The problem is, when you run it, you get the “org.hibernate.PropertyValueException” error. This is because at the time of saving the RestockOrder, the instance of Shelf is still transient.

You get a similar exception if you try and add to the list of RestockOrder’s within a Shelf by adding directly to the Shelf’s restockOrders list:

		def currentShelf = Shelf.findByNumber(1)
		RestockOrder ord = new RestockOrder()
		ord.item =  Item.findByName("a")
		currentShelf.restockOrders.add(ord)
		currentShelf.save(failOnError:true)
	

instead of using Shelf’s addToRestockOrder() method. By using native Collection methods to add to the list, Grails will not automatically set the parent on the child entity.

The Solution

To resolve this, instead of assigning the parent of a child, you can use the addTo* method on the parent to add the Item as a child of the parent.

When you add the hasMany relationship, Grails provides an addTo* method. In the example above, you will have a addToRestockOrder() method which accepts a RestockOrder instance. This relationship automatically cascades saves from the parent to child.

  • You do not need to call save on the child.
  • It also updates the child’s parent reference.

Conclusion

In this example, I showed how you can use the addTo* method to avoid some common Grails errors, but as with all other programming problems, there are always several ways to solve the issue.

So, hopefully after reading this article, you have a slightly better understanding why these errors appeared in your code by looking at how it was caused on ours. I will continue to update this article if I find any other notable or interesting causes to this particular error.

References

What is LESS css?

What is LESS?

LESS is a css pre-compilier that has gained popularity over the past few years. There are a few good introductions to the language you can find here:

So I thought I would share what I like about LESS the most.

Syntax– I like how LESS introduces features such as variables and mixins without the overhead of learning new syntax. In addition, the use of nested rules feels like a native feature to regular css.

Variables – As mentioned previously, variables is a new introduction to css. I find variables mainly assigned to colors and they allow developers to define colors in one place so they can be changed easily without using search and replace.

Nested rules– Nested Rules are by far the greatest feature to regular css. They make css more DRY and easier to read as their inheritance is cleary visable. Nested selectors also force the developer to group togather related css within the file.

Functions – I havn’t used functions too much, but where I have, they really do help reducing duplicate code.

Operations, Namspaces, JavaScript – To be honest, I havn’t really used these 3 features of LESS very often (or at all). As I continue my use of LESS, I will update this post on how I feel about these features.

In conclusion, LESS is a WIN for me. It helps organize CSS in a “natural” way. It also helps keep LESS DRY. So there you go, LESS, it’s a good thing.

Protecting Applications against CSRF attacks

Briefly, what is CSRF?

CSRF stands for cross-site-request-forgery. It is an exploit of a website where an attacker constructs a request and has a victim execute it on the attacker’s behalf. In the past few years, a flurry of major CSRF attacks has thrust this type of exploit into the limelight yet many applications still do not protect against it.

In this post, I won’t go into how to defend against CSRF attacks, but instead review several solutions I’ve come across and provide some of my own opinions for them. For a better description of the CSRF exploit and how to prevent it, here are some really good articles for you to read:

Custom Solutions

With CSRF attacks in mind, it actually takes little additional development cost to integrate a CSRF defenses into a new project. One of the simplest ways to prevent most CSRF related exploits is to append and validate a security token to every request made to your application.

At the basic level, all CSRF libraries must accomplish the following 3 actions:

  1. Generate a token (per session or request) and store it in the session.
  2. On each request, validate the token sent by the browser against the one store in the session. (probably
    implemented as a filter or interceptor)
  3. Handle user specified unguarded or landing pages.

In addition, each form on all your pages will be responsible for sending the token on submission.

Positives

Not tied to any existing CSRF library conventions or limitations. Many CSRF libraries currently available restrict the application to conventions that the application must follow. For example, some libraries restrict applications to only POST requests. This may or may not be acceptable to your client. In addition, many libraries may have crippling limitations that prevent you from using 3rd party solutions “out of the box”.

Many frameworks support the token synchronization pattern built in to prevent double submission of forms. Though it
does not provide 100% protection from CSRF attacks, it can be used as the basis to protecting your application against CSRF attacks.

Negatives

Increased development costs – Regardless of the approach, defending against CSRF attacks do increase cost of the application and developing a custom solution is typically the highest cost. That being said, the cost of retrofitting an existing application to guard against CSRF exploits is far more costly. The costs of dealing with a security breach can be significantly higher.

Non-global Solutions – Many custom CSRF solutions are “exclusive” in the sense, developers choose when to add CSRF protection to specific requests. “inclusive” solutions protect all URLs by default and developers are able to explicitly state unguarded pages. Developers tend to code pages as unprotected and them protect them later. This is highly error prone in “inclusive” solutions and can leave large portions of the application unprotected if they forget to protect them.

Missed Vulnerabilities – With a custom solution, you greatest asset (and weakness) of your CSRF defense is your team
of developers. As with other open-source libraries, open-source CSRF libraries benefit from a large community
continuously providing feedback, updating the source, and thus making the library more effective.

3rd Party Libraries

In the Java world, I’ve worked with OWSAP’s CSRF Guard library. So this will be the bases of my review on “3rd party libraries”

Positives

Provides adequate out of the box protection against CSRF guard attacks. It is a well-established library with ‘some’ community support.

Require minimal configuration to get started.

Once installed, all URLs are protected by default. Developers must specify unprotected URLs.

Negatives

By using a 3rd party library, you are tied into their conventions and limitations.

  • CSRF Guard’s configuration file for defining new landing page and unguarded pages requires the context-root as part of the URL. Pattern matching for unguarded URLs is extremely limited.
  • When going to the new token landing page, CSRF Guard changes the title of the browser to “new token landing page”. Not only does this expose the underlying security library, it can be a total showstopper to the client.
  • Verbose logging is on by default.

Conclusion

In conclusion, CSRF Gurad provides adequate CSRF protection but there are some limitations that make it hard to work with. Custom solutions are…custom. You have to build and maintain it. Custom solutions give you the flexibility to be as tight or loose as you need but with this flexibility comes with the risk of exposing too many CSRF vulnerabilities by accident. So there you have it, as I become more exposed to additional CSRF libraries, I will continue to update this post.

Grails: First Project

Groovy and Grails has been much talked about in the last couple of years and though I’ve fooled around with small sample projects I never really had the chance to do anything more. Recently, a client approved to use Grails on a new J2EE web application and this will be my first time using it on a large complex system.

There are many postings that talk about the general positives of the framework, but in this article, I want to focus on what worked and didn’t in my project and in particular, what didn’t work. My hope is after you read this article, my insights on using Grails for the first time will help you make the right technological decisions for your project.

Introduction

I am no Grails expert.

The team started up with Grails very quickly. As new members joined the team, the overall ramp up time was, as advertised by Grails, very quick and pain free. As you all many know, ramp up and installation of traditional J2EE applications can be extremely painful and take a lot of time, so the ease of ramping up new members was a great relief.

The transition between traditional J2EE to Grails was easy. I would attribute this to the “Convention over Configuration” paradigm that Grails (and Rails) use. By understanding the convention and looking at samples and existing code, developers were able to focus on implementing business logic rather then figuring out how XML configurations and flows work.

Positives

  • Easily change the domain model without having complex SQL migration scripts.
    With a domain model actively changing thoughout early development,
    incorporating the changes in short time would not have been possible.
  • Most of the advantages as advertised by Grails worked for us.
    Such as: clear built-in separation of environments, GROM, automatic binding, etc
    See the additional resources for a other postings on the advantages of Grails.
  • Active Groovy and Grails community. Even for a new framework, there is substantial
    knowledge on the internet and questions are quickly answered by the community.
  • The small things: Groovy syntax, smoother development, integrated environment.
    All that dynamic synamic syntax and sugar code.

Negatives

  • The installation of the plugin in directories outside the project and
    overall in-house plugin setup via the IDE added much confusion during the
    periods of active development of those plugins.
  • Though Springsource’s STS Eclipse integration with Grails is pretty adequate,
    there are some annoying gotcha’s that keep creeping up, especially dealing with
    the installation of in-house plugins.
  • Some developers can to revert back to standard Java techniques when exposed to
    difficult situations. For this reason, I found code reviews very important.
    Detected in reviews, the more experienced reviewer can often pass knowledge on
    how to solve a particular problem the Grails way.
  • Though novice developers can quickly become significant contributors, without
    a solid knowledge in Spring or Hibernate, it is often left up to the more senior
    members to deal with strange Hibernate errors.
  • We are developing the application using the built-in Grails development
    (Tomcat and Java DB) environment. However, the test and production
    environments are using a WebSphere server and Oracle database. Though development
    though Grails is faster, we have seen a number of gotcha’s
    during our switch over to the WebSphere and Oracle database.
  • These compatibility issues do not produce meaningful Exceptions messages and
    usually require a trial-and-error approach to figure out the problem. Examples
    are restricted Oracle keywords used as properties on domain objects and issues when
    Controllers and Domains share the same name as certain WebSphere classes.
  • It remains to be seen how well the client’s IT teams will adapt to
    this new technology.

In conclusion, I would recommend Grails as a framework going forward. Much of Grails’s advertised benefits are true and work. The big question remains is how organizations who are used to traditional J2EE frameworks such as Struts and Spring can adapt to using dynamic language frameworks such as Groovy.

As development continues, I will update this blog entry.

Additional Resources

Here are some additional resources to help you decide if Grails is right for you.

BAD CSS

These Things Annoy Me

(And probably annoy you too)

In this post I’m just listing out some CSS gripes I’ve seen and their annoyance based on my scale here:


Slightly Annoyed

Annoyed

Really Pissed

<%= image_tag "articles/badcss/level.png" %>

Example 1

Please Don’t Do This:

		<div style="color:red;">
			You have not entered a name.
		</div>
		
		<div style="color:gray;font-size:12px">
			Name: <input type="text" size="20" name="name"/>
		</div>
		
		<div style="color:gray;font-size:12px">
			Address: <input type="text" size="20" name="addr"/>
		</div>
	

because that makes me have to do this:

		<div class="error">
			You have not entered a name.
		</div>
		
		<div class="labelInput">
			Name: <input type="text" size="20" name="name"/>
		</div>
		
		<div class="labelInput">
			Address: <input type="text" size="20" name="addr"/>
		</div>
	

and

	.error {
		color:red;
	}
	
	.labelInput {
		color:gray;
		font-size:12px
	}
	

Example 2

Please Don’t Describe What the CSS is Doing

		.highlight-red {
			color:red;
			font-weight:bold
		}
		
		.left-align-input {
			margin-left:30px;
			font-color:gray;
			font-size:20px;
		}
	

Example 3

Please Don’t Add Default Styles to Elements

		.error {
			color:red;
			font-weight:bold
		}
		
		table {
			margin-left:30px;
			font-color:yellow;
			font-size:6px;
		}
		
		p {
			margin-right:20px;
			font-color:red;
			font-size:6px;
		}
		
		articleContent {
			text-align:center;
		}
		.
		.
		.
	

because that makes me do:

		.error {
			color:red;
			font-weight:bold
		}
		/*
		table {
			margin-left:30px;
			font-color:yellow;
			font-size:6px;
		}
		
		p {
			margin-right:20px;
			font-color:red;
			font-size:6px;
		}
		*/
		articleContent {
			text-align:center;
		}
		.
		.
		.
	

or add my own css to P and Table elements I do not want your crappy style applied to.


Example 4

Stay back! I don’t want to catch your divities.

		<div id="out-wrapper-div">
			<div id="inner-wrapper-div">
				<div class="inner-wrapper-input">
					<span class="input-span-wrapper"><input type="text" name="name"/></span>
				</div>
			</div>
		</div>
		<div id="out-wrapper-div">
			<div id="inner-wrapper-div">
				<div class="inner-wrapper-input">
					<span class="input-span-wrapper"><input type="text" name="addr"/></span>
				</div>
			</div>
		</div>
	

Example 5

Important! Don’t abuse !important

There has been much discussion on when is the right time to use !important, so and there are valid reasons to use it. Do not abuse such power.

		p {
			margin-right:20px !important;
			font-color:red !important;
			font-size:6px !important;
			padding-left:0px !important;
			margin:0px !important;
		}
	

ugh.


Example 6

You can actually add arbitrary text to HTML using CSS. No matter how experienced you are, there will be times where you forget this and spend needless time digging around trying to figure out how this magical text appears only to find out it was produced by CSS.

Doing this like:

		#copyright:after { content: "Copyright 2011 John Smith"; }
		.
		.
		#homeLink:after { content: "Home";}
	

makes it really hard to find out which JSP / GSP / RHTML / ETC ‘view’ is rendering it which means I now have to go digging around your javascript and CSS files for content that has been added by CSS.


Example 7

Group related styles

		table {
			text-align:center;
			font-color:gray;
		}
		
		.error {
			font-color:red;
		}
		
		.article-content-header{
			font-size:12px;
		}
		tr {
			margin-left:10px;
		}
		#navbar {
		.
		.
		.
		th {
			font-weight:bold;
		}
		.hello {
			padding:2px;
			margin:10px;
		}
		
		td {
		}
	

What is Photodynamic Therapy?

I was once a researcher at Princess Margret Hospital (part of
University Health Network) and participated in a research group which
involved photodynamic therapy to treat cancer. I just wanted to share
a tid-bit on what we did there and what came out of it.

What is Photodynamic Therapy?

You can read a detailed description here
, but in a nutshell, it
is a form of cancer treatment which involves injecting a tumor with a
drug that is activated by light. The drug can injected or taken orally
and the light can come from external or internal (via fiber optic
cables) sources.

The Problem

After injecting the drug into the tumor, it does not stay within
the bounds of the tumor and is absorbed by the surrounding
tissue. In prevent damage to the surrounding tissue, the key
is to only “activate” the drug that resides within the tumor. Light is
emitted from the light source in a radial pattern and the “intensity”
of the light dimishes as you travel further from the source. The loss
of “intensity” occurs in a pradicitable manner and thus given a light
source, tissue properties, and distance, one can measure the light and
thus “strength” of the drug at any given position.

Because light is emitted radially outwards like a sphere, it is
difficult to achieve the correct light intensity in irregular shaped
tumors. In particular, it is very difficult to achieve good solutions
for tumors with sharp edges (think about a box full of balls, there is
always some amount of empty space). The key is to try and achieve the
correct dosage within the tumor tissue and no drug activation outside.

Modeling the Problem

Before starting, we had to model the
problem. We used Matlab (with embedded Java) to model the problem in a
3D environment. For our test tumor, we decided to use the sine
function with each point rotated around the axis creating a 3D object.
Within the test space, we picked N number of points (inside and
outside the tumor) for which we computed the expected and actual
dosages. These would be our testing points.

The Computational Problem

Here in lies the computation problem. We have several light
sources and testing points within the tumor. The goal is to set the
intensity of the sources such that we get the correct activation level
of the drug at all of our testing points.

Simulated Annealing

This problem is complex…it is not possible to generate all
possible solutions and choose the best case. However , one could
generate a initial solution and keep tweaking values. Each time we
teak a value, we compare its outcome (cost) with the current outcome
and take the better solution. This will eventually lead to a solution
in winch tweaking of the sources leads to no more better solutions.
This is called a local minimum and unfortunately, finding a local
minimum does not guarantee it is the overall best solution (or global
minimum).

To get around the problem of becoming stuck at local minimums,
we decided to go down the route of using probabilistic algorithms to
determine a “good” solution and in particular, decided to use
Simulated Annealing(SA).

In SA, we start off at some initial solution and teak several
light sources as before but at each step, when determining to accept a
particular solution, we allow for a probability to accept a worse
solution. This allows us to “jump” past local minimums.
Mathematically, this can allow the algorithm to eventually find the
global minimum if we run the program for a very long time.

The Cost Function

For each solution generated, we have to evaluate the quality of
the solution. This is done via the cost function. For our problem, we
looked at each testing point and compared the drug activation at that
point with the required amount. We then took the difference and
applied some multiplier. The multiplier was used to emphasize how
important it was for a testing point to be close to it’s required
dosage. For example, if tumor existed near a vital organ, the
multiplier on points within the organ would have extremely high
values.


In the end, it was determined that SA had a difficult time generating “good” solutions.
If often found solutions that could not be easily manufactured in a optic fiber. We also
found that letting the algorithmic run for a long time did not generate better solutions.
That being said, there was a lot discovered. Researchers learned what factors affected the
algorithm, and what worked and what didn’t. It was also a great learning experience for me
since it was my first time participating in a research group.

You can see the full results from the published paper here:

A. Rendon, J. Okawa, R. Weersink, J.C. Beck and Lothar Lilge, Conformal light delivery using tailored cylindrical diffusers,
Optical Methods for Tumor Treatment and Detection: Mechanisms and Techniques in Photodynamic Therapy XVI, 2007.
PDF

Hello world!

I finally got around to building my second iteration of my website. Though my first site served me well, I wanted a new site that would allow me to fool around with the latest and greatest libraries around. I also wanted a site layout in which I could present my opinions better.

Welcome to my general “tech” blog. This is where you will find any work or technology related ramblings. You can find my general topic or ‘fun’ posts here.

My current site is still using Ruby On Rails, but I had originally built it out of Groovy on Grails. I decided I wanted to keep my current server, so ported all the code over the Rails. That in itself was a interesting project even though the application is small. I also want to experiment with different technologies, mainly, using rails and javascript frameworks.

I hope to be constantly making upgrades in the near feature.