Archive

Archive for the ‘Apex’ Category

Seattle Force.com Developer Group

March 3rd, 2010 No comments

Heads up that if you are a Force.com/Salesforce developer or want to learn more about force.com development in the Seattle area there is a meeting this Thursday, the 4th.

The meetings as always will be held in the West Monroe Partners office located at:

1215 4th Ave, Suite 1010

Seattle, WA 98161

When:  Thursday, March 4th, 2010

Start Time: 4:00 PM

This session will be an open forum so bring any questions, problems, and/or issues you have so we can discuss with the group. If we finish early, we can maybe grab a beer at one of the local bars downtown.

If you are interested even a little please stop by.

Categories: Apex, Technology, Visualforce

If Computers Could Barf – Salesforce Debug Log

March 1st, 2010 13 comments

This story starts some time ago. I have been complaining about the system/debug log in salesforce.com ever since they released what I would consider version 1.1. You can see my post here, Please fix the Debug Log!, pleading for salesforce to fix the debug log. This was back in July of 2008! From what I can tell there has only been two noticeable changes with this debug log. I will refer to them as version 1.1 which was implemented around the time of the message board post above and the the most recent Spring ‘10 incarnation which I will refer to as version 2.0.

I still remember the good old days of the debug log, version 1.0 . Everything was so peachy! Apex was brand new. The debug log output was concise and easy to use. Times where good. Version 1.0 was the best! Sigh…… (this is a sigh of fond happy memories). It’s pretty sad version 1.0 is what I consider to be the best, usually software is supposed to get better with subsequent releases right? Right?!?!?

The clouds became dark (pun intended ;-) ) with version 1.1. Now the debug log could log workflow and validation rules! Great! Now my debug logs are incredibly long and full of junk that I rarely, and 99% of the time, never care about when debugging Apex. In orgs that have a lot of workflow rules this makes it terribly painful to do bulk debugging. But Jason, simply set the Log Category to Apex Code and it will only show Apex related output.

logcategory

BWAHAHHAAHHAHA, oh man, that’s a good one. Up until version 2.0 this had never worked right. It doesn’t matter what you set the Log Category to as it never outputs what you want it to.

I remember attending the “Meet the Developers” session at Dreamforce 09 and hearing the salesforce team say that a new and improved debug log was coming. The room literally roared with applause. I was one of those clapping with excitement. When I finally was able to access the new debug log I was giddy with excitement. Will this be everything I have hoped and dreamed for? Will it save me tons of time? Will it make me a hot breakfast every morning? To my amazement and surprise it has fallen short on nearly all of my expectations.

You can’t re-size the input box. This was an incredibly useful feature. Why would a useful feature be removed? It makes no sense. Yes, there are work arounds using browser plugins such as Gresemonkey and Stylish but people don’t want workarounds. They want it to just work.

I may be on a pretty good rant but I have no right to complain if I make no attempt to help improve the tool. I decided to take a stab and building this re-size functionality and it literally took me less than 10 minutes to get a working prototype using jQueryUI. You can check it out here. It is a little rough around the edges but if I can build a working demo this quick there is absolutely no reason salesforce shouldn’t be able to incorporate this functionality.

The output is also hideous. Perhaps this is the way Java code typically outputs debug logs. I don’t have enough experience to know. What I do know is this new version makes my life less happy. From a usability perspective the old version was much easier to quickly scan and find what you were looking for. Let’s compare.

Below I will show the debug outputs for a very simple piece of code. Here is the code:

for(Opportunity opp : [select Id, Name, Amount from Opportunity]){
	system.debug(opp);
}

First let’s look at version 1.1, pre Spring 10.

20100210185937.897:AnonymousBlock: line 1, column 1: SelectLoop:LIST:SOBJECT:Opportunity
20100210185937.897:AnonymousBlock: line 1, column 23: SOQL query with 6 rows finished in 5 ms
20100210185937.897:AnonymousBlock: line 2, column 1: Opportunity:{Name=Territory Test, Amount=152989.18, Id=00660000008gWE1AAM}
20100210185937.897:AnonymousBlock: line 2, column 1: Opportunity:{Name=Pipeline Date Test, Amount=5000.00, Id=00660000008gpbDAAQ}
20100210185937.897:AnonymousBlock: line 2, column 1: Opportunity:{Name=Product Alert Test 123, Amount=555000.00, Id=00660000008gCQ7AAM}
20100210185937.897:AnonymousBlock: line 2, column 1: Opportunity:{Name=Giant Product List, Amount=0.00, Id=00660000009lsB7AAI}
20100210185937.897:AnonymousBlock: line 2, column 1: Opportunity:{Name=Silver Error, Amount=150000.00, Id=00660000009lx17AAA}
20100210185937.897:AnonymousBlock: line 2, column 1: Opportunity:{Name=Visual Force, Amount=0.00, Id=0066000000AFuB8AAL}
20100210185937.897:AnonymousBlock: line 1, column 1:     Number of iterations: 1
 
Cumulative resource usage:
 
Resource usage for namespace: (default)
Number of SOQL queries: 1 out of 100
Number of query rows: 6 out of 10000
Number of SOSL queries: 0 out of 20
Number of DML statements: 0 out of 100
Number of DML rows: 0 out of 10000
Number of script statements: 6 out of 200000
Maximum heap size: 0 out of 2000000
Number of callouts: 0 out of 10
Number of Email Invocations: 0 out of 10
Number of fields describes: 0 out of 10
Number of record type describes: 0 out of 10
Number of child relationships describes: 0 out of 10
Number of picklist describes: 0 out of 10
Number of future calls: 0 out of 10
Number of find similar calls: 0 out of 10
Number of System.runAs() invocations: 0 out of 20
 
Total email recipients queued to be sent : 0
Cumulative profiling information:
 
1 most expensive SOQL operations:
AnonymousBlock: line 1, column 23: [select Id, Name, Amount from Opportunity]: executed 1 time in 5 ms
 
No profiling information for SOSL operations.
 
No profiling information for DML operations.
 
No profiling information for method invocations.

