Archive for the ‘development’ Category

Grails Scaffolding as a <DL> Table

Thursday, May 15th, 2008

I really like scaffolding in grails. However I don’t like the scaffolding for the create, edit, and show. So I decided to hack up the templates. I’m not sure if there is a better way to have custom scaffolding templates. Please post if you have a good way since over riding the default might not be the best approach.

Here’s my hacked up version to use the dl, dt, and dd for create.gsp and the style sheet. The style sheet is not perfect yet but soon will be very close.

.....
<%= multiPart ? ' enctype="multipart/form-data"' : '' %>></code>
<div class="dialog"><fieldset>
<legend>Create ${className}</legend>
<%

excludedProps = [’version’,
‘id’,
Events.ONLOAD_EVENT,
Events.BEFORE_DELETE_EVENT,
Events.BEFORE_INSERT_EVENT,
Events.BEFORE_UPDATE_EVENT]
props = domainClass.properties.findAll { !excludedProps.contains(it.name) }

Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
props.each { p ->
if(p.type != Set.class) {
cp = domainClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
if(display) { %>

<dl class=”table-display prop”> <dt class=”name”> <label for=”${p.name}”>${p.naturalName}:</label> </dt> <dd class=”value \${hasErrors(bean:${domainClass.propertyName},field:’${p.name}’,'errors’)}”> ${renderEditor(p)} </dd> </dl><%  }   }   } %>

</fieldset>
<div class=”buttons”><span class=”button”><input class=”save” type=”submit” value=”Create” /></span></div>
</div>
….

Okay Word Press doesn’t do it justice.

fieldset {
border: 1px solid #336699;
font-family: Verdana;
font-size: 12px;
line-height: 15px;
margin: 0px 0px 5px;
padding: 0px 5px 8px;
float: left;
}

fieldset legend {
font-weight: bold;
padding: 5px;
}

.table-display dt {
float: right;
font-weight: bold;
margin: 0pt;
padding: 0.2em;
text-align: right;
width:14em;
margin-top: .3em;
}

.table-display dd {
margin: 0pt;
padding: 0.2em;
}

dl.table-display {
margin: 0.2em 0pt;
padding: 0pt;
}

dd input {
height: 100%;
}

dd select {

height: 100%;
width: 100px;
}

dd.errors {
background: #fff3f3;
border: 1px solid red;
color: #cc0000;
margin: 10px 0 5px 0;
padding: 5px 0 5px 0;
}

Have to find a plugin to display code better.

If someone wants a better copy just email me.

Grails One Domain many applications…. Bad Developer ?

Monday, April 21st, 2008

Hello …. I think this maybe one way of doing common domain with Grails for multiple applications. Say you have this adserver you are writing or some type of administration you need to do. Create Users , manage a bit-o-content whatever. Your site is moderately popular you get a few 10k hits or so. Why would I want my admins running on my production server sucking up the resources? I don’t so here’s what I’m doing.

I created three grails applications …. I may just cut this down to two and a groovy project later. But I like the framework making test and stuff.

I called one domain-gr , one admin-gr, and one client-gr.

Created a sym-link from the grails-app/domain from each of the domain-gr and the client-gr to the domain-gr/grails-app/domain

Created unique controller for each of my client and domain scaffolded them out changed my datasource to the same ds. BAM one domain two different apps. remember to grails -Dserver.port=9090 run-app on the second app.

Now I can host the admin app locally and the client on my prod server.

Yes …. Yes I know what about a plugin you say? Well I thought about that and I didn’t like the idea of reloading a plugin for a domain while in development. I guess I could roll the plugin later.

That’s my latest hack. Ask me about my layout div control for site-mesh sometime.

My question is anyone got a better way? Is this bad good or ugly. I like it for the DRY principle.

-Doyle

PS… Worked fine importing them into eclipse. I don’t think this will work on Windoze.

Grails PayPal IPN How I did it ….

Sunday, April 20th, 2008

After a bit of searching for a quick and dirty on Paypal and Grails my search came up blank. After making sure I wasn’t going to reinvent the wheel. I prodded off to fine the default jsp and servlet version which I did and it was very straight forward. Some of the code below is still used from that version.

Domain Object for paypal ipn:

class Ipn {
        String last_name
        String address_name
        String txn_type
        String receiver_email
        String address_city
        String residence_country
        String payment_gross
        String payment_date
        String address_zip
        String payment_status
        String address_street
        String first_name
        String payer_email
        String payer_id
        String verify_sign
        String payment_type
        String business
        String address_country_code
        String mc_fee
        String address_status
        String quantity
        String notify_version
        String mc_currency
        String custom
        String address_state
        String payment_fee
        String payer_status
        String shipping
        String item_name
        String tax
        String charset
        String item_number
        String invoice
        String mc_gross
        String txn_id
        String receiver_id
        String address_country
}
SenderController ....
 def paypal = {
                    String amount = params.paymentOptions
                    String itemType
                    if("400.00".equals(amount)){
                            itemType = "Whatever Order"
                    }
                    def now = new Date()
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddmm")

                    String invoice = "P"+params.userid+params.year+params.make+sdf.format(now)
                    String postString = "?"+"cmd=_xclick"+"&"
                    postString += "business=yourbuis@foo.com“+”&”
                    postString += “item_name=”+itemType+”&”
                    postString += “amount=”+params.paymentOptions+”&”
                    postString += “custom=”+params.custom+”&”
                    postString += “invoice=”+invoice+”&”

                    postString += “notify_url=http://foo.com/ipn” + “&”
		    postString += "return=http://foo.com/user/payloop/“+params.userid

                    redirect(url:”https://www.paypal.com/cgi-bin/webscr“+postString)

            }
class IpnController {

        def allowedMethods = [delete:'POST', save:'POST', update:'POST']
        EmailerService emailerService
        def index = {
                        def ipn = new Ipn(params)
                        ipn.parmscustom=params.custom
                    ipn.save()
                        Enumeration en = request.getParameterNames();
                        String str = "cmd=_notify-validate";
                        while(en.hasMoreElements()){
                                String paramName = (String)en.nextElement();
                                String paramValue = request.getParameter(paramName);
                                str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue);
                        }
                        URL u = new URL("https://www.paypal.com/cgi-bin/webscr“);
                        URLConnection uc = u.openConnection();
                        uc.setDoOutput(true);
                        uc.setRequestProperty(”Content-Type”,”application/x-www-form-urlencoded”);
                        PrintWriter pw = new PrintWriter(uc.getOutputStream());
                        pw.close();

                        BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
                        String res = br.readLine();
                        br.close();

                        def foo = MyDomainFoo.get( params.custom )

//                        check notification validation
                        if(res.equals(”VERIFIED”)) {
                                foo.verifiedPayment=”VALIDATED”
                                foo.save()
                                //send email
                                def email = [

                                     to: [ ‘peeps@whocare.com‘ ],
                                     subject: ‘Yadada duh’ + ipn.invoice ,
                                     text:  Information’ 

                                     + ‘nOrder Payment Status: VERIFIED’
                                 ]
                             // sendEmails expects a List
            emailerService.sendEmails([email])
                                //update estimate to Validated
                        }
                        else if(res.equals(”INVALID”)) {
                                foo.verifiedPayment=”INVALID”
                                foo.save()
                                //send email bad here
                        }
                        else {
                                println(”LOG:: Something bad happened with” + ipn.custom)
                        }
                        redirect(uri:”/terminated.html”)
         }

There it is in a nut-shell. It's not the cleanest but it works and works well.
What I would recommend if you  are doing some paypal stuff with grails would be to do the following.
 In your Config.groovy class use the following:
paypalurl = "http://localhost:8080/local-pay/foo"
analytics = "off"
environments {
   test {
	paypalurl = "https://www.sandbox.paypal.com/cgi-bin/webscr"
   }
   production {
	   analytics = "on"
	   paypalurl = "https://www.paypal.com/cgi-bin/webscr”
   }
}

and use the grailsApplication.config.paypalurl convention so you can seperate the test from the production.
For Dev I used a mix of stuff with a selenium test for  checking the call from paypal. below is one I use in my test calls.
?shipping=0.00&txn_id=573053526782394N&mc_fee=0.39&charset=windows-1252&address_country=United States&item_name=Stuff they bought&payment_status=Completed&address_state=FL&address_street=payer address&verify_sign=A2Aln3iC.testuffthatsunreadablegx2Elkzx&address_status=confirmed&payment_fee=0.39&payment_gross=233.99&quantity=1&first_name=payername&address_city=payercity&address_country_code=US&item_number=&mc_currency=USD&residence_country=US&payer_email=payer@foopayer.com&address_name=Brian Doyle&controller=ipn&txn_type=web_accept&payer_status=unverified&last_name=Doyle&payment_type=instant&invoice=W2008041358&payer_id=V636&receiver_id=6VX7YJ&payment_date=20:59:18 Apr 13, 2008 PDT&mc_gross=2.99&tax=0.00&notify_version=2.4&address_zip=12345&receiver_email=paypal@foomydomaintest.com&custom=27&business=paypal@foomydomaintest.com
 Also fix the business from test to production.
Need to make this a plugin....
Questions, Comments, and Improvements Accepted below...

update nice guide on how olaf descripes IPN IPN Diagram From the Dzone Dzone Link

Rational Application Developer 7.0 on Ubuntu J2C Issue

Wednesday, November 7th, 2007

If you are running RAD 7.0 on Ubuntu (I could only verify that this problem exists in Ubuntu 7.10 Gutsy). One of my co-workers had a problem defining the j2c in the admin console in RAD. RAD would kill itself on the update or apply button. Get the big nasty afu dialog.

The work around is to use Firefox (that’s what I used) to configure the server j2c properties. I’m not exactly what the problem is but using the other browser seems to work just fine. http://localhost:9060/admin

Hope this helps others and saves some time.

Developer ADD Helper for Ubuntu Gutsy

Friday, October 5th, 2007

I’m using the development release of Ubuntu (Gutsy). I previously set up Beryl on my home computer with the Feisty release and have enjoyed highly.  Now using the development release on my laptop  (6910p from HP)  using the compiz fusion for  Ubuntu is awesome.

The best stumbled upon feature is the Accessibility ADD Helper IMO. I’m not ADD but sometimes your desktop distracts you from your own work e.g. Changing Songs notifier, new email shows up, or even a buddy pings you on IM. You lose some focus from your task. I set up the short cut to use [Super (that darn microsoft key ) + P] to fade all of the noise to the background.

I find using this feature gets me in the ‘zone’ much quicker.

Here are the settings I am currently using [Toolbar | Utility | Dialog | ModalDialog | Fullscreen | Normal | Dock] in the Misc. Options via the CompizConfig Settings manager. I did have to dig around for the other settings.

Now if I could only press Super + STFU for the background noise … but that’s what active noise canceling is all about. I recommend the SBC HN110 from Phillips check ebay for some good deals.

Europa on old hardware

Thursday, July 19th, 2007

Eclipse Europa is out. I have it on my work laptop, the home dev box, the work computer, and now on the Missus roving celebrity web checking machine that is the laptop around the house.

This is a IBM T23 ThinkPad that I picked up on ebay for 200 bucks. P3 256MB with a 30 Gig HD. With a new refurbished battery from the good folks at Battery-Refill and an older battery in the superbay slot I got on ebay yet again for about 15 bucks. So we can get about 6 hours on the thing at full charge.

Tuesday night I’m lounging on the couch thinking I could fire up my hp nx9660 and try to manage the 10lb beast and try not to catch my pants on fire OR see if the very small install 75mb install of Europa would work. Sure enough I ssh’ed the home dev box, downloaded the install, unzipped/untarred it and fired it up. My machine slooooowed to a crawl.

Then I had an idea. Throw BlackBox on and see if that works. Suddoed APT-Getted the appropriate stuff logged out. Gently asked the GDM to log me in as a BlackBox seesion fired up the terminal and launched Europa.

DANG! It was fast. A handful of processes and I was in Europa Heaven. The neat little effects when you do the CTRL-M to maximize you editor worked great in the GTK environment. I was now sitting on the couch without a fire extinguisher next to me while coding some katas and watching Eureka.

Overall Europa performed quite well for what I was doing. It just shows the impressive progress that the eclipse community has put into this release. I don’t think I could use that hardware with a JEE server on it … well maybe Jetty.

Feisty Fawn and the extrernal USB Drive

Thursday, July 19th, 2007

Yesterday, I received my new shiny external hard drive so I can run some VM Ware appliances. (Lucky me). I happen to be the developer who runs “that linux” at work. So I plugged in the drive to fire up the images and BAM no love. Ubuntu auto-mounted the drive no-problem so why could I not fire up the image? Ahh no permissions no problem a quick chmod on the drive, wait nope. Checked the auto-mout parameters DOH! it’s an NTFS drive. Changed the mount point and the umask so I could do all this. Did this using the GUI right-click properties on the mounted drive. I thought this would work since the ntfs3-g package was installed. This package lets you read and write NTFS file systems (as long as it’s not in a suspended state!).

Unplugged the drive, plugged it back in. No go the auto-mount could not mount. I had placed a trailing “/” on the mount point. Now here is where everything went nuts. Where does that meta data about the drive get stored? After much searching and much frustration I narrowed down the search results to: “mount_point cannot contain the following characters: newline, G_DIR_SEPERATOR (usually /)” found the bug over on the Bug .

You have to change the keys. Here is the relevant key location : “/system/storage/volumes/_org_freedesktop_Hal_devices_voume_uuid_*/mount_point” I launched the gconf-editor as the user I originally mounted the drive with. Do not launch with root or you will never find it. I deleted the key and remounted no problem!

The good folks over at Ubuntu have a patch in the works but until then I hope this helps the search results for others.

Eclipse Shortcuts

Monday, February 26th, 2007

Place holder for comments.

Setting up a xul development environment with MyEclipseIde

Saturday, January 6th, 2007