Showing posts with label Apex. Show all posts
Showing posts with label Apex. Show all posts

Monday, December 28, 2009

S-Control Deprecation

From the Force.com Blog:

S-Controls were labeled as deprecated in the Spring ‘09 release. With the upcoming Spring ‘10 release, we will be taking the next step in S-Control deprecation. Read the S-Control Deprecation article for more detail on what will and what won't change with the next phase of S-Control deprecation.

Friday, November 27, 2009

Dreamforce 2009: How to Write Good Unit Tests in Force.com Code

In addition to presenting the Creating Rich User Experiences session at Dreamforce 2009, I also presented a session on How to Write Good Unit Tests. I was really happy with how the session turned out - after the session, a couple of attendees told me that they were surprised that I was so enthusiastic about a topic that they had considered to be complete drudgery. They said that they were excited to go back home and start applying the tips that I had provided.

If you haven't already, I encourage you to check out the video, read the accompanying How to Write Good Unit Tests article, download the slide deck and play around with the sample source code from the session.


Tuesday, September 22, 2009

Force.com as Google Visualization Data Source

From the Force.com Blog:

Did you know that you can configure Force.com apps to act as a Google Visualization Data Source? This means that you can now publish data from your Force.com org to the internet where it can be easily consumed by various Google Gadgets and Google Visualizations - not just on your website, but on any website that supports embedding the gadgets or visualizations.

Much of your company's data probably should not be published out on the internet, but you can certainly imagine a number of situations where exposing some of your company's data could be very beneficial.

For example, if your company is putting on a user conference, your marketing team might want to expose some of the attendees' demographic data so that the conference attendees can create heat maps of shared geographic locations, shared topics of interest, etc.

Or your sales team might want to expose a list of its most popular products so that your customers can see what other customers are buying - similar to the way that Amazon publishes lists of its bestselling items.

Or your support team might want to expose its call volume data so that customers know when they're most likely to be able to speak with an agent directly.

There are many additional reasons why you might want to publish some of your company's Force.com data to the internet. Once you do, your customers may just innovate and come up with additional uses for your data that you had never even thought about. Learn more about exposing your Force.com data as a Google Visualization Data Source.

Thursday, July 30, 2009

How to Write Good Unit Tests

From the blog:

If you’ve written Apex Code and deployed it to production, then you’ve encountered the 75% code coverage requirement. In order to help you achieve (and hopefully exceed) 75% code coverage, I’ve written an article that introduces some of the most important concepts for crafting good unit tests. It explores the proper structure of unit tests, the code scenarios that your unit tests should cover, and the properties of well-written unit tests.

One property of well-written unit tests is that they are thorough. Good unit tests exercise your code in expected conditions, and in unexpected conditions. One unexpected condition that you may have encountered, is when your code deliberately throws an exception because something out of the ordinary has happened. It’s not necessarily obvious how to write a unit test for this scenario, which is why my article demonstrates this useful pattern:


static testMethod void verifySpecificExceptionIsThrown() {
/* Set up all conditions for testing here. */

try{
/* Call the method being tested here. */
}
catch (SpecificException e){
// If the expected SpecificException is thrown and caught,
// then the test was successful and we can exit.
return;
}

// If the expected SpecificException is not thrown and caught,
// then fail the test.
System.assert(false, 'A SpecificException was expected, but was not thrown.');
}

To learn more, and to see this particular pattern in action, read How to Write Good Unit Tests.


Thursday, May 14, 2009

Are You Having Problems Sharing?

From the blog:

The number one rule in life for author Robert Fulghum is to "Share everything." Your Force.com application is one place where it’s okay to break that rule and not share everything. That’s why Force.com allows developers and administrators to control access to data at many different levels. You can control access at the object-level, the record-level and even at the field-level. In the vast majority of cases, the appropriate Force.com sharing settings can be defined declaratively by simply pointing and clicking. In some cases, developers may need the ability to define even more sophisticated sharing settings, and this is where Apex Managed Sharing comes in.