Why do I like this? It is incredibly easy to identify line and column numbers. When debugging I am usually focused on a specific area. In any browser I can hit CTRL-F, enter “line 142″, and be taken straight to the area I am debugging. The output is very clean and concise with no unwanted garbage. It simply has my debug statements. It also provides a nice clean summary of limits and the most expensive methods, SOQL, SOSL, and DML statements. This is great information to know when optimizing code. For me this is perfect. The only issue I had with version 1.1 was that if my code had any DML statements it would output all of the work flow and validation criteria because the filters did not work as mentioned above.

Now lets take a look at version 2.0 released with Spring 10.

Below are the filter settings I used for this:

filters
11:03:30.381|EXECUTION_STARTED
11:03:30.381|CODE_UNIT_STARTED|[EXTERNAL]System Log Window
11:03:30.393|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)
11:03:30.393|USER_DEBUG|[2,2]|DEBUG|Opportunity:{Name=Edge SLA, Amount=60000.00, Id=006A0000002YZZ9IAO}
11:03:30.393|METHOD_EXIT|[2,2]|debug(ANY)
11:03:30.393|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)
11:03:30.393|USER_DEBUG|[2,2]|DEBUG|Opportunity:{Name=Grand Hotels Kitchen Generator, Amount=15000.00, Id=006A0000002YZZAIA4}
11:03:30.393|METHOD_EXIT|[2,2]|debug(ANY)
11:03:30.394|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)
11:03:30.394|USER_DEBUG|[2,2]|DEBUG|Opportunity:{Name=Grand Hotels SLA, Amount=90000.00, Id=006A0000002YZZBIA4}
11:03:30.394|METHOD_EXIT|[2,2]|debug(ANY)
11:03:30.394|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)
11:03:30.394|USER_DEBUG|[2,2]|DEBUG|Opportunity:{Name=Express Logistics Portable Truck Generators, Amount=80000.00, Id=006A0000002YZZCIA4}
11:03:30.394|METHOD_EXIT|[2,2]|debug(ANY)
11:03:30.394|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)
11:03:30.394|USER_DEBUG|[2,2]|DEBUG|Opportunity:{Name=Express Logistics SLA, Amount=120000.00, Id=006A0000002YZZDIA4}
11:03:30.394|METHOD_EXIT|[2,2]|debug(ANY)
11:03:30.394|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)
11:03:30.394|USER_DEBUG|[2,2]|DEBUG|Opportunity:{Name=Express Logistics Standby Generator, Amount=220000.00, Id=006A0000002YZZEIA4}
11:03:30.394|METHOD_EXIT|[2,2]|debug(ANY)
11:03:30.394|CODE_UNIT_FINISHED
11:03:30.394|EXECUTION_FINISHED

And this brings us back to the title of this post. If computers could barf I’m pretty sure it would look like the output above. Basically every pro in the previous example has now become a con. The noisy output makes it difficult to isolate line numbers and specific areas. This small example is not so bad but imagine a debug log with hundreds if not thousands of lines. What was done in 9 output lines now takes 22 lines!

What is the point of this line: “11:03:30.394|METHOD_EXIT|[2,2]|debug(ANY)” when the line that is actually a debug statement says “|DEBUG|”. I’d really like to know as it looks pretty pointless.

