Wednesday, April 14, 2010

Using a non default Calendar in the Google API

All the examples in the Google Calendar API documentation involve using a default calendar. But i was looking at a project where i would have a shared calendar among users and this calendar would not be the default one. The simple code below demonstrates how to do this in Java. There are three parameter you will need to inject into this class (in my case via Spring) -- the username, password, and calendarname. Using these three you have what you need to work with the non default calendar.


   1: public class CalendarUtil {



   2:   private final static Logger logger = Logger.getLogger(CalendarUtil.class.getName());



   3:   private String username;



   4:   private String password;



   5:   String calendarName;



   6:   private URL calendarUrl;



   7:  



   8:   private CalendarService service;



   9:  



  10:   // The base URL for a user's calendar metafeed (needs a username appended).



  11:   private static final String METAFEED_URL_BASE =



  12:           "http://www.google.com/calendar/feeds/";



  13:  



  14:   private static final String CALENDAR_URL_SUFFIX = "/private/full";



  15:  



  16:   public void init() {



  17:     service = new CalendarService("DR-Appt-App-1");



  18:     try {



  19:       service.setUserCredentials(username, password);



  20:     } catch (AuthenticationException e) {



  21:       throw new RuntimeException("Could not authenticate to Google Calendar with username: " + username, e);



  22:     }



  23:     String calendarId = null;



  24:     try {



  25:       calendarId = getCalendarId();



  26:     } catch (IOException e) {



  27:       throw new RuntimeException("Error caught trying to connect to calendar: ", e);



  28:     } catch (ServiceException e) {



  29:       throw new RuntimeException("Error caught trying to connect to calendar: ", e);



  30:     }



  31:     try {



  32:       calendarUrl = new URL(METAFEED_URL_BASE + calendarId + CALENDAR_URL_SUFFIX);



  33:     } catch (MalformedURLException e) {



  34:       throw new RuntimeException("Bad URL: " + calendarUrl.toString(), e);



  35:     }



  36:     if (logger.isDebugEnabled()) {



  37:       logger.debug("Url is " + calendarUrl.toString());



  38:     }



  39:   }



  40:  



  41:  



  42:   //get id of correct calendar



  43:   private String getCalendarId() throws IOException, ServiceException {



  44:     String calendarId = null;



  45:     URL metafeedUrl = new URL(METAFEED_URL_BASE + username);



  46:     if (logger.isDebugEnabled()) {



  47:       logger.debug("Url is " + metafeedUrl.toString());



  48:     }



  49:     CalendarFeed resultFeed = service.getFeed(metafeedUrl, CalendarFeed.class);



  50:     for (int i = 0; i < resultFeed.getEntries().size(); i++) {



  51:       CalendarEntry entry = resultFeed.getEntries().get(i);



  52:       if (calendarName.equalsIgnoreCase(entry.getTitle().getPlainText())) {



  53:         calendarId = new File(entry.getId()).getName();



  54:         break;



  55:       }



  56:     }



  57:     return calendarId;



  58:   }



  59:  


I have left out of the above the getters and setters to make it more concise.
Using the above class, you now can access the non primary calendar simply using the syntax:
calendarUtil.getService().insert(…)
or any other service function.



Monday, February 22, 2010

Not a Maven yet….

Notwithstanding my post about using Gradle as a build tool, when i needed to start a new project i decided to use maven due to its amazing integration with an IDE (in my case Intellij), as well as its unbiquitousness.

So, as i have written previously, it is really nice to use Maven as you get started, since with no writing of any config files you have the build process working for you. You have a clean, compile, jar, etc with no work and no opening of an XML file. But that is all theoretical. As i attempted to get going with my project i encountered two really serious issues that took a while to figure out, as well as one issue that needs better resolution.

I will start with the more minor issue. When we use standard libraries that we need to add to our project, then things are pretty straightforward, in fact even better than not using maven. All you need to do is go to http://mvnrepository.com and find the item you want and then it gives you the lines to add to your pom, and voila, you have added your dependency to your project. Of course, in one case, this was not so simple. I wanted to use log4j, so i said, ok, I will just use the latest version. That turned out to be a mistake since all of sudden the compile was failing with libraries i had never heard of unable to be downloaded and installed. As it turns out, after a bit of googling, i learned that i needed to stay away from this latest version. But that is not even the issue i was referring to above. The issue i ran into was when i needed to use non standard libraries that are not in the mvnrepository site. This became difficult as i did not have an easy time figuring out what repository to use and what to add to my POM. In my case, i wanted to use Spring 3 and as far as i can tell, there is no browser for the Spring 3 release repository and thus no instructions for what my artifact ids would look like. (Hint to SpringSource – mention in the javadocs which jar is needed for a package). I wound up guessing based on one item i found somewhere and since i had downloaded the spring 3 distribution i was able to guess how the others would look and solved that issue. The second set of non standard artifacts were the google calendar ones. Here, i had to manually install them in my repository to get it going. Since it was a lot of jars, it was tedious, thought here is a nice link to make it easier, just be sure to use version 2 and not 1 for those things are now in version 2.

Now on the two major issues that i encountered. The first one was that my project would not compile successfully even though there was very little code in it other than use of the Google Calendar API. Finally after not getting anywhere for a while, i realized the issue must be Maven since it did compile in my IDE. As it turned, it was a documented Jira issue, but as the guys in the comments wrote there, who would have thought that default of maven today would not be java 5 at least?

The second one related to testing. Even though my most recent work has been using TestNG, i thought maybe i would give JUnit a try. When my JUnit tests were not being recognized, i figured out that this is because, once again, the default is junit 1.3. After a bit of searching i found what i need to do to add Junit4 to be the test runner. But, since i found the documentation of JUnit 4 lacking, i had decided to switch back but figured i would leave both dependencies in the POM. Well, that turned out to be a mistake too, as i eventually found here

But with these problems behind us, we trudge forward assuming that all should now be smooth sailing, until we need some other complex library….

Wednesday, January 27, 2010

Asynchronous Groovy

In my previous post, i showed how simple asynchronous code in Spring 3 is. I wanted to see what it takes to write the same code in Groovy. Well, it is quite straightforward, using the GPARS library. The docs there show it to be quite powerful, but to be loyal to our simple example, here is the code:



   1: Asynchronizer.withAsynchronizer(4) {ExecutorService service ->



   2:       (0..9).each { num->



   3:         service.submit({



   4:         Thread.sleep(2000);



   5:         println("Running for ${num} thread ${Thread.currentThread()}")}as Runnable)



   6:       }



   7: }



See how you specify the number of threads in the parameter to the closure withAsynchronizer.
There are lots more examples at the GPARS site.

Wednesday, January 13, 2010

Asynchronous Code with Spring 3 – Simple as an annotation

After reviewing some of the features of Spring 3, i decided to test out the asychronous features via annotation. And below is all the code i needed in order to have a function executed asynchronously in my application:



   1: public class Asyncher {



   2:     @Async



   3:     public void myMethod(int i) {



   4:         try {



   5:             Thread.sleep(2000);



   6:         } catch (InterruptedException e) {



   7:             e.printStackTrace();



   8:         }



   9:         System.out.println("Running for " + i);



  10:     }



  11:  



  12:     public static void main(String[] args) throws InterruptedException {



  13:         ApplicationContext ctx = new ClassPathXmlApplicationContext("appContext.xml");



  14:         Asyncher a = ctx.getBean("asyncher", Asyncher.class);



  15:         for (int i=0; i<10;i++) {



  16:                 a.myMethod(i);



  17:         }      



  18:  



  19:         ThreadPoolTaskExecutor t = ctx.getBean("myExecutor",ThreadPoolTaskExecutor.class);



  20:         while (t.getActiveCount() > 0) {



  21:             System.out.println("Number of tasks left: " + t.getActiveCount());



  22:             Thread.sleep(2000);



  23:         }



  24:         t.shutdown();



  25:     }



  26: }



Hard to believe, but all i needed to do was add the Async annotation on line 2 to my function and it works. of course we need a few lines in our application Context to make this work, but here they are:


   1: <?xml version="1.0" encoding="UTF-8"?>



   2: <beans xmlns="http://www.springframework.org/schema/beans"



   3:        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"



   4:        xmlns:context="http://www.springframework.org/schema/context"



   5:        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">



   6:  



   7:     <task:annotation-driven executor="myExecutor" />



   8:     <task:executor id="myExecutor" pool-size="2"/>



   9:     <bean id="asyncher" class="Asyncher"/>



  10:  



  11: </beans>


This same method can be used to create scheduled jobs as well, by changing or adding on line 7 the scheduler attribute and then adding in a scheduler bean

<task:scheduler id="myScheduler" pool-size="10"/>

You can read about it in the docs here

Monday, December 28, 2009

Creating a Zip file from a Stream

Given an InputStream generated for me, i wanted to zip it up and email it. From the java almanac i saw that i could easily do this if i write the stream to disk first. But this seemed like an unnecesary step for me. All i needed to do was to attach this outputstream to my email code and get it done. So, after a bit of playing, I got it working. Here is the code:




   1: private byte[] createZipFile(InputStream in, String fileName) throws IOException {



   2:         ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream();



   3:         ZipOutputStream zippedFile = new ZipOutputStream(zipOutputStream);



   4:         byte[] buf = new byte[1024];



   5:         zippedFile.putNextEntry(new ZipEntry(myFileName));



   6:         // Transfer bytes from the file to the ZIP file



   7:         int len;



   8:         BufferedInputStream bs = new BufferedInputStream(bds[0].getInputStream());



   9:         while ((len = bs.read(buf)) > 0) {



  10:             zippedFile.write(buf, 0, len);



  11:         }



  12:         zippedFile.closeEntry();



  13:         bs.close();        



  14:         zippedFile.close();



  15:         return zipOutputStream.toByteArray();



  16: } 



By wrapping the ZipOutputStream around a ByteArrayOutputStream, i am able to access the byte array and use that to attach to my email and send out.

Monday, November 30, 2009

Gradle, my new build tool?

Last week, i had the pleasure of attending the JavaEdge conference. The keynote speaker was Ted Neward, and you could read his thoughts about the conference here. I enjoyed his lecture very much whose theme was that new programming languages in the VM is the future and we should all get used to it and get comfortable with it.

One of the sessions that i attended was “Your Next Successful Build”, given by Baruch Sadogursky, who used a slick tool instead of Powerpoint for his presentation, though it was a bit dizzying. I was happy that for the first time, i heard someone say some of my heretical thoughts – that while Maven has a lot of positive, it has many warts, mostly for the reasons of lack of documentation as well as dependency management. As a side note, i  was amazed to see that statistics show that 44% of companies are using Maven, which probably means they are spending countless hours debugging build issues!  It was also refreshing to hear him mention the pros of Ant as well as something he wants to be able to continue to use in his new build environment. But the most exciting part was to hear from Baruch that there is a tool out there that answers the call and it is Gradle. On the one hand, we like the standardization of the file layout of maven, but Gradle adds in better documentation (200 pages!!!), and the ability to use a scripting language, Groovy, which also means you automatically have full access to Ant via Groovy. And of course, he says that dependency management has been fixed as compared to Maven 2. I am hoping to try it out in my next project.

Monday, November 23, 2009

Why did Hibernate do that?!

As i have mentioned in the past, i am not a fan of Hibernate and other ORM tools that generate the SQL for me. This week i have yet another reason for not being willing to consider changing my opinion.

Unbeknownst to me, in our Hibernate application when we were using an “update” to update the one or two columns we change during the regular running of our application, we discovered that actually the update was updating all fields as well as cascading to additional tables joined to this object, which included a CLOB that was getting and update called on it and causing a lot of overhead.

After being warned by our DBA’s to fix ASAP, our next step was to reproduce the problem in our environment so we quickly turned on the “hibernate.show_sql” property to see our SQL. And before we even got to the issue we were looking to solve, we discovered another perplexing Hibernate-ism. We found that when we were doing an initial load or find by id, we were seeing an update happening to the record at the same time as the find/load!

After some fishing around the internet, we understood why this was happening. It was because one of out getters was changing the value from null to something more meaningful, as we see here. When we altered the code to not have this happen, then that update was prevented.

Now onto the problem we were meant to deal with (isn’t always the case that this happens!). After not seeing the results we were hoping for through setting some of the parameters mentioned in various forums (dynamic-update and select-before-update) in an attempt to have our Hibernate “update” not cascade unnecessarily through all the objects and update them all, we settled on a very iBatis like solution. We created the update ourselves so that we know what we are updating, i.e:

String hql = "update myTable set field1 = :field1 where id = :id";
Session session = SessionFactoryUtils.getSession(getSessionFactory(), false);
query = session.createQuery(hql);
query.setString("field1", myObj.getField1());
query.setLong("id",myObj.getId());
query.executeUpdate();

Of course, once you are doing this, you have lost the “advantage” of Hibernate.