Apex Managed Sharing allows you to use Apex Code to build sophisticated and dynamic sharing settings that aren’t otherwise possible. For example, a developer can use Apex Managed Sharing to write a trigger that will automatically share a custom object record with a user that has been specified in a lookup field. You can also use Apex Managed Sharing to write custom Visualforce controllers that implement your sharing logic.

After an introduction to sharing, the accompanying article looks at the components of Apex Managed Sharing, and how you can use Apex Managed Sharing in your own applications. The article, Using Apex Managed Sharing to Create Custom Record Sharing Logic, also provides sample code for the trigger described above.

Apex Managed Sharing is a really interesting aspect of Force.com. It enables developers to build some very innovative applications.

Tuesday, December 23, 2008

Use Visualforce and Apex to Populate PDF Forms

Does your company's business process involve filling out PDF forms? If so, check out my recent post about using Visualforce and Apex to help automate the process of populating PDF forms: Use Visualforce and Apex to Populate PDF Forms.

Wednesday, October 08, 2008

Visualforce Tip: How to Determine a salesforce.com Hostname

It isn't entirely obvious how a developer can determine the hostname (server url) portion of the absolute path for a Visualforce page via Apex. Luckily, it is rather easy to do.

You might have already figured out that the PageReference class's getUrl() method will return the relative path for your Visualforce page:
ApexPages.currentPage().getUrl();

Once you have the relative path for the page, then there's just one remaining trick to discover - the Map returned by the PageReference class's getHeaders() method contains a 'Host' key whose associated value is the hostname for your salesforce org:
ApexPages.currentPage().getHeaders().get('Host');

The complete code for constructing the absolute path for a Visualforce page is below:

String hostname = ApexPages.currentPage().getHeaders().get('Host');
String pageUrl = ApexPages.currentPage().getUrl();
String absolutePath = 'https://' + hostname + pageUrl;
system.debug(absolutePath); //example output: 'https://na6.salesforce.com/apex/MyPage'

Friday, August 15, 2008

"Apex Code Is Not a Niche Tool"

"[Apex Code] is not a niche tool for a proprietary platform -- rather, it's a Java-like language with an Eclipse-based tool ecosystem and excellent facilities for unleashing immense gains in developer productivity and enterprise project success."

http://blog.sforce.com/sforce/2008/05/proprietary-mis.html

Wednesday, April 09, 2008

salesforce.com cron

Time-based workflows in salesforce currently execute relative to a time. For example, you can use them to to schedule a task for the case owner to follow up with the customer two days after a
case is closed.

It's not currently possible to schedule time-based workflows to execute at a particular time every day - like a cron job would. For that, we'd need to add some secret sauce to time-based workflows.

The Apex trigger below will populate a custom DateTime field called Midnight_Local_Time__c with, you guessed it, midnight - local time for the running user. In conjunction with a time-based workflow, this trigger would allow you to do things like lock all 'Closed' Case records at midnight
trigger Case_PopulateMidnightLocalTime on Case (after update)
{
List cases = new List();
for(Case c : [SELECT CreatedDate FROM Case WHERE Id IN :Trigger.new AND IsClosed = true AND Midnight_Local_Time__c = null])
{
CaseTriggerHelper.SetMidnightTime(c, c.CreatedDate);

cases.add(c);
}

update cases;
}

public static void SetMidnightTime(Case c, DateTime dt)
{
// SFDC defaults 'Midnight' to the 'Time' for this call to newInstance();
DateTime midnightLocalTime = DateTime.newInstance(dt.year(), dt.month(), dt.day());
midnightLocalTime = midnightLocalTime.addDays(1).addMinutes(-1);
c.Midnight_Local_Time__c = midnightLocalTime;
}
If you use this, you'll want to keep in mind that there are limitations around time-based workflows and triggers though:
  • Time-based workflows aren't guaranteed to execute exactly on time, there could be a significant delay in their execution.

  • Unlimited Edition is limited to 20,000 time triggers per org

  • Enterprise Edition is limited to 10,000 time triggers per org
Linvio's CronKit appears to be a useful solution to this problem as well.