This line is also unnecessary, “11:03:30.394|METHOD_ENTRY|[2,2]|system.debug(SOBJECT:Opportunity)”. Yes, thank you for letting me know I am debugging an Opportunity. I was the one who wrote this debug statement so I know what I am debugging. The next line that says, “Opportunity:{Name=Express Logistics” also lets me know I am debugging an Opportunity. I see how this could be helpful for someone looking at new or unfamiliar code but for me it does nothing more than get in the way.

You will also notice the limit and performance metrics are gone. The only way to get these metrics back is to enable Database logging but then the output starts to includes items that I may not want, again making the output even longer.

Not all is bad with version 2.0. The ability to save the debug logs is useful and the logging criteria actually works.

What I want to be able to do is get a very clean and easy to read output that only displays system.debug() statements with limit and performance metrics. Nearly 2.5 years after I started developing Apex I still don’t have this and it makes me sad.

Salesforce.com usually gets it right but with this particular feature I feel like they keep striking out. It feels like this tool received little to no customer usability testing. The CRM piece of salesforce is always having usability testing done but I have never been approached to give feedback on the developer tools. I would encourage the salesforce.com dev group to reach out and do a little usability testing. It doesn’t need to be super formal usability testing. Quick online group meetings with force.com developers would suffice. There are plenty of good force.com developers out here that are more than willing to give constructive feedback on features like this.

The issues I have expressed concern about may eventually be fixed but we are at least four months away from the next release and based on past changes (or lack there of) to this tool I can’t be optimistic that improvements will be made quickly. This tool is was close to being perfect and I think it could have hit a home run if it incorporated some user feedback before it was rolled out.

</end rant>

Categories: Apex

How many lines of Apex code do you have?

February 9th, 2010 1 comment

I have always been curious how many lines of Apex code I have written. Is it a couple hundred (haha, ya right), several thousand, a gazillion million trillion? There was never really a good way to figure this out unless you pulled down all of the data and inspected it file by file. Lame.

Enter Spring 10 and the removal of limits on collection size. Dooo da doooooo (trumpet music)!!!!!!! The data to figure out the number of lines has always been available but it has been difficult to process. All apex class and trigger code is stored in two tables that can be accessed by SOQL. The first part is easy, simply query all of the data, and count the lines. Before Spring 10 there was no good way to count the lines. There is no apex method to count the number of string matches, ie: count number of ‘\n’ breaks. There is a split method that cuts up a string based on pattern matches. What we can do is populate a list of strings split by \n. This will create one entry in our list for each line. TADA! Before Spring 10 this would not have worked if a class had more than 1000 lines as a list could only hold 1000 elements.

Now I know lines of code is totally subjective. Some weirdos will write code like this, 7 lines:

public void doSomething()
{
	if(something)
	{
		//do awesomeness
	}
}

While the cool kids will do it like this, 5 lines:

public void doSomething(){
	if(something){
		//do awesomeness
	}
}

However your write code, the weirdo way or the cool kid way, it is just darn fun to see how many lines you have written.

Here is the code that will give you that answer. Simply copy and paste this to your system log and hit execute. Then dig through a giant debug log that is still horrible (rant on that later) for 3 simple debug lines.

13:35:17.470|USER_DEBUG|[14,1]|DEBUG|Apex Class lines: 21388
13:35:17.470|USER_DEBUG|[15,1]|DEBUG|Apex Trigger lines: 1425
13:35:17.470|USER_DEBUG|[16,1]|DEBUG|Apex Total lines: 22813

Integer classLines = 0;
Integer triggerLines = 0;
 
for(ApexClass a : [Select Body From ApexClass]){
	List<String> lines = a.Body.split('\n');
	classLines += lines.size();
}
 
for(ApexTrigger a : [Select Body From ApexTrigger]){
	List<String> lines = a.Body.split('\n');
	triggerLines += lines.size();
}
 
system.debug('Apex Class lines: ' + classLines);
system.debug('Apex Trigger lines: ' + triggerLines);
system.debug('Apex Total lines: ' + (classLines+ triggerLines));
Categories: Apex

If Visualforce Blows, This Sucks

January 11th, 2010 55 comments

I recently saw a tweet that included nothing but a link and a lot of salesforce.com related tags.

Visual Force Blows (link was shortened in original tweet so I couldn’t see title)

What could this be I pondered? A new product announcement? A glowing review of the force.com platform? Upon clicking the link I entered the “I hate Apex and Visualforce Zone” (Dun Dun Dunnnnnnnnnnn). Some dude on a blog (man, everyone has a blog now days) is trying to build a dynamic link menu with data pulled from salesforce objects and using visualforce to display. This seems pretty normal right? Let us check out some excerpts first:

On Apex and Visualforce:

Sounds great in theory, however in reality it makes you want to stab yourself. A lot.


I on the other hand would bathe in it if I could. Oh ya….Visualforce and Apex, sooo bubbly clean. Ya, that was weird. Let’s move on.

Problem is, it uses what is called MVC (Model View Controller, or some shit like that) which divides your logic code, from your design code (oh my god, they invented the idea of functions that can be called, how fucking astounding). Seems like a solid plan, cause your design team and your programming team get to work separately and not step all over each others code. Problem is, I am the design team, and the coding team. That means I get to deal with the whole project from the ground up and deal with all the over engineered bs.


Whoa whoa whoa! The harshness, it hurts, but wait a second, isn’t the MVC concept pretty common. Isn’t this what all of those crazy iPhone apps use? And about a gazillion other languages.

Separating the design team and programming team is not really the purpose of this as both must work together to build awesome apps (even if it is the same person). The real advantage is that the styling/layout and logic are separate. This makes it much easier to code, debug, troubleshoot, and rework in the future. Anyone who has used the old s-controls can atest to this fact. Let us continue.

So what is the developer trying to do. He (she?) wants to simply create a navigation menu with links that have sub links. With his (we will assume it’s a he, sorry ladies) approach is that it stores all of the link relationships in one object. At first this may seem like a more simple and streamlined approach but this will soon spin out of controll as seen by the post in question.

In cold fusion he said he could do this in 6 lines but it doesn’t look like the example includes the sub links. So how about a Visualforce solution that includes sublinks in 10 lines of Apex and 11 lines of Visualforce (including class name, Visualforce page, and componenet tags)? Oh ya! It also only took me about 30 minutes to build. Double oh ya!

The first thing I would do differently is break this up into two objects. Link and Sub Link. Why more objects? We can then use the out of the box relationships to query all sub links when we query the links. This will actually significantly reduce the amount of required code. Each object has two text fields, URL and Label. The Sub Link object also has a lookup to the Link object. This approach also makes it much easier to maintain from a admin/user perspective. You can see all sub links for a link on one page.

links

Before we jump in to the code you can check out the snazzy demo here:

http://tehnrddemos-developer-edition.na7.force.com/linkmenu

First let’s look at the controller for the custom component we will be using. What we do is query the link object and all sub links related to the “parent” link at the same time. Technically I could make this class have even less lines but this example follows best practices so I won’t.

public class linkMenu{
    List<Link__c> links;
 
    public List<Link__c> getLinks(){
        if(links == null){
            links = [select Label__c, URL__c, (select Label__c, URL__c from Sub_Links__r) from Link__c];
        }
        return links;
    }
}

Next up is the component. This loops through all of the parent links and outputs a hyperlink. For each parent it will then loop through the sub links and create a link that is indented slightly for each.

<apex:component controller="linkMenu">
    <apex:repeat value="{!links}" var="l">
        <apex:outputLink value="{!l.Url__c}">{!l.Label__c}</apex:outputLink><br/>
        <apex:repeat value="{!l.Sub_Links__r}" var="sl">                
            <apex:outputLink value="{!sl.Url__c}" style="margin-left:10px;">{!sl.Label__c}</apex:outputLink><br/>
        </apex:repeat>
    </apex:repeat>
</apex:component>

And finally the page. This is were it gets sort of complicated. Sorry about that.

<apex:page >
    <c:linkMenu/>
</apex:page>

So what have we learned today? I think if the other post is accurate in its statement that Visualforce blows than I am going to assume that this post really really sucks.

Oh, and don’t worry Apex and Visualforce creators, PMs, and team. I will protect you.

Apex and Visual Force (they are the bane of my existence on this planet and I would die a happy man if their creator(s) where beaten with reeds to within an inch of their life).

But seriously, what is up with this guy? I’ll admit some rants are funny but this is going over the top and you should try to keep it a little professional. Bridge burned. This is that last time I will provide any type of assistance to this guy.

EDIT: Oh darn! Just realized I named this post “If Visualforce Sucks, This Blows”. That was backwards. It is fixed now.

Categories: Apex, Visualforce

Seattle Force.com Developer Meeting

January 6th, 2010 No comments

Tomorrow, January 7th, there will be another Force.com Developer Meeting in Seattle (first Thursday of every month). If you develop on the Force.com platform with Apex, Visualforce, use the API, or want to learn more about these topics please feel free to join us.

Date: Thursday, January 7th.

Time: 8:00 – 10:00 AM PST

Location: West Monroe Partners
1215 4th Ave Suite 1010
Seattle, WA 98109

The West Monroe Partners office is located on the 10th floor.

Public Parking garages are located in the building, as well as in a 1-2 block radius. The area is also well serviced by public transportation.

The agenda for this meeting will be as follows:

  • Presentation/Demo – Jason Venable (tehnrd.com) will be demoing his runner up application he created for the most recent Force.com Cloud Developer Challenge. The site is GameForce and includes two games: Blackjack and multiplayer connect four. (http://tehnrd-developer-edition.na7.force.com/gamehome). It was built with 100% Force.com, no flash or JavaScript. Jason is a Salesforce.com Admin and Developer at F5 focused mainly on process automation for the worldwide sales team.
  • Open forum – opportunity to discuss any questions/issues you may have about all things Salesforce

If you are planning on attending this month’s meeting, please send me an email (vgrasparil@westmonroepartners.com) to RSVP.

If you would like to present an application you have built or share some best practices you have learned with the group, please let me know so we can schedule it into a future meeting.

See you on January 7th!

Yup, thats me! I’ll be showing off the gaming site I built on force.com, http://www.tehnrd.com/gameforce/. I’ll show off the basic UI stuff but we will also peel back the covers to see how it works the magic on the back end.

Categories: Apex, Visualforce

Batch Apex Status Bar

December 18th, 2009 6 comments

Batch Apex is here and it is cool. In some of the demos and webinars salesforce.com has put together you may have seen a status bar that represents how far along a batch job has proceeded. This is useful as you only need but a quick glance to see how your batch jobs are doing. Below is an image of what this would look like.

batchstatus

All of this magic status bar stuff is pretty simple. You have two divs, an inner and an outer that construct the status bar, the inner being the percent complete. All of the info to construct this status bar is located in a sObject called AsyncApexJob. This stores information about your batch jobs and other asynchronous operations.

The two important fields in this object are JobItemsProcessed and TotalJobItems. When a batch job is executing it may process millions of records but it will break these up into batches of 200, or less if defined……hence the name Batch Apex. So if I have 5,000 records to be processed there would be 25 batches of 200. In the AsyncApexJob object these 25 batches would be the TotalJobItems. As the job runs the number JobItemsProcessed will increase as the batches are completed.

Now that we have these two number calculating the percent complete is an utterly simple division equation. JobItemsProcessed divided by TotalJobItems times 100 gives us the percent complete. We then pass this value to the width of the inner div and our status bar is complete! To give the status bar the appearance of being animated we add an actionPoller to the page and rerender the table of batch jobs every five seconds which will intern update that status bar with the new values.

As always there is a fun little demo to play with and you can access that here: Click here for nifty cool demo.

I’ve also packaged up this component so you can install it directly to your org. You can download it here.

Here is all the code and markup. First the page that will contain the batchJobs component.

<apex:page controller="batchStatus">
    <apex:form>
        <apex:commandButton value="Start Batch Job" action="{!startBatch}" reRender="jobs,error"/> 
        <apex:outputText id="error" value="{!error}" style="font-weight: bold; color: red"/>
 
        <br/><br/>
        <c:batchJobs id="jobs" numberOfJobs="20"/>
    </apex:form>
</apex:page>

Next we have the Visualforce component:

<apex:component controller="batchJobs" selfClosing="true">
    <apex:attribute name="numberOfJobs" type="Integer" assignTo="{!numberOfJobs}" description="The number of batch jobs to display in the table."/>
 
    <!-- Here is the css styles that will be used for the progress bars -->
    <style>
        .progressBar{
            background-color: #f8f8f8;
            border:1px solid #DDDDDD;
            height: 19px;
            width: 300px;
            -moz-border-radius: 5px; 
            -webkit-border-radius: 5px;
        }
        .progress{
            background-color: #F7B64B;
            border:1px solid #E78F08;
            height: 100%;
            margin: -1px;
            text-align: center;
            -moz-border-radius: 5px; 
            -webkit-border-radius: 5px;
            line-height: 18px;
        }
    </style>
 
    <!-- This action poller will check the status of the batch jobs every 5 seconds -->
    <apex:actionPoller rerender="jobs" interval="5"/>
 
    <apex:pageBlock title="Batch Apex Jobs">
        <apex:pageBlockTable value="{!batchJobs}" var="b" id="jobs">
            <apex:column headerValue="Apex Class" value="{!b.job.ApexClass.Name}"/>
            <apex:column value="{!b.job.CreatedDate}"/>
            <apex:column value="{!b.job.CreatedById}"/>
            <apex:column value="{!b.job.Status}"/>
            <apex:column width="320px" >
 
                <!-- Here with have two divs that construct our progresses bar. An outter which is the entire bar,
                and and inner that represents the percent complete. We simply pass the percentComplete value to
                the inner div width and this will show how far along the job is. Brilliant! -->
 
                <div class="progressBar">
                    <div class="progress" style="width: {!b.percentComplete}%;">
                        {!b.percentComplete}%
                    </div>
                </div>
 
            </apex:column>
            <apex:column value="{!b.job.CompletedDate}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
 
</apex:component>

And finally the custom controller for the component….. where all the magic happens:

public class batchJobs{
 
    public List<BatchJob> batchJobs;
    public Integer numberOfJobs {get; set;}
 
    public List<BatchJob> getBatchJobs(){
        //Create new list of BatchJobs, a wrapper class that includes the job and percent complete.
        batchJobs = new List();
 
        //If number of jobs was not defined, default to 20
        if(numberOfJobs== null || numberofJobs <= 0){
            numberofJobs = 20;
        }
 
        //Query the Batch apex jobs
        for(AsyncApexJob a : [select TotalJobItems, Status, NumberOfErrors, MethodName, JobType, JobItemsProcessed, Id, CreatedDate, CreatedById, CompletedDate, ApexClassId, ApexClass.Name From AsyncApexJob order by CreatedDate desc limit :numberOfJobs]){
            Double itemsProcessed = a.JobItemsProcessed;
            Double totalItems = a.TotalJobItems;
 
            BatchJob j = new BatchJob();
            j.job = a;
 
            //Determine the pecent complete based on the number of batches complete
            if(totalItems == 0){
                //A little check here as we don't want to divide by 0.
                j.percentComplete = 0;
            }else{
                j.percentComplete = ((itemsProcessed  / totalItems) * 100.0).intValue();
            }
 
            batchJobs.add(j);
        }
        return batchJobs;
    }
 
    //This is the wrapper class the includes the job itself and a value for the percent complete
    public Class BatchJob{
        public AsyncApexJob job {get; set;}
        public Integer percentComplete {get; set;}
    }
 
    /*--------------------TEST METHOD------------------------*/
    static testMethod void batchStatusBarTest(){
        batchJobs controller = new batchJobs();
        controller.getBatchJobs();
    }
}

I initially planned on adding all sorts of cool features to this component such as color coding the status bar based on the status of the job and estimated time to completion. These were axed in 1.0 as it was taking too long and there our some other cool posts I have lined up that I want to get working on. Maybe in the future I’ll post an updated version of this component with all the flair it deserves.

UPDATE:

I’ve been asked a couple times what exactly happens when a user clicks the <apex:commandButton value=”Start Batch Job” action=”{!startBatch}” reRender=”jobs,error”/> button. This calls a very simple method in the controller that starts a batch job.

public void startBatch(){
	error = '';
	batchJob job = new batchJob();
	List<AsyncApexJob> openJobs = [select Id from AsyncApexJob where Status = 'Processing' OR Status = 'Queued']; 
 
	if(openJobs.size() < 5){
	        ID batchprocessid = Database.executeBatch(job);
	}else{
		error = 'WHOA BUDDY! Only five batch jobs at a time.';
	}
}

And here is the batch apex job.

global class batchJob implements Database.Batchable<SObject>{
 
    global database.querylocator start(Database.BatchableContext bc){
        return Database.getQueryLocator('select Id, Name from Account where Type = \'Batch Test\'');
    }
 
    global void execute(Database.BatchableContext bc, sObject[] objects){
        List<Account> accns = new List<Account>();
 
        for(sObject s : objects){
            Account a = (Account)s;
            a.Description = 'batch testing. blah blah blah.  ' + system.now();  
            accns.add(a);
        }
        update accns;
    }
 
    global void finish(Database.BatchableContext bc){
       system.debug('all done');
    }
}
Categories: Apex, Visualforce

Error Handling, Savepoints, and Inserts

October 19th, 2009 2 comments

I’ve been working with Apex for a little over two years now and I still learn little tips and tricks all the time.

Today I ran in to a somewhat peculiar problem when trying to catch errors on the insertion of a record. Here is the scenario in super pseudo apex code.

1) Set a database save point with Apex
2) Insert a record with Apex
3) Some type of validation error prevents the record from being inserted
4) Using a try-catch statement catch the error and display it to user
5) Roll back to your Database savepoint
6) Allow the user to fix the error.
7) When the save occurs the second time I would receive this error: “cannot specify Id in an insert call”

