DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Software Design and Architecture Topics

article thumbnail
Generate, Rename and Delete Getters/Setters Instantly in Eclipse
despite the arguments and debates about getters and setters in java, the fact is that they’re a reality and you have to work with them. but managing getters and setters is a time-consuming effort. creating a getter/setter for 5 fields in a class can take minutes, renaming one is error-prone and deleting one is just plain inconvenient. there are options like project lombok (that implicitly creates getters/setters without the need to code them) and you could avoid getters/setters altogether by redesigning your classes. but these options aren’t always available, so it’s a good thing eclipse has some handy features for managing getters and setters. combined with the ability to generate constructors based on fields , you can get the boilerplate code out of the way in seconds and get on with the real coding. generate getters and setters to generate getters and setters, do the following: create the fields you want in the class then press alt+shift+s, r . a dialog will pop up allowing you to choose the fields you want to generate getters and setters for. click select all to create getters/setters for all fields. of course you can choose individual fields as required. change insertion point to last member . this tells eclipse that you want to put the methods at the bottom of the class. this is normally the best option for me as i want them out of the way. click ok . eclipse will create the getters and setters for you. here’s an example of what the dialog should look like. note: by default, eclipse doesn’t allow you to create a setter for a final field – the setter just doesn’t appear in the dialog. this can be a nuisance, especially if you’ve enabled autoformatting to make fields final where possible. to bypass this restriction, enable the checkbox allow setters for final fields on the dialog. the setter for the field will now appear in the dialog. once you click ok, eclipse will remove the final keyword from the field and generate the setter. eclipse also remembers this setting. another way to add just a single getter/setter is to position your cursor anywhere in the class (outside any method), start typing either “get” or “set” and press ctrl+space . the options on the autocomplete menu will include any getters/setters of fields that don’t have any defined yet. this is a quick way to create a single getter/setter but isn’t geared for bulk creation. here’s an example of how the autocomplete looks: rename getters and setters the easiest way to rename getters/setters is to use the rename refactoring. place your cursor on the field name (anywhere in the class, not just the declaration) and press alt+shift+r . if you’re using in-place rename (the default), then just rename the field, press enter and eclipse will rename the corresponding getters and setters as well. if you’ve chosen to use the classic refactor dialog (see note below) then make sure you enable rename getter and rename setter on the rename dialog. note: you can choose to do renaming using the traditional rename dialog by going to window > preferences > java and unchecking rename in editor without dialog . i prefer using the rename dialog as it highlights the whole name by default making it easier to overwrite and i have the option of not renaming the getters and setters if i don’t want to. the eclipse default these days is to use the new in-place renaming. although eclipse will rename the getter/setter, it won’t rename the argument passed to the setter method. if you want consistency, you can navigate to that method (eg. using ctrl+o ) and rename the argument yourself. delete getters and setters deleting getters and setters isn’t as straightforward as just deleting the field in the editor. however, you can delete a field and its getters/setters from the outline view. open the outline view ( alt+shift+q, o ), select the field you want to delete and press delete (or right-click, delete). eclipse will ask you whether you want to delete the getters/setters as well. just choose yes to all and they will be removed. you need to have fields visible in the outline view to use this feature (ie. untoggle the hide fields button ). you can select multiple fields simultaneously. and you can delete individual getters/setters (excluding the field) by just selecting the getter/setter and pressing delete . from http://eclipseone.wordpress.com/2010/10/26/generate-rename-and-delete-getterssetters-in-eclipse/
October 27, 2010
by Byron M
· 157,775 Views · 2 Likes
article thumbnail
Know the JVM Series: Shutdown Hooks
Shutdown Hooks are a special construct that allow developers to plug in a piece of code to be executed when the JVM is shutting down.
October 23, 2010
by Yohan Liyanage
· 85,711 Views · 1 Like
article thumbnail
REST API: for Infrastructure, Domain or Application Layer?
It seems that lots of projects/products/services want to expose a REST API these days. But I have found very few that actually follow the REST constraints, and in a lot of the cases it doesn't even make sense for them to follow REST constraints in the first place. One of the main constraints that is commonly violated is the hypertext constraint. Basically, all state changes have to be done by following links, starting from a bookmarked URL. But almost noone does that. However, should they? This article will outline various layers that REST API's can be implemented in, and when it makes sense, and when not. To begin with, in a typical enterprise app there are three options for layers that you might want to expose using a REST API. These are the infrastructure layer, the domain layer, and the application layer. Infrastructure layer If we start with the infrastructure layer, we are typically talking about a database vendor that wants to allow developers to access it using "REST". The API would allow you to create/remove databases, and then insert/update/delete data. Typically it's pretty normal stuff, and the API doesn't change all that much between versions. Accessing this over HTTP maybe makes sense, but is it RESTful? I'll give you an example. I installed CouchDB, and given the hypermedia constraint I should then be able to go to "http://localhost:5984/", and it will tell me what I can do next (like create a database). But when I do a GET on that URL I get this: {"couchdb":"Welcome","version":"1.0.1"} So now what? The hypermedia doesn't tell me what I can do, so therefore as a REST client I will assume there's nothing I can do. This very simple test shows that the HTTP API for CouchDB isn't really RESTful at all. The question is: should it be? That is obviously up to the developers to decide. But if I were the architect I would maybe say, no, it shouldn't be RESTful. Why? Because I want to allow URL templates to be used, so that the client, given the server URL and a document id, is allowed to construct a URL on its own and GET the document. If this was truly RESTful the client would have to do a query in a form first, with the id, in order to get the URL of the document to be retrieved. That might be inefficient for a database, so I might opt not to do this. Which is, in effect, what they already have done. The only problem is that they call it RESTful, when it isn't, so it gives me as a developer the wrong impression of what I can expect from it. This line of reasoning could be done for pretty much most infrastructure layer API's. They're not RESTful, though many say they are, and most likely they shouldn't try to be! IT'S OK! Just say "Accessible over HTTP, see docs for URL templates and whatnot", and be done with it. Domain layer The next potential layer to be exposed over REST is the domain layer. This typically means that you take your domain entities and expose their data straight on the web, through CRUD operations. Very straightforward. There are tons of articles and blogs that show how to do this. But is it RESTful? Or is it even a good idea in the first place? The first test, again, would be to see if the app follows the hypermedia constraint. In this option it is technically possible to allow queries that will list the various URL's to entities in your domain, which you then can update/delete. So on the surface it might seem like you are following the hypermedia constraint. The problem usually comes with the fact that you are exposing domain state rather than application state. Let me explain through a simple example. Let's say you are building an issue tracker. You can access individual issues through links like: /issue/123 which on GET gives you documents such as: {"status":"OPEN","description":"Some issue"} Awesome. Now a client can change the status to "CLOSED" and PUT that. Tada! Case closed. Or is it? What if a client then decides to reopen it, by simply posting a new status of "OPEN" to it. Ok, that worked. But should it? Maybe your domain model really would have wanted it to only go to "REOPENED" from the "CLOSED" state. But how do you express that? How is the client to know that this is the only valid transition? And what happens when we have many versions of clients, each of which has a slightly different set of rules for what you are allowed to do when? Basically, chaos is ensured. And this is the problem with exposing your domain model using a REST API. The client has to own the application logic, and there's no way the server can be sure that it has the "right" logic. And the client, even if it *wants* to play nice (if code ever wants anything is debatable), will have a hard time knowing whether it is playing by the rules or not. It might even get a bit neurotic, trying to do the right thing, whatever that means. In summary, exposing your domain model does not help the client know what the valid state transitions are, and makes it very hard to do other things like role-based security authorization (maybe only an admin is allowed to REOPEN a CLOSED case?). I would therefore recommend that noone exposes their domain models using a REST API. Application layer Finally we come to the application layer. The application layer is designed to implement usecases of the domain model, and has all the context and logic needed to ensure that only valid state transitions are made. In short, it seems like it is especially appropriate to being exposed through a REST API, as it can at all points tell the client what it can do (either based on state or authorization rules or any other type of rules it might have). If we go back to the issue tracker, what would this mean in practice? It could mean that when you do a GET on /issue/123 you get something like this back: {"data":{"status":"OPEN","description":"Some issue"},"links":[{"close":"/issue/123/close.json"}]} This now instead of referring to viewing the domain state of an issue refers to the usecase of viewing an issue with the intent of working on it. There might be other URL's and other queries that only return the data, or maybe a table of the data, or somesuch. But this one, specifically, refers to the usecase of working with the issue. So, as a REST client I can now inspect the data, and then look at what links are available. If the client has a UI it can enable a button that says "Close issue" based on the available link, since it detected a link relation "close" that it understands. The client can then do GET on that link, find out whether the server expects any form to be filled in, and then submit it using POST, thereby letting the server application layer logic transition the issue to the "CLOSED" state. We are no longer relying on the client to contain the logic of knowing when to allow what, and the client also does not have to know how to construct the URL. As long as it can parse the hypertext (and we might use a custom JSON mediatype to indicate what "data" and "links" mean) and do something with it, we're fine. If we in the future change the domain model to also allow the "resolve" link relation for "OPEN" issues, old clients can ignore it, and new clients can enable new actions in the UI that uses it. In summary, the application layer is a very good candidate to be exposed through a REST API. It encapsulates the application rules for when the various state transitions are allowed, and can make use of user authorization to further enable/disable actions. This takes away a lot of responsibilities from the client, which now also can be "dynamic" in the sense that it can easily react to what state changes are available when by simply checking link availability in the hypermedia returned from the server. The main issue with exposing the application layer through a REST API is that there are pretty much no available frameworks that help you do all this in an easy way. But this is not REST's "fault", obviously, but rather that the "REST" community hasn't yet matured to understand what it should and what it should not do. In the Streamflow project we rolled our own simple framework for doing the above, and I'm very happy with that, but unfortunately most other frameworks seems to be in the "expose your domain model" camp, which means that a lot of this link management is non-trivial to do. This is a fixable situation though. I hope that this post has somewhat clarified what the issues are with exposing infrastructure and domain models through REST API's, and why it's not really a good idea in the first place, and why exposing the application layer really is the logical and simpler option. From http://www.jroller.com/rickard/entry/rest_api_for_infrastructure_domain
October 18, 2010
by Rickard Oberg
· 21,540 Views
article thumbnail
Reduce Boilerplate Code for DAO's -- Hades Introduction
Most web applications will have DAO's for accessing the database layer. A DAO provides an interface for some type of database or persistence mechanism, providing CRUD and finders operations without exposing any database details. So, in your application you will have different DAO's for different entities. Most of the time, code that you have written in one DAO will get duplicated in other DAO's because much of the functionality in DAO's is same (like CRUD and finder methods). One of way of avoiding this problem is to have generic DAO and have your domain classes inherit this generic DAO implementation. You can also add finders using Spring AOP; this approach is explained Per Mellqvist in this article. There is a problem with the approach: this boiler plate code becomes part of your application source code and you will have to maintain it. The more code you write, there are more chances of new bugs getting introduced in your application. So, to avoid writing this code in an application, we can use an open source framework called Hades. Hades is a utility library to work with Data Access Objects implemented with Spring and JPA. The main goal is to ease the development and operation of a data access layer in applications. In this article, I will show you how easy it is write DAO's using Hades without writing any boiler plate code. In order to introduce you to Hades, I will show you how we can manage an entity like Book. Before we write any code we need to add the following dependencies to pom.xml. org.synyx.hades org.synyx.hades 2.0.0.RC3 org.hibernate hibernate-entitymanager 3.5.5-Final So, lets start by creating a Book Entity import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(unique = true) private String title; private String author; private String isbn; private double price; // setters and getters } This is a very simple JPA entity without any relationships. Now that we have modeled our entity we need to add a DAO interface for handling persistence operations. You need to create a BookDao interface which will extend GenericDao interface provided by Hades. GenericDao is an interface for generic CRUD operations on a DAO for a specific type. So, we passed the type parameters Book for entity and Long for id. import org.synyx.hades.dao.GenericDao; public interface BookDao extends GenericDao { } GenericDao has an default implementation called GenericJpaDao which provides implementation of all its operations. Now that we have created a BookDao interface, we will configure it in the Spring application context xml. Hades provides a factory bean which will provide the DAO instance for the given interface (in our case BookDao). In the xml shown above I have used a new feature introduced in Spring 3 Embedded Databases to give me the instance of HSQL database datasource. You can refer to my earlier post on Embedded databases in case you are not aware of it. I have used Hibernate as my JPA provider so you need to configure it in persistence.xml as shown below org.hibernate.ejb.HibernatePersistence Next we will write a JUnit test for testing this code. @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @Transactional public class BookDaoTest { @Autowired private BookDao bookDao; private Book book; @Before public void setUp() throws Exception { book = new Book(); book.setAuthor("shekhar"); book.setTitle("Effective Java"); book.setPrice(500); book.setIsbn("1234567890123"); } @Test public void shouldCreateABook() throws Exception { Book persistedBook = bookDao.save(book); assertBook(persistedBook); } @Test public void shouldReadAPersistedBook() throws Exception { Book persistedBook = bookDao.save(book); Book bookReadByPrimaryKey = bookDao.readByPrimaryKey(persistedBook.getId()); assertBook(bookReadByPrimaryKey); } @Test public void shouldDeleteBook() throws Exception { Book persistedBook = bookDao.save(book); bookDao.delete(persistedBook); Book bookReadByPrimaryKey = bookDao.readByPrimaryKey(persistedBook.getId()); assertNull(bookReadByPrimaryKey); } private void assertBook(Book persistedBook) { assertThat(persistedBook, is(notNullValue())); assertThat(persistedBook.getId(), is(not(equalTo(null)))); assertThat(persistedBook.getAuthor(), equalTo(book.getAuthor())); } } Auto Configuration Using Spring Namespaces The way that we have configured the DAO can become quite cumbersome if the number of DAO's increases. To overcome this we can make use of namespaces to configure daos. This configuration will trigger the auto detection mechanism of DAOs that extend GenericDAO or Extended-GenericDAO. It will create DAO instances for all the DAO interfaces found in this package. You can use or for including or excluding interfaces from getting their beans created. Adding Finders and Query Methods So far we have used the inbuilt operations provided by GenericDao but most of the time we need to add our own finders methods like findByAuthorAndTitle, findWithPriceLessThan . Hades makes it very easy for you to add such methods in your domain dao interface like BookDao. Hades provides 3 strategies for creating JPA query at runtime. These are :- CREATE : This will create a JPA query from method name. This strategy ties you with the method name so you have to think twice before changing the method name. public interface BookDao extends GenericDao { public Book findByAuthorAndTitle(String author, String title); } // test code @Test public void shouldFindByAuthorAndTitle() throws Exception { Book persistedBook = bookDao.save(book); Book bookByAuthorAndTitle = bookDao.findByAuthorAndTitle("shekhar", "Effective Java"); assertBook(bookByAuthorAndTitle); } USE DECLARED QUERY : This lets you define query using JPA @NamedQuery or Hades @Query annotation. If no query is found exception will be thrown. @Query("FROM Book b WHERE b.author = ?1") public Book findBookByAuthorName(String author); // test code public void shouldFindBookByAuthorName() { Book persistedBook = bookDao.save(book); Book bookByAuthor = bookDao.findBookByAuthorName("shekhar"); assertBook(bookByAuthor); } CREATE IF NOT FOUND : It is the combination of both the strategies mentioned above. It will first lookup for the declared query and if it is not found will lookup for method name. This is by default option and you can change it by changing query-lookup-strategy attribute in hades:dao-config element. Hades queries also has the support for pagination and sorting. You can pass the instance of Pageable and Sort to the finder methods create above. public Page findByAuthor(String author, Pageable pageable); public List findByAuthor(String author, Sort sort); Hades is not limited to just limited to CRUD and adding custom finder methods. There are some other features like auditing ,Specifications,etc that I will discuss in second part of this article.
October 15, 2010
by Shekhar Gulati
· 21,313 Views
article thumbnail
Mockito - Pros, Cons, and Best Practices
It's been almost 4 years since I wrote a blog post called "EasyMock - Pros, Cons, and Best Practices, and a lot has happened since. You don't hear about EasyMock much any more, and Mockito seems to have replaced it in mindshare. And for good reason: it is better. A Good Humane Interface for Stubbing Just like EasyMock, Mockito allows you to chain method calls together to produce less imperative looking code. Here's how you can make a Stub for the canonical Warehouse object: Warehouse mock = Mockito.mock(Warehouse.class); Mockito.when(mock.hasInventory(TALISKER, 50)). thenReturn(true); I know, I like a crazy formatting. Regardless, giving your System Under Test (SUT) indirect input couldn't be easier. There is no big advantage over EasyMock for stubbing behavior and passing a stub off to the SUT. Giving indirect input with mocks and then using standard JUnit asserts afterwards is simple with both tools, and both support the standard Hamcrest matchers. Class (not just Interface) Mocks Mockito allows you to mock out classes as well as interfaces. I know the EasyMock ClassExtensions allowed you to do this as well, but it is a little nicer to have it all in one package with Mockito. Supports Test Spies, not just Mocks There is a difference between spies and mocks. Stubs allow you to give indirect input to a test (the values are read but never written), Spies allow you to gather indirect output from a test (the mock is written to and verified, but does not give the test input), and Mocks are both (your object gives indirect input to your test through Stubbing and gathers indirect output through spying). The difference is illustrated between two code examples. In EasyMock, you only have mocks. You must set all input and output expectations before running the test, then verify afterwards. // arrange Warehouse mock = EasyMock.createMock(Warehouse.class); EasyMock.expect( mock.hasInventory(TALISKER, 50)). andReturn(true).once(); EasyMock.expect( mock.remove(TALISKER, 50)). andReturn(true).once(); EasyMock.replay(mock); //act Order order = new Order(TALISKER, 50); order.fill(warehouse); // assert EasyMock.verify(mock); That's a lot of code, and not all of it is needed. The arrange section is setting up a stub (the warehouse has inventory) and setting up a mock expectation (the remove method will be called later). The assertion in all this is actually the little verify() method at the end. The main point of this test is that remove() was called, but that information is buried in a nest of expectations. Mockito improves on this by throwing out both the record/playback mode and a generic verify() method. It is shorter and clearer this way: // arrange Warehouse mock = Mockito.mock(Warehouse.class); Mockito.when(mock.hasInventory(TALISKER, 50)). thenReturn(true); //act Order order = new Order(TALISKER, 50); order.fill(warehouse); // assert Mockito.verify(warehouse).remove(TALISKER, 50); The verify step with Mockito is spying on the results of the test, not recording and verifying. Less code and a clearer picture of what really is expected. Update: There is a separate Spy API you can use in Mockito as well: http://mockito.googlecode.com/svn/branches/1.8.3/javadoc/org/mockito/Mockito.html#13 Better Void Method Handling Mockito handles void methods better than EasyMock. The fluent API works fine with a void method, but in EasyMock there were some special methods you had to write. First, the Mockito code is fairly simple to read: // arrange Warehouse mock = Mockito.mock(Warehouse.class); //act Order order = new Order(TALISKER, 50); order.fill(warehouse); // assert Mockito.verify(warehouse).remove(TALISKER, 50); Here is the same in EasyMock. Not as good: // arrange Warehouse mock = EasyMock.createMock(Warehouse.class); mock.remove(TALISKER, 50); EasyMock.expectLastMethodCall().once(); EasyMock.replay(mock); //act Order order = new Order(TALISKER, 50); order.fill(warehouse); // assert EasyMock.verify(mock); Mock Object Organization Patterns Both Mockito and EasyMock suffer from difficult maintenance. What I said in my original EasyMock post holds true for Mockito: The method chaining style interface is easy to write, but I find it difficult to read. When a test other than the one I'm working on fails, it's often very difficult to determine what exactly is going on. I end up having to examine the production code and the test expectation code to diagnose the issue. Hand-rolled mock objects are much easier to diagnose when something breaks... This problem is especially nasty after refactoring expectation code to reduce duplication. For the life of me, I cannot follow expectation code that has been refactored into shared methods. Now, four years later, I have a solution that works well for me. With a little care you can make your mocks reusable, maintainable, and readable. This approach was battle tested over many months in an Enterprise Environment(tm). Create a private static method the first time you need a mock. Any important data needs to be passed in as a parameter. Using constants or "magic" fields hides important information and obfuscates tests. For example: User user = createMockUser("userID", "name"); ... assertEquals("userID", result.id()); assertEquals("name", result.name(); Everything important is visible and in the test, nothing important is hidden. You need to completely hide the replay state behind this factory method if you're still on EasyMock. The Mock framework in use is an implementation detail and try not to let it leak. Next, as your dependencies grow, be sure to always pass them in as factory method parameters. If you need a User and a Role object, then don't create one method that creates both mocks. One method instantiates one object, otherwise it is a parameter and compose your mock objects in the test method: User user = createMockUser( "userID", "name", createMockRole("role1"), createMockRole("role2") ); When each object type has a factory method, then it makes it much easier to compose the different types of objects together. Reuse. But you can only reuse the methods when they are simple and with few dependencies, otherwise they become too specific and difficult to understand. The first time you need to reuse one of these methods, then move the method to a utility class called "*Mocker", like UserMocker or RoleMocker. Follow a naming convention so that they are always easy to find. If you remembered to make the private factory methods static then moving them should be very simple. Your client code ends up looking like this, but you can use static imports to fix that: User user = UserMocker.createMockUser( "userID", "name", RoleMocker.createMockRole("role1"), RoleMocker.createMockRole("role2") ); User overloaded methods liberally. Don't create one giant method with every possible parameter in the parameter list. There are good reasons to avoid overloading in production, but this is test. Use overloading so that the test methods only display data relevant to that test and nothing more. Using Varargs can also help keep a clean test. Lastly, don't use constants. Constants hide the important information out of sight, at the top of the file where you can't see it or in a Mocker class. It's OK to use constants within the test case, but don't define constants in the Mockers, it just hides relevant information and makes the test harder to read later. Avoid Abstract Test Cases Managing mock objects within abstract test cases has been very difficult for me, especially when managing replay and record states. I've given up mixing mock objects and abstract TestCase objects. When something breaks it simply takes too long to diagnose. An alternative is to create custom assertion methods that can be reused. Beyond that, I've given up on Abstract TestCase objects anyway, on the grounds of preferring composition of inheritance. Don't Replace Asserts with Verify My original comments about EasyMock are still relevant for Mockito: The easiest methods to understand and test are methods that perform some sort of work. You run the method and then use asserts to make sure everything worked. In contrast, mock objects make it easy to test delegation, which is when some object other than the SUT is doing work. Delegation means the method's purpose is to produce a side-effect, not actually perform work. Side-effect code is sometimes needed, but often more difficult to understand and debug. In fact, some languages don't even allow it! If you're test code contains assert methods then you have a good test. If you're code doesn't contain asserts, and instead contains a long list of verify() calls, then you're relying on side effects. This is a unit-test bad smell, especially if there are several objects than need to be verified. Verifying several objects at the end of a unit test is like saying, "My test method needs to do several things: x, y, and z." The charter and responsibility of the method is no longer clear. This is a candidate for refactoring. No More All or Nothing Testing Mockito's verify() methods are much more flexible than EasyMock's. You can verify that only one or two methods on the mock were called, while EasyMock had just one coarse verify() method. With EasyMock I ended up littering the code with meaningless expectations, but not so in Mockito. This alone is reason enough to switch. Failure: Expected X received X For the most part, Mockito error messages are better than EasyMock's. However, you still sometimes see a failure that reads "Failure. Got X Expected X." Basically, this means that your toString() methods produce the same results but equals() does not. Every user who starts out gets confused by this message at some point. Be Warned. Don't Stop Handrolling Mocks Don't throw out hand-rolled mock objects. They have their place. Subclass and Override is a very useful technique for creating a testing seam, use it. Learn to Write an ArgumentMatcher Learn to write an ArgumentMatcher. There is a learning curve but it's over quickly. This post is long enough, so I won't give an example. That's it. See you again in 4 years when the next framework comes out! From http://hamletdarcy.blogspot.com/2010/09/mockito-pros-cons-and-best-practices.html
October 14, 2010
by Hamlet D'Arcy
· 57,316 Views
article thumbnail
Practical PHP Patterns: Plugin
The Separated Interface pattern can often be used to provide hook points to client code, in the form of interfaces to implement or classes to extend with client code. The right implementation to use in a part of the system can then be chosen via configuration: the Factory or Dependency Injection container with the largest scope would process the configuration and execute conditionals only one time, and inject the right Plugin as a collaborator of a standard object. This pattern is a evolution of the Separated Interface one, where the implementor package is not even under your maintenance, but it is provided by some external developer that links his code to your work. Implementation In PHP the concept of compile time does not exist, apart from the just-in-time cached compilation of the scripts to operation codes, a phrase which you can peacefully ignore if you are not into caching. By the way, even if some checks are performed while loading and parsing the PHP code, PHP is by design a dynamic language where you can write nearly everything and it will not explode until executed. This design leaves open many possibilities for inserting plugins, but due to the lack of compile there is often a lack of a clean separation between code and configuration. For example, database credentials are embedded in PHP code more often than in other languages. Think now of a framework or a library: you cannot change the code but you must adapt or create a configuration to make it work. To implement a Plugin pattern, your application should strive towards the flexibility of a library: think of your production code as external and untouchable, and try to deploy a particular configuration to make it work and to modify a functionality. For example, extract it in a temporary working copy with svn checkout or git clone and hook in the necessary extensions. When you succeed, and your svn diff or git diff is clean, you'll have implemented a Plugin system. Modification of vendor code (and you are the vendor here) is out of the question. Future changes Kent Beck says in Implementation Patterns that providing hooks via implementation and inheritance is one of the most effective ways to tie a framework down from future evolution. For example, once you have published an interface, you cannot add methods to it without breaking all the implementors. You can publish versioned interfaces, but this adds complexity to your application. With a published abstract class instead, you can include a default implementation for new methods, but you can't remove methods or refactor protected members without breaking Plugin implementators. This is the specular situation of providing an interface. Zend Framework includes both an interface and an abstract class for most of its components, but it does not get right the management of extension points (at least in the 1.x branch). When including the possibility of Plugins in your application, default as much as possible to private visibility and hide the internals of your Plugin hook point. What is left to protected is a seam that screams "extend me", and the interfaces not marked as internal will be implemented by someone else. There is no built-in language mechanism to protect interfaces,m so you'll have to rely on some kind of convention (like a particular prefix or namespace), but for private methods left to protected scope we can only blame ourselves. Configuration The configuration of your Plugin system can be managed with solution of different levels of complexity, each more powerful than the previous ones. Of course, you shouldn't provide a needlessly complex system when all you need is a class name. The first solution is indeed to insert class names into configuration files. This is a totally declarative approach, which uses simple INI files. This is commonly done in Zend Framework, for example with bootstrap resources, and in some cases can even manage dependencies of the Plugins. Bootstrap resources can request other object of the same kind, but cannot pull in arbitrary collaborators (unless they create them by themselves... ugly if you know what DI is). A second, widely applicable solution is to request Factory objects. this solution still involves writing PHP code, but it is one step towards textual configuration. However, a Factory object can fetch and inject all the dependencies into a Plugin without cluttering it with this kind glue code (only a constructor or some setters). The problem with Factories is that they tend to contain all the same boilerplate code. A third solution can be used to provide quick construction of objects: Dependency Injection containers, which have recently been introduced even in PHP. A DI container is configured textually, via an XML or INI file containing parameters like the collaborators each object requires, its lifetime, and so on. DI containers are probably the future of flexible PHP applications, but beware of growing too dependent on them: they are a library like every other open source component, and should be isolated from your code as much as possible like you would do with your models and Doctrine 2, or your services and Zend Framework. Example The code sample shows hot to predispose a class for receiving an injected simple Factory that manages user-defined plugins. // plugin_view.php formatDate(time()), ".\n"; factory = $factory; } public function render($script) { include $script; } /** * Forwards the call to the View Helper invoked. */ public function __call($name, $args) { $callback = $this->factory->getHelper($name); return call_user_func_array($callback, $args); } } /** * Extension code. */ class UserDefinedFactory implements ViewHelperFactory { private $helpers; /** * In this example, we only define a simple Plugin for * formatting dates using PHP's internal function. */ public function __construct() { $this->helpers = array( 'formatDate' => function($time) { return date('Y-m-d', $time); } ); } public function getHelper($name) { return $this->helpers[$name]; } } // client code $view = new View(new UserDefinedFactory); $view->render('plugin_view.php');
October 11, 2010
by Giorgio Sironi
· 5,280 Views
article thumbnail
Java Barcode API
Originally Barcodes were 1D representation of data using width and spacing of bars. Common bar code types are UPC barcodes which are seen on product packages. There are 2D barcodes as well (they are still called Barcodes even though they don’t use bars). A common example of 2D bar code is QR code (shown on right) which is commonly used by mobile phone apps. You can read history and more info about Barcodes on Wikipedia. There is an open source Java library called ‘zxing’ (Zebra Crossing) which can read and write many differently types of bar codes formats. I tested zxing and it was able to read a barcode embedded in the middle of a 100 dpi grayscale busy text document! This article demonstrates how to use zxing to read and write bar codes from a Java program. Getting the library It would be nice if the jars where hosted in a maven repo somewhere, but there is no plan to do that (see Issue 88). Since I could not find the binaries available for download, I decided to download the source code and build the binaries, which was actually quite easy. The source code of the library is available on Google Code. At the time of writing, 1.6 is the latest version of zxing. 1. Download the release file ZXing-1.6.zip (which contains of mostly source files) from here. 2. Unzip the file in a local directory 3. You will need to build 2 jar files from the downloaded source: core.jar, javase.jar Building core.jar cd zxing-1.6/core mvn install cd zxing-1.6/core mvn install This will install the jar in your local maven repo. Though not required, you can also deploy it to your company’s private repo by using mvn:deploy or by manually uploading it to your maven repository. There is an ant script to build the jar as well. Building javase.jar Repeat the same procedure to get javase.jar cd zxing-1.6/javase mvn install cd zxing-1.6/javase mvn install Including the libraries in your project If you are using ant, add the core.jar and javase.jar to your project’s classpath. If you are using maven, add the following to your pom.xml. com.google.zxing core 1.6-SNAPSHOT com.google.zxing javase 1.6-SNAPSHOT com.google.zxing core 1.6-SNAPSHOT com.google.zxing javase 1.6-SNAPSHOT Once you have the jars included in your project’s classpath, you are now ready to read and write barcodes from java! Reading a Bar Code from Java You can read the bar code by first loading the image as an input stream and then calling this utility method. InputStream barCodeInputStream = new FileInputStream("file.jpg"); BufferedImage barCodeBufferedImage = ImageIO.read(barCodeInputStream); LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Reader reader = new MultiFormatReader(); Result result = reader.decode(bitmap); System.out.println("Barcode text is " + result.getText()); InputStream barCodeInputStream = new FileInputStream("file.jpg"); BufferedImage barCodeBufferedImage = ImageIO.read(barCodeInputStream); LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Reader reader = new MultiFormatReader(); Result result = reader.decode(bitmap); System.out.println("Barcode text is " + result.getText()); Writing a Bar Code from Java You can encode a small text string as follows: String text = "98376373783"; // this is the text that we want to encode int width = 400; int height = 300; // change the height and width as per your requirement // (ImageIO.getWriterFormatNames() returns a list of supported formats) String imageFormat = "png"; // could be "gif", "tiff", "jpeg" BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, width, height); MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.png"))); String text = "98376373783"; // this is the text that we want to encode int width = 400; int height = 300; // change the height and width as per your requirement // (ImageIO.getWriterFormatNames() returns a list of supported formats) String imageFormat = "png"; // could be "gif", "tiff", "jpeg" BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, width, height); MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.png"))); In the above example, the bar code for “97802017507991″ is written to the file “qrcode_97802017507991.png” (click to see the output). JavaDocs and Documentation The Javadocs are part of the downloaded zip file. You can find a list of supported bar code formats in the Javadocs. Open the following file to see the javadocs. zxing-1.6/docs/javadoc/index.html zxing-1.6/docs/javadoc/index.html From http://www.vineetmanohar.com/2010/09/java-barcode-api/
September 27, 2010
by Vineet Manohar
· 112,577 Views · 2 Likes
article thumbnail
Commons Lang 3 -- Improved and Powerful StringEscapeUtils
In the first and second parts of this series I talked about some of the new features like enum and concurrency support that have been added in commons-lang 3. In this article, I am going to talk about a new package 'org.apache.commons.lang3.text.translate' which has been added in commons-lang 3. This package is added to fix problems in the design and implementation of the StringEscapeUtils class which exists in versions prior to 3.0. To make it clearer, let's first talk about the purpose of StringEscapeUtils class and the problems it had prior to version 3. Purpose of StringEscapeUtils StringEscapeUtils is a utility class which escapes and unescapes String for Java, JavaScript, HTML, XML, and SQL. For example, @Test public void test_StringEscapeUtils() { assertEquals("\\\\\\n\\t\\r", StringEscapeUtils.escapeJava("\\\n\t\r")); // escapes the Java String assertEquals("\\\n\t\r",StringEscapeUtils.unescapeJava("\\\\\\n\\t\\r")); //unescapes the Java String assertEquals("I didn\\'t say \\\"you to run!\\\"",StringEscapeUtils.escapeJavaScript("I didn't say \"you to run!\""));//escapes the Javascript assertEquals("<xml>", StringEscapeUtils.escapeXml(""));//escapes the xml } Problems with StringEscapeUtils There were a lot of problems in the StringEscapeUtils implementation prior to version3. Some of these were: The implementation was not extensible. Let's take an example of escapeJava, suppose we want to add support in the escapeJava method that it should start escaping single quotes. To add such support we would have to change the existing class code and another if condition which if satisfied will escape single quotes. So, the API was breaking the open-closed principle i.e. a class should be open for extension and closed for modification. It was not symmetric i.e. original should be equal to unescape(escape(original)) but it was not the case. StringEscapeUtils.escapeHtml() escapes multibyte characters like Chinese, Japanese etc. Issue 339 @Test public void testEscapeHiragana() { // Some random Japanese unicode characters String original = "\u304B\u304C\u3068"; String escaped = StringEscapeUtils.escapeHtml(original); assertEquals(original, escaped); } StringEscapeUtils.escapeHtml incorrectly converts unicode characters above U+00FFFF into 2 characters. Issue 480 @Test public void testEscapeHtmlHighUnicode() throws java.io.UnsupportedEncodingException { byte[] data = new byte[] { (byte) 0xF0, (byte) 0x9D, (byte) 0x8D,(byte) 0xA2 }; String original = new String(data, "UTF8"); String escaped = StringEscapeUtils.escapeHtml(original); assertEquals(original, escaped); } StringEscaper.escapeXml() escapes characters > 0x7f . Issue 66 @Test public void shouldNotEscapeValuesGreaterThan0x7f() { assertEquals("XML should not escape >0x7f values", "\u00A1",StringEscapeUtils.escapeXml("\u00A1")); } Solution -- Rewritten StringEscapeUtils In version 3.0, StringEscapeUtils is completely rewritten to fix all the bugs associated with this class and to provide a way for the user to customize the behavior of its methods. They have moved all the logic present in the StringEscapeUtils to the classes in the package 'org.apache.commons.lang3.text.translate'. Let's take an example of escapeJava function in StringEscapeUtils, escapeJava function does not contain any business logic, it just calls the translate method on CharSequenceTranslator reference. What they did can be best understood by looking at the code below public static final CharSequenceTranslator ESCAPE_JAVA = new AggregateTranslator(new LookupTranslator( new String[][] { {"\"", "\\\""}, {"\\", "\\\\"}, }),new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_ESCAPE()),UnicodeEscaper.outsideOf(32, 0x7f)); and in the escapeJava method public static final String escapeJava(String input) { return ESCAPE_JAVA.translate(input); } A constant of type CharSequenceTranslator was assigned an AggregateTranslator object. AggregateTranslator can take an array of translators, and it iterates over each of them. The LookupTranslator replaces the string at zeroth index with the string at the first index. UnicodeEscaper translates values outside the given range to unicode values. As you can see, you can very easily write your own escape methods. For example, if you want to add the support of escaping &, you can do it like this public static final CharSequenceTranslator ESCAPE_JAVA = new LookupTranslator( new String[][] { {"\"", "\\\""}, {"\\", "\\\\"}, }).with(new LookupTranslator( new String[][]{ {"&", "&"}, {"<", "<"} )).with( new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_ESCAPE()) ).with( UnicodeEscaper.outsideOf(32, 0x7f) ); StringEscapeUtils.escapeSql has been removed from the API as it was misleading developers to not use PreparedStatement.This method was not of much use as it was only escaping single quotes.
September 17, 2010
by Shekhar Gulati
· 71,350 Views · 2 Likes
article thumbnail
Jetty-maven-plugin: Running a Webapp with a DataSource and Security
this post describes how to configure the jetty-maven-plugin and the jetty servlet container to run a web application that uses a data source and requires users to log in, which are the basic requirements of most web applications. i use jetty in development because it’s fast and easy to work with. why jetty? well, because it’s much faster then the websphere as i normally use and it really well supports fast (or shall i say agile? ) development thanks to its fast turnaround. and because it’s simply cool to type bash$ svn checkout http://example.com/repo/trunk/mywebapp bash$ cd mywebapp bash$ mvn jetty:run bash$ firefox http://localhost:8080/mywebapp and to be able to immediatelly log into and interact with the application. however it should be noted that jetty isn’t a full-featured javaee server and thus may not be always usable. project setup general configuration you need to add the jetty plugin to your pom.xml : 4.0.0 com.example mywebapp war ... ... org.mortbay.jetty maven-jetty-plugin 6.1.0 3 ... ... ... as you can see, i’m using jetty 6.1.0. defining a datasource let’s assume that the application uses a datasource configured at the server and accesses it normally via jndi. then we must define a reference to the data source in src/main/webapp/ web-inf/web.xml : ... ... ... jdbc/lmsdb javax.sql.datasource container shareable next we need to describe the datasource to jetty. there are multiple ways to do that, i’ve chosen to do so in src/main/webapp/ web-inf/jetty-env.xml : jdbc/lmsdb lmsdb myuser secret db.toronto.ca.ibm.com 3711 notice that the class used is db2simpledatasource and not a jdbc driver. that is, of course, because we need a datasource, not a driver. the jetty wiki pages also contain examples of datasource configuration for other dbs . finally we must make the corresponding jdbc implementation available to jetty by adding it to the plugin’s dependencies in the pom.xml : org.mortbay.jetty maven-jetty-plugin 6.1.0 <... com.ibm.db2 db2jcc 9.7 jar system ${basedir}/../lms.sharedlibraries/db2/db2jcc.jar com.ibm.db2 db2jcc_license_cisuz 9.7 jar system ${basedir}/../lms.sharedlibraries/db2/db2jcc_license_cisuz.jar please do not scorn me for using system-scoped dependencies , sometimes that is unfortunatelly the most feasible way. enabling security and configuring an authentication mechanism we would like to limit access to the application only to the authenticated users in the admin role with the exception of pages under public/. therefore we declare the appropriate security constraints in web.xml: ... authorizedusers all urls /* admin publicaccess public pages /public/* basic learning@ibm mini person feed management administrator access admin ... beware that jetty doesn’t support https out of the box and thus if you will add the data constraint confidential to any resource, you will automatically get http 403 forbidden no matter what you do. that’s why i’ve commented it out above. it is possible to enable ssl in jetty but i didn’t want to bother with certificate generation etc. next we need to tell jetty how to authenticate users. this is done via realms and we will use the simplest, file-based one. again there are multiple ways to configure it, for example in the pom.xml : org.mortbay.jetty maven-jetty-plugin 6.1.0 3 learning@ibm mini person feed management src/test/resources/jetty-users.properties ... the name must match exactly the realm-name in web.xml. you then define the users and their passwords and roles in the declared file, in this case in src/test/resources/ jetty-users.properties : user=psw,admin the format of the file is username=password[,role1,role2,...]. when you download jetty, you will find a fine example of using jaas with a file-based back-end for authentication and authorization under examples/test-jaas-webapp (invoke mvn jetty:run from the folder and go to http://localhost:8080/jetty-test-jaas/). however it seems that jaas causes an additional overhead visible as a few-seconds delay when starting the server so it might be preferrable not to use it. conclusion with jetty it’s easy to enable security and create a data source, which are the basic requirements of most web applications. anybody can then very easily run the application to test and develop it. development is where jetty really shines provided that you don’t need any feature it doesn’t have. when troubleshooting, you may want to tell jetty to log at the debug level with mvn -ddebug .. or to log requests , which can be also configured in the jetty-env.xml. beware that this post describes configuration for jetty 6.1.0. it can be different in other versions and it certainly is different in jetty 7. from http://theholyjava.wordpress.com/2010/09/10/jetty-maven-plugin-running-a-webapp-with-a-datasource-and-security/
September 13, 2010
by Jakub Holý
· 23,144 Views
article thumbnail
Eclipse on Mac: Use Magic Mouse/Trackpad back and forward gestures
The new Apple Magic Mouse is a controversial piece of hardware. Most people either really hate it or adore it. Personally, I think it is probably the best mouse I've ever used. There's a lot of criticism regarding the low profile of the mouse, suggesting it is not ergonomic. From my experience, I don't have any more wrist pains since I started using it. Ergonomics aside, the highlight of the mouse is the upper multi-touch surface with the enabled gestures. I use the back and forward gestures a lot. Especially when browsing the web. Swipe two fingers to the left and go back. Swipe right to go forward. It is very easy to get used to it. It works in web browsers, it works in Finder windows and native applications are adding support as well. However, it doesn't work in Eclipse. I want to swipe back and forward when browsing code. Back, go to previous location. Forward, return to the next location. I incidentally found a solution for that. There are many programs on the market that augment the Magic Mouse behavior. The reason for their existence is because Apple provides very limited gesture functionality. Other than back/forward and scroll, there's simply no support for other functions, not even Exposé or Spaces which were supported in the previous Mighty Mouse and are supported on the multi-touch trackpads. The most popular tools are MagicPrefs and BetterTouchTool (both free) but there are many others, free and commercial. Personally, I use MagicDriver, which is commercial (free while in beta). The reason I prefer it is because it has much lower CPU utilization, which was an issue for me in MagicPrefs. MagicDriver replaces the back/forward gestures with their keyboard equivalent: ⌘+[ and ⌘+]. These shortcuts are commonly used in OS X. Eclipse, by default, also uses these keyboard shortcuts to navigate back and forward. It just works. MagicPrefs and BetterTouchTool will require some customization: you can define the two finger swipe left and right to fire these keyboard shortcuts rather than use the default back/forward functionality. If you use a newer MacBook with a multi-touch trackpad or a Magic Trackpad, you can achieve the same functionality by using BetterTouchTool. AFAIK MagicPrefs does not support it and the current version of MagicDriver doesn't support it either. BetterTouchTool also has the ability to define gestures per application, so you can customize the behavior specifically for Eclipse and leave it as is for the rest of the applications. If you are new to these tools, I should warn you: defining too many gestures doesn't work very well. There are tons of options and it is very easy to get carried away and use as much as you can. However, there's probably a reason why Apple did not include support for all those gestures in the first place. It is very easy to "miss-fire" and perform gestures by accident. You don't always pay close attention to the number of fingers you have on the surface, so mistakes are very common. I just use a 3-finger click for expose. Don't be greedy and it will work just fine. Finally, if you want proper native support for back/forward gestures in Eclipse, you can vote for this bug.
August 31, 2010
by Zviki Cohen
· 11,069 Views
article thumbnail
Configure Those Annoying Tooltips in Eclipse to Only Popup on Request
whenever you hover over any piece of code in eclipse, it pops up a tooltip that displays more information about the item, such as its declaration, variable values or javadoc information, as in the example below. although useful at times , this becomes extremely annoying after a while, especially when you’re using your mouse to browse some code. popup after popup of unwanted information keeps obscuring your view of the code, leading to some lengthy expletives and big productivity loss. it’s useful information, but not every time all the time , almost like your car’s gps giving you directions to 10 different places at once while you’re still parked in the driveway. luckily there is a way to alleviate the problem and all it takes is changing some preferences in eclipse. we don’t want to completely disable tooltips (they can be useful), so i’ll show you how to tell eclipse to bring up the tooltips only when you request them. show tooltips only on request to tell eclipse to only show tooltips on request, do the following: go to window > preferences > java > editor > hovers . select the source item in the list. make sure the entire row is highlighted and that the checkbox is selected. move focus to the pressed key modifier while hovering field, positioning the cursor at the end of the default value shift . press and release ctrl . the value should now read shift+ctrl . if you made a mistake, just clear the field by pressing backspace or delete and try again. select the combined hover item in the list. move focus to the pressed key modifier while hovering field and press shift . the value should now read shift . click ok to accept the changes. the preferences should look something like this: you should now notice the following: if you want to show the javadoc or the declaration of some element hold down shift while hovering over the element. variable values won’t popup automatically anymore. to show a variable’s value in debug mode, press shift and hover over the variable. this is probably the only time when it’s a bit of a hassle to press shift, but the pros totally outweigh the cons here as i view variable values a lot less than the number of times annoying tooltips appear. if you want to show a quick preview of a method’s code, press ctrl+shift and hover over the method. this is a nice feature combined with the tooltip enrichment eclipse provides, so you can view a method’s code in a scrollable tooltip without having to navigate to the method and back again. other options – configure, disable or use the keyboard you can, of course, choose your own modifier keys in preferences, but these are the ones i found that work the best, especially given that ctrl and a click is a way to go to an element’s declaration or implementation in eclipse. i’ve found shift to conflict the least with existing features and easy enough to use on a frequent basis. keep in mind that 2 hovers can’t share the same modifier key (which is why we reassigned the source hover to use shift+ctrl ). you can also disable tooltips completely by deselecting the combined hover checkbox in the preference above, but i’ve found the shift key to be a nice middle ground so keep it enabled. to get similar information using the keyboard, press f2 while the cursor’s positioned on the code. to show variable values in debug mode, press ctrl+shift+d . a nice tip if you’ve disabled tooltips completely. from http://eclipseone.wordpress.com/2010/08/24/configure-tooltips-in-eclipse-to-only-popup-on-request/
August 25, 2010
by Byron M
· 12,434 Views · 19 Likes
article thumbnail
Practical PHP Patterns: Optimistic Offline Lock
In this series we are now entering the realm of concurrency, an option which adds complexity to an application as many different threads of execution are accessing the state storage at the same time. There is no native multithreading support in PHP (every script gets its own isolated process), but still concurrency can easily become an issue: multiple clients from all over the world continuosly make requests to PHP applications, and they can easily mutually overwrite their changesets. A classic example of race condition in the PHP world is two different clients filling an editing form referred to the same entity. They both will submit the form once it is complete, and the first one will get his changes overwritten by the second request. There are many other common situations were concurrent user can provoke errors in the system. Just think of different people choosing the same username and being told via Ajax that it is available; the slower one of them will be surprised when he submits his registration form. Background Before entering the explanation of patterns emerged to solve the concurrency problems, we need some definitions. First of all the notion of transaction is necessary: we define a transaction as a change of state of the application. Editing an entity is a transaction; adding or deleting another is still a transaction. The first kind of transaction we are interested in is the database transactions, which is totally accomplished in one PHP script. This is usually automatically enforced by mechanisms supported at the database level. The other kind of transaction is the business transaction, which spans over multiple HTTP requests and makes uses of from one to N database transactions. It comprehends checking out data, populating a form or other kind of rich user interface, modifying or adding data (a human-based action), and sending it back to the server. There is no automatic enforcement for business transaction, since they are defined by the business rules of the domain. This is not a problem that originates because of PHP nature, but because of the separation between client and server which the web is based on. Optimistic lock The Optimistic Offline Lock pattern is a way of ensuring integrity of data, avoiding the option that different clients submit conflicting changes. As the name suggests, it assumes that the chances of conflict are low. Indeed, when this is the case the optimistic lock does not slow down the user interaction a bit. The goal of this pattern is detecting a conflicting change and instead of applying it, rollback the business transaction and present an error to the user. It accomplishes this goal by validating that no one else has tampered with a record in the data source prior to allowing the modification to be committed. All open source version control systems such as Subversion and Git implement optimistic lock: anyone may check out a source file and work on it, to end his little fork later with a commit or push. The pain comes while merging, so you are supposed to integrate often. We also borrowed terminology from the source control systems, so in this article you'll encounter terms like commit, checkout, and merge. Implementation The most common implementation of Optimistic Offline Lock is a numerical version field on the record to protect from condurrency issues; to aid rollback notifications, other additional fields are useful for signaling the conflict, like the id of the last user that modified the record. The pattern inner working is not complex: when the data is submitted along with the version field value kept on the client, the version field in it must be the same currently present in the database. Only then it is incremented and the changeset committed. Encountering a different version field value in the database record means someone else has modified the data in between our checkout and commit, and so it must be preserved. For example we can show a diff to the user, like VCS does; in any case, we should interrupt the transaction. RDBMS and ORMs can simply use an additional column on the table where the root object is stored to support this pattern. Alternatives An alternative implementation consists in using all fields in the WHERE clause of the UPDATE (or only the sensible ones, or only the modified ones to let transactions that affect different field succeed when the business logic allows it. See below). This solution is handy when you can't add a version field, but it may have performance impact. Another alternative is to check conditions instead of version fields, which is practical in different use cases. For example, we can check the existence of a record before deleting it. This is already indirectly done to a cartain extent by ORMs and other abstraction layers when they provide you with an object abstraction you can calla delete() method on. An extension to the functionality of this pattern is checking that a current editing will (probably) commit, as a feature available at any time during editing of the data. This feature should check that the checkout data is still current. The domain An important is that it is part of the job of business domain logic to decide when a conflict occurs: some concurent changesets may be acceptable, while others may not be allowed even if they modify different fields. In his book, Fowler makes the example of adding elements to a collection concurrently. We can't know if this is right by seeing that the object is a collection, because it is the abstraction that it represent that must be maintained valid: sometimes it is right to add elements, sometimes the transaction should be stopped. Also merging strategies, which solve the conflicts, are subsceptible to domain considerations. Some are valuable and should be pursued, while some are costly and a rollback with manual user editing of the data is fine. Advantages The greatest advantage of this pattern is that it can support real time concurrency, like the check out of multiple items by multiple users simultaneously, as long as there is a merging strategy in place. It can also easily prevent race conditions. This pattern is also easy to implement, and thus it is the default choice to solve concurrency issues. Disadvantages When the conflict probability is high, since there are many concurrent transactions, this pattern produces too many rollbacks. It is not adequate for use cases where a pessimistic pattern should be adopted. Examples Doctrine 2 uses natively database transactions: it only commits the changes made in a PHP script when the EntityManager::flush() method is called. It automatically rolls back if an error is detected. Besides that, Doctrine 2 has also automatic Optimistic Offline Locking support, via the addition of a version field to the entity to lock.
August 17, 2010
by Giorgio Sironi
· 4,677 Views · 1 Like
article thumbnail
File Copy in Java – Benchmark
Yesterday I wondered if the copyFile method in JTheque Utils was the best method or if I need to change. So I decided to do a benchmark. So I searched all the methods to copy a File in Java, even the bad ones and found the following methods : Naive Streams Copy : Open two streams, one to read, one to write and transfer the content byte by byte. Naive Readers Copy : Open two readers, one to read, one to write and transfer the content character by character. Buffered Streams Copy : Same as the first but using buffered streams instead of simple streams. Buffered Readers Copy : Same as the second but using buffered readers instead of simple readers. Custom Buffer Stream Copy : Same as the first but reading the file not byte by byte but using a simple byte array as buffer. Custom Buffer Reader Copy : Same as the fifth but using a Reader instead of a stream. Custom Buffer Buffered Stream Copy : Same as the fifth but using buffered streams. Custom Buffer Buffered Reader Copy : Same as the sixth but using buffered readers. NIO Buffer Copy : Using NIO Channel and using a ByteBuffer to make the transfer. NIO Transfer Copy : Using NIO Channel and direct transfer from one channel to other. I think, this is the ten principal methods to copy a file to another file. The different methods are available at the end of the post. Pay attention that the methods with Readers only works with text files because Readers are using character by character reading so it doesn’t work on a binary file like an image. Here I used a buffer size of 4096 bytes. Of course, use a higher value improve the performances of custom buffer strategies. For the benchmark, I made the tests using different files. Little file (5 KB) Medium file (50 KB) Big file (5 MB) Fat file (50 MB) And I made the tests first using text files and then using binary files. The source file is not on the same hard disk as the target file. I used a benchmark framework, described here, to make the tests of all the methods. The tests have been made on my personal computer (Ubuntu 10.04 64 bits, Intel Core 2 Duo 3.16 GHz, 6 Go DDR2, SATA Hard Disks). And after a long time of bench, here are the results : Little Text File - All results We see that the method with a simple stream (Naive Streams) is from far the slowest followed by the simple readers methods (Naive Readers). The readers method is a lot faster than the simple stream because FileReader use a buffer internally. To see what happens to the other, here are the same graph but without the first two methods : Little Text File - Best results The best two versions are the Buffered Streams and Buffered Readers. Here this is because the buffered streams and readers can write the file in only one operation. Here the times are in microseconds, so there is really little differences between the methods. So the results are not really relevant. Now, let’s test with a bigger file. Medium Text File We can see that the versions with the Readers are a little slower than the version with the streams. This is because Readers works on character and for every read() operation, a char conversion must be made, and the same conversion must be made on the other side. Another observation is that the custom buffer strategy is faster than the buffering of the streams and than using custom buffer with a buffered stream or a single stream doesn’t change anything. The same observation can be made using the custom buffer using readers, it’s the same with buffered readers or not. This is logical, because with custom buffer we made 4096 (size of the buffer) times less invocations to the read method and because we ask for a complete buffer we have not a lot of I/O operations. So the buffer of the streams (or the readers) is not useful here. The NIO buffer strategy is almost equivalent to custom buffer. And the direct transfer using NIO is here slower than the custom buffer methods. I think this is because here the cost of invoking native methods in the operating system level is higher than simply the cost of making the file copy. Big Text File - All results Here we see that the Naive Readers shows its limit when the file size if growing. So let’s concentrate us on the best methods only, namely, remove the Naive Readers : Big Text File - Best results Here, it’s now clear that the custom buffer strategy is a better than the simple buffered streams or readers and that using custom buffer and buffered streams is really useful for bigger files. The Custom Buffer Readers method is better than Custom Buffer Streams because FileReader use a buffer internally. And now, continue with a bigger file : Fat Text File Results You can see that it doesn’t take 500 ms to copy a 50 MB file using the custom buffer strategy and that it even doesn’t take 400 ms with the NIO Transfer method. Really quick isn’t it ? We can see that for a big file, the NIO Transfer start to show an advantage, we’ll better see that in the binary file benchmarks. We will directly start with a big file (5 MB) for this benchmark : Big Binary File Results So we can make the same conclusion as for the text files, of course, the buffered streams methods is not fast. The other methods are really close. Fat Binary File Results We see here again that the NIO Transfer is gaining advantages more the files is bigger. And just for the pleasure, a great file (1.3 GB) : Enormous Binary File Results We see that all the methods are really close, but the NIO Transfer method has an advantage of 500 ms. It’s not negligible. Conclusion In conclusion, the NIO Transfer method is the best one for big files but it’s not the fastest for little files (< 5 MB). But the custom buffer strategy (and the NIO Buffer too) are also really fast methods to take files. So perhaps, the best method is a method that make a custom buffer strategy on the little files and a NIO Transfer on the big ones. But it will be interesting to also make the tests on an other computer and operating system. We can take several rules from this benchmark : Never made a copy of file byte by byte (or char by char) Prefer a buffer in your side more than in the stream to make less invocations of the read method, but don’t forget the buffer in the side of the streams Pay attention to the size of the buffers Don’t use char conversion if you only need to tranfer the content of a file Don’t hesitate to use channels to make file transfer, it’s the fastest way to make a file transfer I’ve also made some tests, but not complete, for files in the same hard disk and here the NIO Transfer method is a lot faster than the other. I think this is because on the same disk this method can make better use of the filesystem cache. I hope this benchmark (and its results) interested you. Here are the sources of the benchmark : Java Benchmark of File Copy methods From http://www.baptiste-wicht.com/2010/08/file-copy-in-java-benchmark
August 8, 2010
by Baptiste Wicht
· 27,697 Views
article thumbnail
Code Generation With Xtext
Recently I attended a local rheinJUG meeting in Düsseldorf. While the topic of the session was Eclipse e4, the night’s sponsor itemis provided some handouts on Xtext which got me very interested. The reason is that currently at work we are developing a mobile Java application (J9, CDC/Foundation 1.1 on Windows CE6) for which we needed an easy to use and reliable way for configuring navigation through the application. In a previous iteration we had – mostly because of time constraints – hard coded most of the navigational paths, but this time the app is more complex and doing that again was not really an option. First we thought about an XML based configuration, but this seemed to be a hassle to write (and read) and also would mean we would have to pay the price of parsing it on every application startup. Enter Xtext: An Eclipse based framework/library for building text based DSLs. In short, you just provide a grammar description of a new DSL to suit your needs and with – literally – just a few mouse clicks you are provided with a content-assist, syntax-highlight, outline-view-enabled Eclipse editor and optionally a code generator based on that language. Getting started: Sample Grammar There is a nice tutorial provided as part of the Xtext documentation, but I believe it might be beneficial to provide another example of how to put a DSL to good use. I will not go into every step in great detail, because setting up Xtext is Eclipse 3.6 Helios is just a matter of putting an Update Site URL in, and the New Project wizard provided makes the initial setup a snap. I assume, you have already set up Eclipse and Xtext and created a new Xtext project including a generator project (activate the corresponding checkbox when going through the wizard). In this post I am assuming a project name of com.danielschneller.navi.dsl and a file extension of .navi. When finished we will have the infrastructure ready for editing, parsing and generating code based on files like these: navigation rules for MyApplication mappings { map permission AdminPermission to "privAdmin" map permission DataAccessPermission to "privData" map coordinate Login to "com.danielschneller.myapp.gui.login.LoginController" in "com.danielschneller.myapp.login" map coordinate LoginFailed to "com.danielschneller.myapp.gui.login.LoginFailedController" in "com.danielschneller.myapp.login" map coordinate MainMenu to "com.danielschneller.myapp.gui.menu.MainMenuController" in "com.danielschneller.myapp.menu" map coordinate UserAdministration to "com.danielschneller.myapp.gui.admin.UserAdminController" in "com.danielschneller.myapp.admin" map coordinate DataLookup to "com.danielschneller.myapp.gui.lookup.LookupController" in "com.danielschneller.myapp.lookup" } navigations { define navigation USER_LOGON_FAILED define navigation USER_LOGON_SUCCESS define navigation OK define navigation BACK define navigation ADMIN define navigation DATA_LOOKUP } navrules { from Login on navigation USER_LOGON_FAILED go to LoginFailed on navigation USER_LOGON_SUCCESS go to MainMenu from LoginFailed on navigation OK go to Login from MainMenu on navigation ADMIN go to UserAdministration with AdminPermission on navigation DATA_LOOKUP go to DataLookup with DataAccessPermission from UserAdministration on navigation BACK go to MainMenu from DataLookup on navigation BACK go to MainMenu } As you can see it is a nice little language for defining coordinates in an application, meaning a specific GUI for a certain task and the possible navigation paths between them. Optionally a navigation path can be tagged to require one or more permissions to work. So for example one possible navigation path shown in the above sample is from the applications main menu, identified by the identifier MainMenu and represented in code by the com.danielschneller.myapp.gui.menu.MainMenuController class in the com.danielschneller.myapp.menu OSGi bundle to a GUI identified as DataLookup, implemented by com.danielschneller.myapp.gui.lookup.LookupController in the com.danielschneller.myapp.lookup bundle. For this path to be taken, the application must request the DataLookup navigation path and the currently logged in user be assigned the DataAccessPermission. What exactly that means is not the focus of this tutorial, suffice it to say that we somehow need to get the information contained in this specialized language into our Java application in some shape or form that can be evaluated at runtime. In the following example all information will be transformed into a HashMap based data structure. For our little mobile application this has several advantages over the XML option mentioned earlier: No XML parsing necessary on application startup, saving some performance Validation of the navigation rules ahead of time, preventing parse errors at runtime No libraries needed to access the information – by putting everything in a simple HashMap we do not have to rely on any non-standard classes whatsoever First thing I did when I started with Xtext was define a sample input file such as the one above. Then – following its general structure – I began to extract a formal grammar for it. Of course, the first draft of the sample data was not perfect, over the course of a few iterations I refined some of the syntax, but in the end this is the grammar definition I came up with. It is heavily commented to allow you to copy it out and still leave the documentation intact: grammar com.danielschneller.navi.NavigationRules with org.eclipse.xtext.common.Terminals generate navigationRules "http://com.danielschneller/fw/funkmde/navi/NavigationRules" /* * The top level entry point for the file. * "Root" is just a name as good as any, but * makes the meaning quite clear. */ Root: // first thing in the file is a "keyword", // followed by an attribute that will be // accessible as "name" later and allow // definition of an ID type of thing. 'navigation rules for' name=ID // after the keyword and "name" attribute // three sections follow, each assigned // to an attribute for later reference // (called "mappingdefs", "transitiondefs" // and "ruledefs"). // Their types are defined later in the file. mappingsdefs=Mappings transitiondefs=TransitionDefinitions ruledefs=NavigationRules // semicolon ends the definition of "Root" ; // mappings section >>>>>>>>>>>>>>>>>>>>>>>>>>>>> /* * Definition of the "Mappings" type used in * the "Root" type. */ Mappings: // first the keyword "mappings" is expected, // then an open curly 'mappings' '{' // after that a collection of "Mapping"s is // expected. The "+=" means that they will // all be collected in a collection type element // called "mappings" for future reference. // The "+" at the end means "at least one, but // more is just fine". (mappings+=Mapping)+ // finally the "Mappings" type requires a closing // curly brace. '}' // semicolon ends the definition of "Mappings" ; /* * Definition of a single "Mapping", those we are * collecting in the "mappings" attribute of the * "Mappings" type. */ Mapping: // each mapping starts with the keyword "map" // and is followed by an element of type "MappingSpec" 'map' MappingSpec ; /* * Definition of a "MappingSpec" element. This is * actually just a "parent type" for two more specific * kinds of "MappingSpec": */ MappingSpec: // no keywords are defined here, a "MappingSpec" // can be either a "PermissionMappingSpec" or a // "CoordinateMappingSpec". Any of these will be // fine where a "MappingSpec" is asked for. PermissionMappingSpec | CoordinateMappingSpec ; /* * Definition of a "PermissionMappingSpec" element. */ PermissionMappingSpec: // first the keyword "permission" is required. // then a "name" attribute is expected of type ID. // Following the name the "to" keyword is expected, // followed by a string that is stored in the "value" // attribute 'permission' name=ID 'to' value=STRING ; /* * Definition of a "CoordinateMappingSpec" element. * The definition is very similar to the "PermissionMappingSpec" * but has more attributes. */ CoordinateMappingSpec: // first the keyword "coordinate", then an ID stored as "name", // the keyword "to", followed by a string stored as "controllername", // next the keyword "in" and finally another string, memorized as // "bundleid" 'coordinate' name=ID 'to' controllername=STRING 'in' bundleid=STRING ; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< mappings section // >>>>>>>>>>>>>>>>>>>>>>>>>>>>> navigations section /* * Definition of the "TransitionDefinitions" type used in * the "Root" type. */ TransitionDefinitions: // first, this element is introduced with the "navigations" // keyword, followed by an open curly brace. 'navigations' '{' // after that a collection of "TransitionDefinition"s is // expected. The "+=" means that they will // all be collected in a collection type element // called "transitions" for future reference. // The "+" at the end means "at least one, but // more is just fine". (transitions+=TransitionDefinition)+ // the element ends with a closing curly brace '}' ; /* * Definition of a "TransitionDefinition" element. This * one is very simple. */ TransitionDefinition: // the keyword "define navigation" is required first, // then a "name" attribute of type ID is expected. 'define navigation' name=ID ; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< navigations section // >>>>>>>>>>>>>>>>>>>>>>>>>>>>> navrules section /* * Definition of the "NavigationRules" element. */ NavigationRules: // Element starts with the keywords "navrules" and // open curly. 'navrules' '{' // collection attribute called "rules", consisting // of one or more occurrences of a "Rule" element. (rules+=Rule)+ // element finishes with a closing curly keyword '}' ; /* * Definition of a "Rule" element as used in the "NavigationRules" * element. */ Rule: // first the "from" keyword, then a reference to one of the // coordinate mappings defined earlier. This time no new // definition of a coordinate is required, but one of those // that have been listed before. So the type here is put in // square brackets 'from' source=[CoordinateMappingSpec] // following the source specification, one or more "Destination" // type elements are expected, collected in a collection attribute // named "destinations" (destinations+=Destination)+ ; /* * Definition of a "Destination" type. These are collected * in a "Rule". */ Destination: // first comes an "on navigation" keyword. After that a // reference to one of the Transition elements defined // in the "navigations" section is required and stored // in the "transition" attribute. // after that follows a "go to" keyword and a reference // to a coordinate mapping, stored in the "target" attribute. // finally - as with the "destinations" collection attribute // in the "Rule" element - a "permissions" collection is // defined to store none or more (*) "PermissionReference" // elements. 'on navigation' transition=[TransitionDefinition] 'go to' target=[CoordinateMappingSpec] (permissions+=PermissionReference)* ; /* * Definition of a "PermissionReference" type. This is used * in the "permissions" collection of a "Destination". */ PermissionReference: // first, a "with" keyword is expected. After that a // "permission" attribute stores a reference to one of // the previously defined permission mappings from the // "mappings" section. 'with' permission=[PermissionMappingSpec] ; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< navrules section This is what XText can digest and create an editor plugin and outline view for. Just save this as navigationRules.xtext – when you created the XText project in Eclipse using the wizard it should have been prepared for you. Copying and pasting this into a .xtext file in Eclipse will provide you with syntax highlighting, code completion and syntax checking, making it easy to play around with grammar files. Once done, right click the .mwe2 file lying next to the grammar file in the Package Explorer view and select Run As MWE2 Workflow from the context menu. This will take a moment and generate several classes, both in the current (XText) project and the accompanying ...ui project. Next, right click the Xtext project and select Run As Eclipse Application from the context menu. This will bring up another Eclipse instance with the newly created support for navigation rules files (with a .navi suffix) installed. To try it out, just create a new project and in that a new file. Make sure its name ends in .navi. When asked, make sure to accept adding the Xtext nature to the project. You will be presented with a new, empty editor that already has an error marker in it. This is because according to our grammar definition, an empty file does not comply to all the rules we specified. Try hitting the code-completion shortcut (Ctrl-Space) twice and see what happens: The first code-completion fills in the navigation rules for part. According to the grammar this is the only valid text at the beginning of a file, so it is automatically inserted. Hitting Ctrl-Space again will tell you that now you need a Name of type ID. Just go ahead and try out the completion. It will help you create a syntactically sound navigation rules file. Notice that the Problems View tells you what is currently wrong. Also notice, that one you reach a part where references are expected by the grammar (e. g. when defining source and destination coordinates in a navigation rule) you will get suggestions based on what you entered earlier. This is what the whole sample from above looks like in the editor: While you are still fleshing out and fine tuning your grammar definitions, you will probably close this Eclipse instance and reopen it, once you repeated the Run As MWE2 Workflow steps in the main instance. In the long run I suggest you create a Feature and an Update Site project to allow easier distribution and updates of the intermediate iterations. Generating Code Now, as we have a complete Xtext DSL defined and in place let’s have a look at the Code Generation side of things. This part is completely optional: You are free to include the necessary Xtext libraries into your applications runtime (although they seem to be numerous) and just use them to dynamically load and parse .navi files on-the-fly. This would probably be a good idea if you were writing an Eclipse based application anyway. However, when targeting a very limited platform like JavaME this option is not viable. Instead we will now create a code generator that provides a transformation from the DSL syntax into more classic Java terms – specifically we will create a HashMap based data structure that carries all the same information, but in Java terms. This is a sample of what the generated output is going to look like: public class NaviRules { private Map navigationRules = new Hashtable(); // ... public NaviRules() { NaviDestination naviDest; // ========== From Login (com.danielschneller.myapp.gui.login.LoginController) // ========== On USER_LOGON_FAILED // ========== To LoginFailed (com.danielschneller.myapp.gui.login.LoginFailedController in com.danielschneller.myapp.login) naviDest = new NaviDestination(); naviDest.action = "USER_LOGON_FAILED"; naviDest.targetClassname = "com.danielschneller.myapp.gui.login.LoginFailedController"; naviDest.targetBundleId = "com.danielschneller.myapp.login"; store("com.danielschneller.myapp.gui.login.LoginController", naviDest); // ========== On USER_LOGON_SUCCESS // ========== To MainMenu (com.danielschneller.myapp.gui.menu.MainMenuController in com.danielschneller.myapp.menu) naviDest = new NaviDestination(); naviDest.action = "USER_LOGON_SUCCESS"; naviDest.targetClassname = "com.danielschneller.myapp.gui.menu.MainMenuController"; naviDest.targetBundleId = "com.danielschneller.myapp.menu"; store("com.danielschneller.myapp.gui.login.LoginController", naviDest); // ============================================================================= // ========== From LoginFailed (com.danielschneller.myapp.gui.login.LoginFailedController) // ========== On OK // ========== To Login (com.danielschneller.myapp.gui.login.LoginController in com.danielschneller.myapp.login) naviDest = new NaviDestination(); naviDest.action = "OK"; naviDest.targetClassname = "com.danielschneller.myapp.gui.login.LoginController"; naviDest.targetBundleId = "com.danielschneller.myapp.login"; store("com.danielschneller.myapp.gui.login.LoginFailedController", naviDest); // .... and so on ... } } The support class NaviDestination is omitted but is generally just a value holder struct type class. When creating the Xtext project using the wizard earlier we created a third Eclipse project, ending in ...generator. Its src folder contains three subdirectories called model, templates and workflow. Put the sample .navi file into the model directory. It will serve as the input for the generator. Create the first template Code generation is based on templates. Xtext leverages the Xpand template engine. In the templates directory create a new Xpand template using the context menu. Call it NaviRules.xpt, open it and insert the following: «REM» import the namespace defined in our DSL model «ENDREM» «IMPORT navigationRules» «REM» Define a template called "main" for elements of type "Root". The minus sign at the end takes care of not adding a newline at the end of it. «ENDREM» «DEFINE main FOR Root-» «ENDDEFINE» As there is only one instance of a Root element in a navigation rules file, this will be the main entry point - hence the name. There is no need to call it main, but it seems fitting. Now between the DEFINE and ENDDEFINE insert what is to be generated: As shown above, we need a new Java source file called NaviRules.java: ... «DEFINE main FOR Root-» «FILE "NaviRules.java"-» «ENDFILE-» «ENDDEFINE» ... Again, the contents to be generated is put in between the FILE and ENDFILE brackets. Anything not enclosed in «» will be used verbatim in the output file. So first of all, put in the static parts of the Java file. What I did was first write the source for a single navigation rule by hand, made sure it compiled and then copied over the relevant parts into the template piece by piece: ... «FILE "NaviRules.java"-» import java.util.*; public class NaviRules { public static class NaviDestination { String action; List requiredPermissions = new ArrayList(); String targetClassname; String targetBundleId; NaviDestination() {}; public final List getRequiredPermissions() { return new ArrayList(requiredPermissions); } // let Eclipse generate getters, setters, // equals and hashCode methods for this } private Map navigationRules = new Hashtable(); «ENDFILE-» ... Now, this is nothing special so far. To fill in the elements from the navigation rules DSL file put in the following: ... private Map navigationRules = new Hashtable(); public NaviRules() { NaviDestination naviDest; «REM» Iterate all elements in the "rules" collection attribute of the "ruledefs" attribute of the "Root" element. Call each iterated element (which is of type "Rule") "rule" and expand the "ruletmpl" template for it here. «ENDREM» «FOREACH ruledefs.rules AS r»«EXPAND ruletmpl FOR r»«ENDFOREACH» } ... In the class constructor we first define a local variable naviDest of the previously declared type. Then - as the comment states - the FOREACH instruction will iterate over all Rule type elements. This might not seem to be completely obvious at first. Remember at this point in the template the current scope is the "Root" element from the navigation rules file. It has an attribute called ruledefs as per the grammer definition. This attribute is of type NavigationRules which in turn has a collection attribute called rules, containing of Rule type objects. Inside the loop the current element can then be adressed by the template variable name r. The loop body (between FOREACH and ENDFOREACH) contains another Xpand instruction to expand a template called ruletmpl which will be declared next. Don't worry, even though this is a little difficult at first - switching contexts between the Java and the template scopes is made significantly easier in Eclipse, because the Xpand template editor will syntax color (static parts are blue) and also assist you with code completion inside the Xpand template parts. Ctrl-Spacing your way through it will make things more obvious than they are when reading an example. Now for the ruletmpl template. Place it below the ENDDEFINE statement belonging to the main template: ... «ENDFILE-» «ENDDEFINE» «DEFINE ruletmpl FOR Rule-» // ========== From «source.name» («source.controllername») «FOREACH destinations AS d»«EXPAND destTmpl(source) FOR d»«ENDFOREACH» // ============================================================================= «ENDDEFINE» You see the same idea used again: Static parts that get transferred into the output file 1:1 and Xpand statements that fill in data from the navigation rules definition file. In this case you see references to the attributes of the Rule element. As per the FOREACH instruction in the previous template, the one at hand will be repeated for every instance of Rule in our source file. Inside this definition the current scope is that of Rule, so with «source.name» the name attribute of the CoordinateMappingSpec object referenced as source in a Rule is taken first, then the controllername attribute likewise. Next up another FOREACH loop iterates the one or more possible Destinations of each Rule. Instead of just applying a template (destTmpl) for every Destination we also pass in the corresponding CoordinateMappingSpec stored in the source attribute of the Rule. This is then used in the following template: ... «DEFINE destTmpl(CoordinateMappingSpec source) FOR Destination-» // ========== On «transition.name» // ========== To «target.name» («target.controllername» in «target.bundleid») naviDest = new NaviDestination(); naviDest.action = "«transition.name»"; naviDest.targetClassname = "«target.controllername»"; naviDest.targetBundleId = "«target.bundleid»"; «FOREACH permissions AS p»«EXPAND permTmpl FOR p»«ENDFOREACH» store("«source.controllername»", naviDest); «ENDDEFINE» «DEFINE permTmpl FOR PermissionReference-» naviDest.requiredPermissions.add("«permission.value»"); «ENDDEFINE» In this innermost templates the attributes of the CoordinateMappingSpec objects source and target are accessed and put into place to be assigned to the members a NaviDestination Java object instance per Destination. There is only one more (very simple) template for the PermissionReference elements. With this, the Xpand file is complete. Set Up The Generator Workflow The wizard initially created a NavigationRulesGenerator.mwe2 file in the workflow folder. Open it and replace its contents with the following: module workflow.NavigationRulesGenerator import org.eclipse.emf.mwe.utils.* var targetDir = "src-gen" var fileEncoding = "Cp1252" var modelPath = "src/model" Workflow { component = org.eclipse.xtext.mwe.Reader { path = modelPath // this class has been generated by the xtext generator register = com.danielschneller.navi.NavigationRulesStandaloneSetup {} load = { slot = "root" type = "Root" } } component = org.eclipse.xpand2.Generator { metaModel = org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel {} expand = "templates::NaviRules::main FOREACH root" outlet = { path = targetDir } fileEncoding = fileEncoding } } The most interesting parts of this workflow file are the load section in the Reader component and the expand and outlet sections in the Generator component: The first one will connect a so-called slot with the Root element from our navigation rules. The second one will trigger the evaluation of the main template in the NaviRules.xpt file in the templates folder and feed any Root instances it finds in the *.navi files from the src/model (modelPath) into it. Now it is time for some actual generation. Run the generator workflow Right click the MWE2 file you just edited and select the Run As MWE2 Workflow command from the context menu. The Eclipse console will show this output: 0 [main] DEBUG org.eclipse.xtext.mwe.Reader - Resource Pathes : [src/model] 431 [main] DEBUG xt.validation.ResourceValidatorImpl - Syntax check OK! Resource: file:/Users/ds/ws/ws36_xtext/com.danielschneller.navi.dsl.generator/src/model/MyApp.navi 1013 [main] INFO org.eclipse.xpand2.Generator - Written 1 files to outlet [default](src-gen) 1014 [main] INFO .emf.mwe2.runtime.workflow.Workflow - Done. Then have a look at the newly generated contents of the src-gen source folder. If everything went alright, you should find a fresh NaviRules.java file placed there, based on the contents of your navigation rules file and the Xpand templates. Try and make some changes to the template, then re-run the workflow. You will see the changes reflected in the generated source file. Generate a second source File In the templates directory add another Xpand template file Navigation.xpt with the following content: «IMPORT navigationRules»; «DEFINE main FOR Root-» «FILE "Navigation.java"-» public final class Navigation { «FOREACH ruledefs.rules.destinations.transition.collect(e|e.name).toSet().sortBy(e|e) AS t»«EXPAND actionTmpl FOR t»«ENDFOREACH» private final String name; private Navigation(String aName) { name = aName; } public String getName() { return name; } } «ENDFILE-» «ENDDEFINE» «DEFINE actionTmpl FOR String-» /** Constant for Navigation «this» */ public static final Navigation «this» = new Navigation("«this»"); «ENDDEFINE» This is a template for a type-safe enumeration that can be used in Java 1.4 - remember I had to do this for JavaME. Notice the FOREACH loop in this case. It demonstrates that not only simple iterations are possible, but that Xpand allows more complex operations as well. In this case it will collect the names of all the navigation transitions from all the Destinations in the navigation rules. These are of type String. They are made unique by converting them to a Set datastructure and then finally sorted in their natural order. The resulting list of sorted strings is then iterated, each one - called t - is passed to the actionTmpl template. It is very simple, just placing the string itself («this») into a single line of Java source code. Of course, strictly speaking this is a rather complicated procedure to get the same information we could also have taken from the TransitionDefinitions element in the rules definition. However I think it serves as a nice example for additional Xpand capabilities. For a full description of its possibilities, have a look at the Xpand Reference in the Eclipse documentation. To use the new template, add another section to the MWE2 workflow definition: component = org.eclipse.xpand2.Generator { metaModel = org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel {} expand = "templates::Navigation::main FOREACH root" outlet = { path = targetDir } fileEncoding = fileEncoding } Running it again will produce a slightly different output, making clear that two files have been generated. This is what comes out in the src-gen folder as Navigation.java: public final class Navigation { /** Constant for Navigation ADMIN */ public static final Navigation ADMIN = new Navigation("ADMIN"); /** Constant for Navigation BACK */ public static final Navigation BACK = new Navigation("BACK"); /** Constant for Navigation DATA_LOOKUP */ public static final Navigation DATA_LOOKUP = new Navigation("DATA_LOOKUP"); /** Constant for Navigation OK */ public static final Navigation OK = new Navigation("OK"); ... More... This was just about my first experiments with Xtext. I am sure there is plenty more to be done with it. For more reading, please have a look at this very nice Getting started with Xtext tutorial by Peter Friese of Itemis. From http://www.danielschneller.com/2010/08/code-generation-with-xtext.html
August 7, 2010
by Daniel Schneller
· 27,323 Views
article thumbnail
Eclipse SDK 4.0: A Platform For A New Wave Of Killer Apps?
Last week you may have noticed that Eclipse SDK 4.0 got an early adopter release, allowing developers to play around with the updated SDK to create their own rich client applications. It's a bit different from the "traditional" Eclipse, introducing a model based user interface and CSS for application styling, as well as a services-oriented programming model. While the main focus of the release is to allow Eclipse projects and plugins to prepare for future releases, the following tutorial shows how to write applications in Eclipse 4.0. Tom Schindl has also produced a useful introduction. I will be kicking off my own tutorial into e4 in the next few weeks. I asked Mike Wilson, Eclipse Project PMC Lead a bit more about the e4 release: DZone: What is the difference between e4 and the core Eclipse stream? Mike Wilson: e4 is the name of an incubator, not a development stream. Ignoring source bundles, the difference between the Eclipse 3.6 SDK and 4.0 SDK is (only) a new version of the Workbench bundle, some new branding, and some new bundles to support the new workbench's implementation. The other 184 (assuming I counted correctly) bundles are common between the two versions. Internally, the workbench code has been completely re-architected to provide a new CSS-based look and feel, on top of a fully modelled user-interface. The changes involved in building this have been so significant that we have labelled 4.0 as an "Early Adopter Release". The intent is for it to be used by those early adopters that want to test backwards compatibility and migrate their plug-ins and RCP applications. I expect Eclipse end users will generally adopt the next release, Eclipse 4.1. DZone: Can I use any Eclipse based framework like EMF or GMF in e4? Mike Wilson: Yes. If the framework makes direct use of internals from the 3.x workbench implementation, it will need to be updated to be API clean first, anything else should work fine. The new workbench is actually built using EMF core. DZone: How long will you keep parallel streams going? Mike Wilson: As you can see from the previous answer, the differences between the streams are currently quite small. Depending on where innovation is happening, the delta could get larger but, in any case, the incremental cost of maintaining the existing 3.x stream is low. Really, the constraints that 3.x has (i.e. stability and backwards compatibility above anything else) mean that that we will be able to maintain it as long as the community needs it. DZone: e4 seems ready for early adopters. What is the plan to mature it past incubation status? Mike Wilson: At the risk of sounding like a broken record, e4 is the name of an incubator, of the form which I believe the foundation is calling a "perpetual incubator". It is a sandbox to allow new innovations in the Eclipse platform to be created. It will exist as long as the community believes innovation at the platform level is important. If you mean the Eclipse SDK 4.0 Early Adopter Release, that is *not* in incubation. It differs from any other SDK release only in that sweeping changes in the internals of the workbench may mean that those who consume it will see more visible bugs than in other recent releases. We fully expect to resolve those bugs to bring the quality up to the expected level by next year's Indigo release. Interim milestone builds should provide evidence of that. [Aside: Because we are aligning our 3.7 and 4.1 milestones, "M1" happens one week after 4.0 ships, so you likely won't see much difference for this first one.] DZone: What is your favourite e4 feature? Mike Wilson: My favourite feature is that we have found a way to make innovation possible at the platform level. The new community that has grown around the e4 Incubator is strong evidence that we all care that Eclipse has a future DZone: What is the rationale behind the name? Mike Wilson: "e4" just comes from "e" for Eclipse, and "4" to indicate that the goal is to build the "next major version" of Eclipse after "3.x". The Eclipse SDK 4.0 Early Adopter Release is built using technology from e4, and is the first release of the Eclipse SDK that is part of that new 4.x development stream.
August 4, 2010
by James Sugrue
· 14,197 Views
article thumbnail
Navigate and Fix Errors and Warnings in a Class With Eclipse Keyboard Shortcuts
i really don’t like it when eclipse shows errors/warnings annotations in a class. it’s sometimes nice to jump from one to the next and clean out a class one line at a time, but most of the time they’re just distractions, so i want to be able to find and fix them fast. so there must be a better way to jump between the errors/warnings than to use the mouse or page down to the next error. these methods are not only slow but often frustrating because you tend to miss the annotation, especially if it’s a big class. and navigating to the problems view using the keyboard is ok, but sometimes overkill for just clearing out errors/warnings in one class. a good thing then that eclipse offers keyboard shortcuts that take you to the next/previous annotation in the class. and it does so in a way that selects the annotation immediately, allowing you to use quick fix (ctrl+1) to fix it fast. so here’s how to use these shortcuts to navigate between the error/warning annotations and fix some of the errors easily. how to jump between errors and warnings below are the keys you can use to go to the next/previous annotation and to initiate quick fix. shortcut description ctrl+. next annotation. moves to the next warning/error in the class. ctrl+, previous annotation. moves to the previous warning/error in the class. ctrl+1 quick fix. a fast way to resolve certain warnings/errors automatically, but also useful for automating common editing tasks . to see how fast the next annotation/quick fix combo works, i’ve set up an example in the following video that shows a class with multiple errors/warnings and how using the next/previous annotation and quick fix combo can make you work faster. there’s 1 warning (an unused variable, message , that should die) and 2 errors (not wrapping a fileoutputstream call in a try-catch and not initialising a local variable output ). obviously not all errors are going to be solvable by quick fix, but some are: adding a missing cast, filling in types for generics and adding the @suppresswarning or @override annotations. and for the rest, at least you’ll be able to get to them easily. bonus tip : also see how to cleanup some of these warnings automatically every time you save . you can, of course, remap any of these keyboard shortcuts if they’re inconvenient. have a look at how to manage your keyboard shortcuts , specifically looking out for the commands next , previous (yes, for some reason they’re just called next and previous) and quick fix . only jumping between errors you might sometimes want to tell eclipse to only move between errors (and not warnings) when you press the next/previous annotation command. well, this is controlled by a next/previous annotation dropdown menu in the toolbar (as shown in the image below). as you press the next/previous annotation key (either the keyboard shortcut or toolbar button), eclipse will move to whatever annotations are checked in the dropdown. eclipse’s default only has errors and warnings selected (which is a reasonably good default, for once). you could disable warnings if you only want to move between errors, or vice versa. bonus tip: the other selection you might want to enable is occurrences . an occurrence is when you stand on a variable/method and eclipse highlights it and its declaration and usages within the class. if you select occurrences, pressing the next/previous annotation keys will also jump to the variable’s/method’s declaration and usages. this is nice when you want to quickly move to the variable’s usage in a long class. it’s optional if you want this on, so play around and see if it works for you. from http://eclipseone.wordpress.com
July 14, 2010
by Byron M
· 12,289 Views
article thumbnail
Spring Framework Architecture
the spring framework is a layered architecture which consists of several modules. all modules are built on the top of its core container. these modules provide everything that a developer may need for use in the enterprise application development. he is always free to choose what features he needs and eliminate the modules which are of no use. it's modular architecture enables integration with other frameworks without much hassle. the core module: provides the dependency injection (di) feature which is the basic concept of the spring framework. this module contains the beanfactory, an implementation of factory pattern which creates the bean as per the configurations provided by the developer in an xml file. aop module: the aspect oriented programming module allows developers to define method-interceptors and point cuts to keep the concerns apart. it is configured at run time so the compilation step is skipped. it aims at declarative transaction management which is easier to maintain. dao module: this provides an abstraction layer to the low level task of creating a connection, releasing it etc. it also maintains a hierarchy of meaningful exceptions rather than throwing complicated error codes from specific database vendors. it uses aop to manage transactions. transactions can also be managed programmatically. orm module: spring doesn’t provides its own orm implementation but offers integrations with popular object relational mapping tools like hibernate, ibatis sql maps, oracle toplink and jpa etc. jee module: it also provides support for jmx, jca, ejb and jms etc. in lots of cases, jca (java ee connection api) is much like jdbc, except where jdbc is focused on database jca focus on connecting to legacy systems. web module: spring comes with mvc framework which eases the task of developing web applications. it also integrates well with the most popular mvc frameworks like struts, tapestry, jsf, wicket etc. from http://himanshugpt.wordpress.com/2010/07/05/262/
July 6, 2010
by Himanshu Gupta
· 118,477 Views · 10 Likes
article thumbnail
Pragmatic Look at Method Injection
Intent Allows container to inject methods instead of objects and provides dynamic sub classing. Also Known As Method decoration (or AOP injection) Motivation Sometimes it happens that we need to have a factory method in our class which creates a new object each time we access the class. For example, we might have a RequestProcessor which has a method called process which takes a request as an input and returns a response as an output. But, before the response is generated, request needs to be validated and then passed to a service class which will process the request and returns the response. public class RequestProcessor implements Processor { private Service service; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = service.makeServiceCall(request); return response; } protected ValidatorImpl getNewValidatorInstance() { return new ValidatorImpl(); } } As can be seen in the above code snippet, we are creating a new ValidatorImpl instance each time process method is called. RequestProcessor requires a new instance each time because Validator might have some state which should be different for each request(for example a list of error messages). RequestProcessor bean is managed by dependency injection container like spring where as Validator is being instantiated within the RequestProcessor. This solution looks like ideal but it has few shortcomings : RequestProcessor is tightly coupled to the Validator implementation details. If Validator had any constructor dependencies, then RequestProcessor need to know them also. For example, if Validator has a dependency on some Helper class which is injected in Validator constructor then RequestProcessor needs to know about helper also. There is also another approach that you can take in which container will manage the Validator bean(prototype) and you can make bean aware of the container by implementing ApplicationContextAware interface. public class RequestProcessor implements Processor,ApplicationContextAware { private Service service; private ApplicationContext applicationContext; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = getService().makeServiceCall(request); return response; } protected Validator getNewValidatorInstance() { return (Validator)applicationContext.getBean("validator"); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void setService(Service service) { this.service = service; } public Service getService() { return service; } } This approach also has its drawback as the application business logic is now coupled with Spring framework. Method injection provides a better way to handle such cases. The key to Method injection is that the method can be overridden to return the another bean in the container.In Spring method injection uses CGLIB library to dynamically override a class. Applicability Use Method injection when you want to avoid container dependency as we have seen in the second approach, in which you have to inject a non singleton bean inside a singleton bean. you want to avoid subclassing. For example, suppose that RequestProcessor is processing two types of response and depending upon the the type of report , we use different validators. So, we can have subclass RequestProcessor and have Report1RequestProcessor which just provides the Validator required for Report1. public class Report1RequestProcessor extends RequestProcessor { @Override protected Validator getNewValidatorInstance() { return new ValidatorImpl(); } } public abstract class RequestProcessor implements Processor { private Service service; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = getService().makeServiceCall(request); return response; } protected abstract Validator getNewValidatorInstance(); public void setService(Service service) { this.service = service; } public Service getService() { return service; } } Implementation Method injection provides a cleaner solution. Dependency Injection container like Spring will override getNewValidatorInstance() method and your business code will be independent of both the spring framework infrastructure code as well as Concrete implementation of Validator interface. So, you can code to interface. public abstract class RequestProcessor implements Processor { private Service service; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = getService().makeServiceCall(request); return response; } protected abstract Validator getNewValidatorInstance(); public void setService(Service service) { this.service = service; } public Service getService() { return service; } } The method requires a following signature [abstract] methodName(no-arguments); If the class does not provide implementation as in our class RequestProcessor, Spring dynamically generates a subclass which implements the method otherwise it overrides the method. application-context.xml will look like this This is how method injection can be used in our applications. Consequences Method injection has following benefits: 1) Provides dynamic subclassing 2) Getting rid of container infrastructure code in scenarios where Singleton bean needs to have non singleton or prototype bean. Method injection has following Liabilities : 1) Unit testing - Unit testing will become difficult as we have to test the abstract class. You can avoid this by making the method which provides you the instance as non-abstract but that method implementation will be redundant as container will always override it. 2) Adds magic in your code - Anyone not familiar with method injection will have hard time finding out how the code is working. So, it might make your code hard to understand.
July 5, 2010
by Shekhar Gulati
· 34,823 Views · 2 Likes
article thumbnail
16 Tips for Securing Your Admin Page
So you've finished that shiny new website and you want make sure that you and your buddies are in control. Besides the obvious things such as SSL and logging all access, there are a fewest practices for authentication/access that developers recommend. Here are some of the recommendations: Require separate login pages for users and admin using the same DB table. This will prevent XSRF and session-stealing, plus the attacker won't be able to access to admin areas) [Thief Master] Use complex passwords for admin accounts. For example, "uvula{:&:>iuJ", not "12345". Of course, you have to remember it. :) [Developer Art] Introduce an artificial pause between each admin password attempt to prevent brute force attacks. [Lo'oris] Blocking users IP after a number of failed admin login attempts or requiring a CAPTCHA after a failed login (but not the first one, because that's really annoying) will also stop brute force attacks. [Thief Master] If the admin section is in a separate subdirectory, you should consider also adding webserver native authentication to that area (e.g. via .htaccess in Apache). Then an attacker would need both the subdirectory password and the user password. [Thief Master] Consider Second level authentication such as client certificates (e.g. x509 certs), smart cards, cardspace, etc. [JoeGeeky] Restrict access to the admin area. Only allow clients from trusted IPs/Domains. [JoeGeeky] Lock down IPrincipal & Principal-based authorization and make rights immutable and non-enumerable. Also make sure that all authorization assessments are based on the Principal. [JoeGeeky] Set up an email notification system that alerts admins when any rights are upgraded. This will help you catch an attacker that elevates his/her rights. [JoeGeeky] Consider fine-grained rights for admins. Typical Role-Based Security (RBS) approaches are not as safe because some roles will end up with more rights that they need. You should distribute rights based on the exact actions that a admin performs. This could cause a lot of overhead with more diverse admin-types, but it is safer because rights are issued more sparingly. [JoeGeeky] Restrict the creation of further admins and carefully control what admins can do to other admins. It's best to have a locked-down 'super-admin' client. [JoeGeeky] Consider Client Side SSL Certificates or RSA type keyfobs (electronic tokens) for added security. [Daniel Papasian] If you're using using cookies for authentication, use separate cookies for admin and normal pages. One way is to put the admin section on a different domain. [Daniel Papasian] One possibility, if it's practical, is to put the admin site on a private subnet instead of the internet. [John Hartsock] Re-issue auth/session tickets when moving between admin and normal usage contexts of the website. [Richard JP Le Guen] Require equally strong mechanisms (using the above techniques) for basic users so that admins aren't the only ones with highly-secure accounts. [Lo'oris] These tips were gathered in a question by UpTheCreek from StackOverflow.
June 21, 2010
by Mitch Pronschinske
· 9,261 Views
article thumbnail
Working with the bit.ly API to shorten URLs
Bit.ly is a quite popular URL shortening service. On Tiwtter, almost all of the links I see provided by the people I follow are posted as bit.ly shortcuts. If you’ve used a Twitter client, you probably already know that some of them (if not almost every single of them) offers URL shortening as a built-in capability. Now, you can implement the same functionality, thanks to the fact that bit.ly offers a public API to do this. But let’s start with coding. First of all, all data that is passed to the service is transferred via HTTP requests. The response generated by the service is by default formatted as a JSON document, however the developer can explicitly specify that XML data should be returned. A request to the bit.ly shortening service requires authentication, and the username and API key are required to be passed as parameters. This means that in order to use the service, a bit.ly account is needed (it is free). The API key can be found here (http://bit.ly/account/your_api_key) once the user registered. Shortening The first (and probably the most important method) is the one that actually shortens the URL and it is called /v3/shorten. V3 at the beginning stands for the API version (that is 3.0 at the moment, so don’t worry about that). This method accepts 5 parameters: • format – determines the output format for the request • longUrl –determines the long URL that needs to be shortened • domain – [optional] the domain used for shortening – either bit.ly or j.mp (default: bit.ly) • x_login – the user ID (although in the documentation it is indicated as optional, it is not) • x_apiKey – the user API key (although in the documentation it is indicated as optional, it is not) Let’s look at the method I’ve written to shorten the URL: enum Format { XML, JSON, TXT } enum Domain { BITLY, JMP } string ShortenUrl(string longURL, string username, string apiKey, Format format = Format.XML, Domain domain = Domain.BITLY) { string _domain; string output; // Build the domain string depending on the selected domain type if (domain == Domain.BITLY) _domain = "bit.ly"; else _domain = "j.mp"; HttpWebRequest request = (HttpWebRequest)WebRequest.Create( string.Format(@"http://api.bit.ly/v3/shorten?login={0}&apiKey={1}&longUrl={2}&format={3}&domain={4}", username, apiKey, HttpUtility.UrlEncode(longURL), format.ToString().ToLower(), _domain)); using (WebResponse response = request.GetResponse()) { using (StreamReader reader = new StreamReader (response.GetResponseStream())) { output = reader.ReadToEnd(); } } return output; } There are two enums that hold the possible data formats as well as the domain names. This is made for safety reasons – if I would pass these as string parameters, there is a higher chance the end-user will pass the wrong string, and then the function will fail. The code is based on a single HttpWebRequest that creates a HTTP request to the URL that is built according to the data passed to it. Then, I am getting the response stream and passing the string representation to the returned string variable. Notice the fact that I am explicitly returning a string value for this method. In fact, I could either return a JsonDocument instance (requires a third-party library to use this class) or XmlDocument. But since there are two possible formats for the request to handle, it is better to return this as a simple string and then let the developer decide what he wants to do next. Once called, the function will return data similar to this: 200 OK http://j.mp/crnexS crnexS msft http://www.microsoft.com 0 Or this (for JSON): { "status_code": 200, "status_txt": "OK", "data": { "long_url": "http:\/\/www.microsoft.com", "url": "http:\/\/j.mp\/crnexS", "hash": "crnexS", "global_hash": "msft", "new_hash": 0 } } Or this (for TXT): http://j.mp/crnexS I am using a custom domain here, but as you see – the format and domain are optional parameters. I can leave them with default values without actually passing them to the function, and then the only values that need to be indicated are the user ID, API key and the long URL. Decoding There is also a way to decode the URL to its initial state from what was the shortened one. The method is called /v3/expand and is used in a similar manner as the shortening one. In this method, I am also using the Format enum to specify the output format: string DecodeUrl(string[] urlSet, string[] hashSet, string username, string apiKey, Format format = Format.XML) { string output; string URL = string.Format(@"http://api.bit.ly/v3/expand?login={0}&apiKey={1}&format={2}", username, apiKey, format.ToString().ToLower()); if (urlSet != null) { foreach (string url in urlSet) URL += "&shortUrl=" + HttpUtility.UrlEncode(url); } if (hashSet != null) { foreach (string hash in hashSet) URL += "&hash=" + hash; } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); using (WebResponse response = request.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { output = reader.ReadToEnd(); } } return output; } It works a bit different though. As you can see, I am requesting the user to pass two arrays – one with URLs and one with hashes. One of them can be null, therefore the URL can be decoded either by the hash or by the shortened URL. The user can pass both arrays, and get a result similar to this: 200 OK http://j.mp/crnexS http://www.microsoft.com crnexS msft crnexS http://www.microsoft.com crnexS msft The URLs are sanitized inside the function – I am not assuming that the user will pass the encoded URL. In fact, the developer should never assume that the user will pass the correct value – the code should be as foolproof as possible. User validation If you work on an application that depends on the URL shortening service, it would be a good idea to validate the user before making the API calls. Bit.ly provides a method for this as well and it is called /v3/validate. It only requires three parameters – the username, the API key and the output format (that is in fact optional). The C# implementation for this method looks like this: string ValidateUser(string username, string apiKey, string userToCheck, string keyToCheck, Format format = Format.XML) { string output; string URL = string.Format(@"http://api.bit.ly/v3/validate?x_login={0}&x_apiKey={1}&login={2}&apiKey={3}&format={4}", userToCheck, keyToCheck, username,apiKey, format.ToString().ToLower()); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); using (WebResponse response = request.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { output = reader.ReadToEnd(); } } return output; } A bit of confusion can be caused by the fact that there are x_ -prefixed copies of login and API key. You need to pass your ID and API key to verify someone else’s account validity. X_ -prefixed parameters represent the end user. The output should look similar to this: 200 OK 1 Count clicks Bit.ly provides click statistics, so once you shorten a URL, you can track its basic usage. Statistics are available through the /v3/clicks method. It doesn’t have a TXT output format, so you will have to avoid using that (or create a separate enum, that is the best choice). The implementation for it looks like this: string GetClicks(string[] urlSet, string[] hashSet, string username, string apiKey, Format format = Format.XML) { string output; string URL = string.Format(@"http://api.bit.ly/v3/clicks?login={0}&apiKey={1}&format={2}", username, apiKey, format.ToString().ToLower()); if (urlSet != null) { foreach (string url in urlSet) URL += "&shortUrl=" + HttpUtility.UrlEncode(url); } if (hashSet != null) { foreach (string hash in hashSet) URL += "&hash=" + hash; } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); using (WebResponse response = request.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { output = reader.ReadToEnd(); } } return output; } Same as for the Expand method, an array of URLs and hash codes can be passed and statistics will be generated for multiple entries at once. The response looks like this (in XML format): 200 http://j.mp/crnexS msft 0 crnexS 2230 0 msft crnexS crnexS 2230 OK Note that the XML won’t be indented by default. Check for PRO domain Bit.ly offers pro, customizable domains. That means, that not only bit.ly and j.mp can be used for shortening, but user-defined domains as well. The /v3/bitly_pro_domain method allows to check whether a domain is bit.ly PRO-powered or not. It is very similar to the user validation method, but it accepts the domain name instead of the user credentials. The C# implementation looks like this: string CheckPro(string username, string apiKey, string domain, Format format = Format.XML) { string output; string URL = string.Format(@"http://api.bit.ly/v3/bitly_pro_domain?login={0}&apiKey={1}&domain={2}&format={3}", username, apiKey, domain, format.ToString().ToLower()); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); using (WebResponse response = request.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { output = reader.ReadToEnd(); } } return output; } Once called, the output looks like this: 200 nyti.ms 1 OK URL lookup Bit.ly also allows the lookup of long URLs. For example, you might want to find if there is an existing short URL for the existing long URL. To do this, there is the /v3/lookup method. The implementation is quite simple and as other methods, it has the same base structure: string Lookup(string username, string apiKey, string[] url, Format format = Format.XML) { string output; string URL = string.Format(@"http://api.bit.ly/v3/lookup?login={0}&apiKey={1}&format={2}", username, apiKey, format.ToString().ToLower()); foreach (string _url in url) URL += "&url=" + HttpUtility.UrlEncode(_url); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); using (WebResponse response = request.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { output = reader.ReadToEnd(); } } return output; } The XML response looks similar to this for a positive result (there is a URL found): 200 http://www.dreamincode.net http://bit.ly/mviGY mviGY OK Notice that I can pass an array of URLs to be checked. Mind, though, that the maximum number of URLs that can be passed to the method is 15. With the methods described above, you can harness the power of bit.ly and bring it to your .NET application (the code can easily be ported to any .NET-compatible programming language). For official documentation, you can take a look here.
June 18, 2010
by Denzel D.
· 33,654 Views
  • Previous
  • ...
  • 757
  • 758
  • 759
  • 760
  • 761
  • 762
  • 763
  • 764
  • 765
  • 766
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×