Huh, wait….what? The insert failed because of the validation rule, right? Kinda, sort of, it’s not really clear. Even though the insert failed my object in memory was still being assigned an Id. This caused a problem when trying to insert the second time.

I’m guessing salesforce.com sets the ID of a record before the insert as you can’t set values after inserts as the object would become read-only. Similar to how triggers work, you can only write values before inserts and updates, not after. When the operation fails the Id in the code is not removed. This is a giant guess on how the process works and it could be totally wrong.

So how to get around this problem? The solution is fairly simple. In the catch section of the code we want to clone the record without preserving the Id and assign this clone back to the original object. Something like this:

Savepoint sp = Database.setSavepoint(); 
try{		
	insert object;
}catch(exception e){
	Database.rollback(sp); 
	object = object.clone(false);
	return null;		
}

The false parameter in the clone method makes an exact copy of the object without preserving the Id. So the next time the user attempts to save, the Id is null, and there should be no issues.

Categories: Apex

Apex Flow Control – Preventing Infinite Loops

October 2nd, 2009 5 comments

When you build your first few triggers everything is so peaceful. The grass is green, the birds are chirping, and everything is working wonderfully. You continue to develop more triggers, classes, batch jobs, @future classes, and then one day your realize, “Great Scott!, I have created a monster”. If you connected all the classes and triggers that were related it would look like a giant spaghetti dinner.

When this happens you will undoubtedly run into one very specific problem. You have a piece of code A that causes code B to execute which then causes code A to execute which then causes code B to execute. OH NO! Infinite loop, governor limits AHHHHH!

Fear not! For there is a very simple solution to this problem. The extremely clear and concise diagram below shows a common scenario.

flowj

Let’s say we have an update trigger that sends a group of objects to be processed by an @future asynchronous method. There is a good chance this method will need to update the records. This would normally cause the trigger to execute and the @future method to be called again, hence our unstoppable loop. So how do we stop this loop? Before we perform the update on the records we need to say, “Hey, this is a update from a @future methods, don’t do anything”. We can do this by creating a simple Boolean value in a utility class and can be accessed by anycode in context of the update operation.

Below is the code of how something like this would work. First let’s look at the very simple solution. Yup, this is it. Some minor changes to our @future and trigger code and this is it.

public class utility{
 
    public static boolean isFutureUpdate;
 
}

Here is the trigger, we only want the code in this trigger to execute if the isFutureUpdate variable is not true.

trigger updateSomething on Account (after insert, after update) {
 
    /*We only want this trigger to perform it's logic when the
    update is not from an @future method */
    if(utility.isFutureUpdate == null || utility.isFutureUpdate == false){
 
        Set<Id> idsToProcess = new Se<Id>();
 
        for(Account acct : trigger.new){
            if(acct.NumberOfEmployees > 500){
                idsToProcess.add(acct.Id);
            }
        }
 
        //Send Ids to @future method for processing
        futureMethods.processLargeAccounts(idsToProcess);
 
    }
}

And here is our @future method. The only thing we need to add is one line of code to set the isFutureUpdate variable to true before we perform the update.

public class futureMethods{
 
    @future
    public static void processLargeAccounts(Set<Id> acctIDs){
 
        List<Account> acctsToUpdate = new List<Account>();
 
        /* Do awesome stuff with apex code */
 
        /*Before we perform this update we want to set the 
        isFutureUpdate boolean in our utility class to true */
        utility.isFutureUpdate = true;
 
        /*Now we can perform the update. The trigger will still 
        fire but none of the code inside of it will execute and
        this method will not be called again*/
        update acctsToUpdate;
    }
}

Now when the trigger is fired the @future method will not be called again.

This example shows the interaction between asynchronous operations but you can use this same solution if you have triggers that update triggers and cause a loop.

Categories: Apex

Seattle Force.com User Group

September 29th, 2009 1 comment

This is sort of a late notice but on October 1st there will be a Force.com user group in Seattle. If you are in the area and want to exchange ideas and best practices revolving around the Force.com platform please swing by.

Want to take a deeper dive into the technical capabilities of Salesforce? Would you like to meet other Force.com developers in the Seattle area? Interested in learning about new/different tools that will help you create and develop better solutions? A new Salesforce user group will be starting up on Thursday Oct 1. Meetings will be held on the first Thursday of every month.

We will try to cover a different range of topics at these monthly meetings such as:

  • Summary of new functionality in the upcoming release
  • Project spotlight where someone will demo their project and the technical details
  • Best Practices
  • 3rd Party development and integration tools
  • Apex and VisualForce
  • Open session to discuss specific questions you may have regarding your current projects

Time: 8-9am
Date: Oct 1, 2009
Location:

West Monroe Partners
1215 4th Ave Suite 1010
Seattle, WA 98161

Please contact Val Grasparil (vgrasparil@westmonroepartners.com) or Andrew Brown (abrown@westmonroepartners.com) if you have any questions.

Since it is in the morning, coffee and snacks will be provided. Please RSVP if you are planning on attending so we can make sure to have enough food for everyone.

Reach out directly to Val to RSVP. I’ve been told there is public parking available at the address above.

Gameforce

August 28th, 2009 7 comments

Update: Video posted below.

This is my first post in nearly three weeks and my first Force.com related post in nearly a month. Where have I been you may wonder? Only working on the coolest Force.com site in the world :-P .  Haha, just kidding.  But yes, for the past 2 months I have been slowly chipping away on my entry for the Force.com Cloud Developer Challenge. So what did I build?

Gameforce - The Worlds 1’st online gaming site built upon the Force.com platform.

When I set out to build my entry I wanted to build something that had never been done before. We have all see the blogging, HR, accounting, shopping cart, content management, and many other traditional business apps. There is no doubt these can be super cool but in the end most of them have been done before. Salesforce.com and Force.com are typically viewed as a platform for business apps and I wanted to build something on the complete opposite end of the spectrum. I hope I have succeeded with building an online gaming site.

The site consists of two games: blackjack and LineUp4 aka Connect 4.

Blackjack
Place your bets and play against the dealer.

blackjack

LineUp4

A true online multiplayer game where two people can play against each other anywhere in the world. It also has the ‘Smack Talker’ which is live chat between the players. You can see more features listed on the about page located here.

lineup4

This site may not have the coolest graphics or the trendiest web design but when it comes to taking the Force.com platform to the limit I have used every trick in the book that I know about. When checking out this site keep in mind it was built with 100% Force.com. There is no extra javascript, flash, or any other web technology.

Video update:
After seeing how cool some of the videos were that other people created showing of their site  I created one as well. It gives a great overview in about 5 minuets. The one feature I forgot to mention in the video is that if you are playing a game of LineUp4 and are not logged in, you can log in, and will be returned to the game right where you left off. The game state will be saved.

http://tehnrd.com/gameforce.swf (if the video is to large for your screen, right click on the video and select ‘Show All’)

Now we wait for the results of the contest. I’m hoping this site puts me in contention for the Mac Book prize. I’m sure there are going to be some great entries but I’m hoping for the best since this site is like nothing I have ever seen before. My current computer is also 5 years old so a new pc definitely wouldn’t hurt. With so many entries in this contest perhaps salesforce could give away a more than one Mac Book ;-) ?

Also, due to the very dynamic nature of this site and the fact that it is currently hosted on a developer edition account I fully expect to exceed the site limits if this site gets popular. I have mirrored this site an a Force.com Free Edition account located here but it does not have the log in ability.

And one more thing. Thanks to my awesome wife for putting up with me while I constantly snuck away to work on this site.

Visualforce Pop up

July 29th, 2009 15 comments

One of the most common request you will see when perusing the Visualforce discussion boards is that developers want some sort of pop up box to display or gather more information. Due to the way Visualforce works a traditional pop up box won’t always work as this is a separate window and the state of one controller/extensions can not be accessed from two different windows. Each new window gets a new instance of the controller.

The most commonly recommended way to address this is issue is to use a modal dialog box similar to this or this. These work great but sticking to my anti javascript 100% native Visualforce mantra I assumed there must be an alternative to incorporating external javascript libraries. These libraries can add really cool and polished features but usually at the expense of more complexity and potentially higher maintenance.

I decided to take a stab at creating a 100% native Visualforce pop up and I’m pretty happy with the results. You can check out the demo here:

http://tehnrd-developer-edition.na7.force.com/popup

I’ll be the first to say this method is not perfect. The pop up may not always display in the exact center of the screen as it does not inspect the window size to dynamically center the pop up. Even with this limitation it tends to work pretty good 90% of the time. EDIT: css has been updated below and this is no longer an issue.

This code and markup is pretty simple so I didn’t add a lot of comments but if you have any questions please leave a comment below.

First lets take a look at the page.

<apex:page controller="popup">
    <apex:form >
        <apex:commandButton value="Show Pop up" action="{!showPopup}" rerender="popup"/>
        <apex:pageBlock >
            Lorem ipsum ..... dummy stuff to show the popup is above content
        </apex:pageBlock>
 
        <apex:outputPanel id="popup">
            <apex:outputPanel styleClass="customPopup" layout="block" rendered="{!displayPopUp}">
                Lorem ipsum <br/><br/><br/>
                <apex:commandButton value="Hide Pop up" action="{!closePopup}" rerender="popup"/>
            </apex:outputPanel>
        </apex:outputPanel>
 
    </apex:form>
 
    <style type="text/css">
       .customPopup{
            background-color: white;
            border-style: solid;
            border-width: 2px;
            left: 50%;
            padding:10px;
            position: absolute;
            z-index: 9999;
            /* These are the 3 css properties you will need to tweak so the pop 
            up displays in the center of the screen. First set the width. Then set 
            margin-left to negative half of what the width is. You can also add 
            the height property for a fixed size pop up.*/
            width: 500px;
            margin-left: -250px;
            top:100px;
        }
    </style>
</apex:page>

And the controller, very simple.

public class popup {
 
    public boolean displayPopup {get; set;}
 
    public void closePopup() {
        displayPopup = false;
    }
 
    public void showPopup() {
        displayPopup = true;
    }
}
Categories: Apex, Visualforce

Super Cool Advanced Lookup Component

July 26th, 2009 7 comments

Okay, so maybe it isn’t exactly a super cool advanced lookup, but it is a lookup, and it is cool. Title at least got your attention right? No? Darn.

So what is a super cool advanced lookup you may ask? It is basically text field that as you start to type it becomes a picklist of values depending on the text you are typing. You can have it lookup records on any object that has a Name field. This type of functionality can be done with javascript libraries (examples here) but why do that if you can build something that performs just as well using only Apex and Visualforce? I did play around with the ext.js library and it is definitely more polished but on very large data sets performance was not that good. As I would type it felt like it was freezing up. To me this is much more annoying than a slight delay the VF component makes when performing the SOQL query.

Here is the example page, enjoy: http://tehnrd-developer-edition.na7.force.com/comboBox

First we will take a look at the component named advancedLookup. This component has 4 important attributes:
- object: The object you would like to search, Account, Contact, MyCustomObject__c, etc.
- value: This component returns an Id value and this must be bound to a value in your page’s controller or extension
- maxHeight: As you begin you type a picklist will appear of matching results and you must set the default height.
- width: Depending on the object searched the Name may only be 15 characters wide or it could be 250. Here you set the width so the names are readable.

<apex:component controller="advancedLookUp" >
    <apex:attribute name="object" assignTo="{!objectType}" required="true" type="string" description="The object this component will search."/>
    <apex:attribute name="value" assignTo="{!selectValue}" required="true" type="object" description="A merge feld that references the controller class variable that is associated with this feld. This must be an Id field."/>
    <apex:attribute name="maxHeight" assignTo="{!maxHeight}" required="true" type="Integer" description="Max height of selectList."/>
    <apex:attribute name="width" required="true" type="string" description="Width of the component in pixels or percent."/>
    <apex:attribute name="style" type="string" description="The style used to display the inputText component, used primarily for adding inline CSS styles."/>
    <apex:outputPanel layout="block" style="{!style}">
 
            <!-- This is our input text that we will use in a wildcard search against the names of the defined object. We refresh the results every time this field
            is clicked or a letter is entered (keyup) -->
            <apex:inputText value="{!searchValue}" style="width:{!width}" id="searchValue">
                <apex:actionSupport event="onkeyup" action="{!search}" rerender="resultsPanel"/>
                <apex:actionSupport event="onclick" action="{!search}" rerender="resultsPanel"/>
            </apex:InputText>
 
            <!-- Once we perform the query on the object we will populate this list with the returned values. When a user selects a value we will hide this list
            and auto complete the selected value -->
            <apex:outputPanel id="resultsPanel" layout="block" style="position: absolute;">
                <apex:selectList value="{!value}" size="{!height}" style="width:{!width}" rendered="{!showList}" >
                    <apex:selectOptions value="{!results}"/>
                    <apex:actionSupport event="onchange" action="{!selectvalue}" rerender="resultsPanel,searchValue"/>
                </apex:selectList>
            </apex:outputPanel>
 
    </apex:outputPanel>
 
    <!-- This component has one little piece of javascript. If a user clicks on the screen before selecting a value we want to hide the list of options similar to
    how a normal picklist behaves -->
    <apex:actionFunction name="hideResults" action="{!hideResults}" reRender="resultsPanel"/>
    <script type="text/javascript">
        document.onclick = function(){
            hideResults();
        }
    </script>
</apex:component>

Next the controller for this this custom component:

public class advancedLookUp{
 
    public Object selectValue{get; set;}
    public String objectType {get; set;}
    public String searchValue {get; set;}
    public Integer maxHeight {get; set;}
    public Integer height {get; set;}
    public List<SelectOption> results {get; set;}
    public Boolean showList {get; set;}
    Map<String,String> resultsMap;
 
    //This is our seach method that is called every time a character is entered
    public void search(){
        showList = true;
        results = new List<SelectOption>();
        resultsMap = new Map<String,String>();
 
        //Using dynamic SOQL we pass the object and the search value
        if(searchValue.length() > 0){
            String entry = '%' + searchValue + '%';
            String queryString = 'Select Id, Name from ' + objectType + ' where Name like :entry order by Name limit 1000';
 
            /*Next we add the results to our list of selectOptions. We also add the values to a map so that when a value
            is selected we can auto fill the search box with the selected value */
            for(sObject o : Database.query(queryString)){
                results.add(new SelectOption((String)o.get('Id'),(String)o.get('Name')));
                resultsMap.put((String)o.get('Id'),(String)o.get('Name'));
            }
        }
 
        //Next we inspect the results to set the height and contents of the selectList
        if(searchValue.length() == 0){
            showList = false;
        }else if(results.size() == 0 && searchValue.length() != 0){
            results.add(new SelectOption('','No matches found'));
            height = 2;
        }else if(results.size() == 1){
            height = 2;
        }else if(results.size() > maxHeight){
            height = maxHeight;
        }else{
            height = results.size();
        }
    }
 
    //When a value is selected we will auto complete the searchValue
    public void selectValue(){
        showList = false;
        searchValue = resultsMap.get((string)selectValue);
    }
 
    //simply hides the list of results
    public void hideResults(){
        showList = false;
    }
}

Almost there now. Up next the page and page controller:

<apex:page controller="coolLookUp">
    Try searching with 'e', 'oil', 'az', 'install', etc then click the Show button.
 
    <apex:form >
        <!-- This is only line need for the advanced lookup. The value is bound to an ID variable in this page's controller. When you click the button it 
        refreshes the detail panel and displays the selected opp -->
        <c:advancedLookup object="Opportunity" value="{!oppId}" maxHeight="20" width="250px" style="float: left"/> 
        <apex:commandButton value="Show" rerender="detail" style="float: left" status="status"/>
        <apex:actionStatus startText="elevator music...." id="status"/>      
        <apex:outputPanel id="detail">
            <apex:detail subject="{!oppId}"/>
        </apex:outputPanel>
    </apex:form>
</apex:page>

Doesn’t get much more simple than this:

public class coolLookUp {
    public Id oppId {get; set;}
}

FYI, there is an issue if you try to use this component more than once on a page but I have not yet had the time to investigate.

Categories: Apex, Visualforce

Simple Visualforce Captcha

July 16th, 2009 2 comments

With Force.com sites now in GA it is possible to create public facing web forms and save directly to your salesforce.com database. You can do point of entry validation, auto fill fields based on the user, and all sort of other awesomeness. One problem with public facing forms is they are prone to spam, lots of spam. The best approach is to prevent the spam from even being submitted in the first place. This is usually done with some sort of CAPTCHA validation.

Ron Hess put together a great little article here on how you can use reCAPTCHA. It works great but (there is always a but) it requires setting up a web service callout, using javascript, and isn’t the the most straight forward CAPTCHA to setup. I am all about 100% salesforce.com. Javascript libraries and external services are great but if I can do the same thing with 100% Apex and Visualforce I’m all for that.

With this mindset I set out to create a CAPTCHA utility built 100% on the force.com platform. I think my results where pretty darn successful. It isn’t super fancy but I think it will get the job done……but then again it hasn’t exactly been tested against spam bots. Oh well, it’s still cool.

You can check out a working example here: http://tehnrd-developer-edition.na7.force.com/captcha

And here is the code, first the page:

<apex:page controller="captcha" >
 
    Enter only the <strong>black</strong> characters.
    <apex:outputPanel styleClass="container" layout="block" id="code">
        <apex:outputText value="{!char1}" styleClass="blackChar"/>
        <apex:outputText value="{!char2}" styleClass="redChar"/>
        <apex:outputText value="{!char3}" styleClass="blackChar"/>
        <apex:outputText value="{!char4}" styleClass="redChar"/>
        <apex:outputText value="{!char5}" styleClass="blackChar"/>
        <apex:outputText value="{!char6}" styleClass="redChar"/>
    </apex:outputPanel>
 
    <apex:form >
        <apex:inputText value="{!input}"/>
        <apex:commandButton action="{!validate}" value="Validate" rerender="result"/>
        <apex:commandButton value="Reset" rerender="code"/>
    </apex:form>
 
    <apex:outputPanel id="result">
        {!result}
    </apex:outputPanel>
 
    <style>
        .redChar{
            color: #C30000;
            font-size: 24px;
            padding:5px;
        }
        .blackChar{
            color: black;
            font-weight: bold;
            font-size: 24px;
            padding:5px;
        }
        .container{
            background-color: #E8E8E8;
            border-style: solid;
            border-width:1px;
            width: 150px;
            text-align: center;
        }
    </style>
</apex:page>

And next the controller:

public class captcha {
 
    List<String> characters;
    public String input {get; set;}
    public String result {get; set;}
    String char1;
    String char3;
    String char5;
 
    //In our contructor we will populate a list of strings with numbers and letters
    public captcha(){
        characters = new List<String>{'a','b','c','d','e','f','g','h',
            'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
            'x','y','z','1','2','3','4','5','6','7','8','9','0'
        };
    }
 
    //This methods simply returns a random number between 0 and the size of the character list
    public Integer randomNumber(){
        Integer random = Math.Round(Math.Random() * characters.Size());
        if(random == characters.size()){
            random--;
        }
        return random;
    }
 
    /*Here we have 6 get methods that return 6 random characters to the page.
    For chars 1,3, and 5 (the black characters) we are saving the the values so 
    that we can compare them with the user's input */
    public String getChar1(){
        char1 = characters[randomNumber()];
        return char1;
    }
    public String getChar2(){
        return characters[randomNumber()];
    }
    public String getChar3(){
        char3 = characters[randomNumber()];
        return char3;
    }
    public String getChar4(){
        return characters[randomNumber()];
    }
    public String getChar5(){
        char5 = characters[randomNumber()];
        return char5;
    }
    public String getChar6(){
        return characters[randomNumber()];
    }
 
    /*In the validate method we make sure that the 3 characters entered equal the three black characters: char1, char3, char5*/
    public void validate(){
        if(input.length() == 3 && input.subString(0,1) == char1 && input.subString(1,2) == char3 && input.subString(2,3) == char5){
            result = 'Whoohoo! You got it right.';
        }else{
            result = 'Come on...the letters aren\'t even disfigured.'; 
        }
    }
}

The next logical step would be turning this into a component but this should give you a pretty good start.

Comparing Code

June 23rd, 2009 No comments

Today I discovered a neat little feature in Eclipse that allows you to compare two files and identify the differences. With multiple sandboxes, production, and developer environments I often have multiple versions of a class or Visualforce page in many different places and I lose track of minor changes. Yes, I should be using some type of real version control system but I am the only developer and so far there haven’t been any issues. I also get the vibe this is the way a lot of orgs are developing on Force.com, wild wild west style.

To compare two files in Eclipse simply hold CTRL while selecting the files, right click on one of them, Compare With, and then select Each Other. This will load a screen that allows you to easily identify the differences between the two files. This works for everything including triggers, classes, pages, objects, etc.

For the Eclipse gurus the response may be, “uh, duh”, but a lot of people developing on the Force.com platform may be new to Eclipse (myself included) and this is a great little feature.

Categories: Apex, Visualforce