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

Latest Articles - DZone

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,635 Views · 1 Like
article thumbnail
Simple Hostname Validation
Ruby version of http://stackoverflow.com/questions/2532053/validate-hostname-string-in-python/2534561#2534561 Support of validation as per: http://en.wikipedia.org/wiki/Hostname -- but does not include the SCTP extension ... def valid_hostname?(hostname) return false if hostname.length > 255 or hostname.scan('..').any? hostname = hostname[0 ... -1] if hostname.index('.', -1) return hostname.split('.').collect { |i| i.size <= 63 and not (i.rindex('-', 0) or i.index('-', -1) or i.scan(/[^a-z\d-]/i).any?) }.all? end Simple use-case: (main):001:0> %w( example.com. example.com example.-com *example.com *example.-com example example- -example _http._sctp.www.example.com example..com example.com.. example..com.. ..example.com ).each { |i| p valid_hostname?(i) } true true false false false true false false false false false false false => ["example.com.", "example.com", "example.-com", "*example.com", "*example.-com", "example", "example-", "-example", "_http._sctp.www.example.com", "example..com", "example.com..", "example..com..", "..example.com"]
August 15, 2010
by Snippets Manager
· 3,179 Views
article thumbnail
Do not use Relative Path with LogBack
A little tip that can be useful and save a lot of time : Do not use relative path with LogBack. I wondered why this little LogBack configuration didn’t work : JTheque logs/jtheque.log logs/jtheque.%i.log.zip 1 5 5MB %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n No file were written. I searched over a long time and after that tested with an absolute path and it worked really well. But absolute path is not very good. But, you can use system properties in the configuration, so I used user.dir to make the thing work : ... ${user.dir}/logs/jtheque.log ${user.dir}/logs/jtheque.%i.log.zip 1 5 ... And this time, it works well ! Hope this will be useful to somebody. From http://www.baptiste-wicht.com/2010/08/do-not-use-relative-path-with-logback
August 14, 2010
by Baptiste Wicht
· 39,592 Views · 1 Like
article thumbnail
Practical PHP Patterns: Data Transfer Object
Information can travel in very different ways between the parts of an applications, which could be tricky when these parts are distributed on different tiers, or times. The Data Transfer Object pattern prescribes to use a first-class citizen like a class to model the data used in the communication. This pattern was originally meant to aid logic distribution: coarse grained interfaces, which are ideal for remote interaction, must return more data in each call to reduce the number of messages sent over the network and their overhead. This kind of objects is built with the goal of be easy to serialize and send over the wire. In the PHP world, the communication is usually either from server to server, or even targets the same server: PHP is a lot different from other languages which are used for application distribution. Commonly the serialization and unserialization of objects are accomplished by the same codebase, which has a short life (the time of an HTTP request) and stores data with the serialization mechanism to maintain state between different requests. As a result, the usual dependencies discourse, which prescribes to use a Data Mapper between the Domain Model and the DTOs, do not apply; to the point that sometimes even domain model objects are serialized directly (an ORM like Doctrine 2 allows you to do so). There are more differences with classic Java DTOs which we'll see in this article. Implementation The definition of Data Transfer Object talks about communication between different processes: subsequent executions of the same PHP script are indeed different processes (or, when the same process is reused, it does not share any variable space with the previous executions). PHP is peculiar also from the implementation point of view: a DTO may not even be an object, since an ordinary or multidimensional array will do the same job in many cases. However, an object implementation is necessary to take advantage of object handlers, where the structure of data is not hierarchical but involves a connected graph of objects or recursive data structures. This implementation choice is much more clear than using arrays and variable references, which can be tricky in PHP. Basically, a DTO is the object which we have been told to never write: it has getters and setters to expose allof its properties, while providing nearly no encapsulation nor business logic. It's a data structure, like a Value Object (which was its name in certain Java literature). But it is not immutable nor it carries the semantic meaning of Value Objects. Use cases Data Transfer Objects come handy in many use cases. In their simplest implementation, they are used for returning multiple values from a method. Their further evolution involves then serialization mechanisms; of course both the provenience and the destination of a Data Transfer Object need to be a PHP environment, a fact which opens different scenarios from classical Java distribution ones, that involve clients well. For example a Data Transfer object, easily serializable, can be stored in caches (memcache) or sessions ($_SESSION). Other use cases regard databases: according to Fowler, Record Sets like PDOStatement can be defined as the Data Transfer Objects of relational databases. There are even more scenarios for Data Transfer Object, like clients which return a serialized data structure, or their usage for breaking dependencies between different layers: a Controller may populate a DTO and pass it to the View. Serialization As you may have experience while using var_dump() in PHP, the objects of a Domain Model are usually interconnected in a complex graph; DTOs isolate a subset of the graph and make it easy to serialize, even by omitting part of the information. Thus, serialization of domain object needs some complex infrastructure (lazy loading proxies which are discarded on serialization and must be re-initialized during the merge with a current object graph); sometimes is by far easier to extract data in a DTO, especially when you do not have particular libraries at your disposal. Once you have an isolated object graph, PHP will handle serialization by itself, even without marker interfaces; it will simply include all the public, protected and private properties (this behavior can be modified by specifying a __sleep() method). Example This running code shows a small domain model composed of the User and Group classes, and how a DTO for the User class allows to serialize a User without pulling in its Groups, for example for quickly storing it in a cache. _name; } public function setName($name) { $this->_name = $name; } /** * @return string */ public function getRole() { return $this->_role; } public function setRole($role) { $this->_role = $role; } public function addGroup(Group $group) { $this->_group = $group; } public function getGroups() { return $this->_groups; } } /** * Another Domain Model class. */ class Group { private $_name; /** * @return string */ public function getName() { return $this->_name; } public function setName($name) { $this->_name = $name; } } /** * The Data Transfer Object for User. * It stores the mandatory data for a particular use case - for example ignoring the groups, * and ensuring easy serialization. */ class UserDTO { /** * In more complex implementations, the population of the DTO can be the responsibilty * of an Assembler object, which would also break any dependency between User and UserDTO. */ public function __construct(User $user) { $this->_name = $user->getName(); $this->_role = $user->getRole(); } public function getName() { return $this->_name; } public function getRole() { return $this->_role; } // there are no setters because this use cases does not require modification of data // however, in general DTOs do not need to be immutable. } // client code $user = new User(); $user->setName('Giorgio'); $user->setRole('Author'); $user->addGroup(new Group('Authors')); $user->addGroup(new Group('Editors')); // many more groups $dto = new UserDTO($user); // this value is what will be stored in the session, or in a cache... var_dump(serialize($dto));
August 12, 2010
by Giorgio Sironi
· 95,502 Views · 5 Likes
article thumbnail
Infinite scroll : Loading Content While Scrolling, Using Java and JQuery
Have you seen the infinite scrolling of content in some web pages? For example, in DZone.com when you scroll the page to the bottom, new links will be loaded automatically and it’ll give you the illusion that the page scrolls infinitely. Another good example is that Bing’s Image Search. The technique is not hard to implement. With the use of a single servlet and JSP, we can implement a basic functionality with infinite scroll. Before dive into code details, have a look at this demo to get a feel of it: Infinite Scroll Demo To implement this, we need a servlet which will serve the dynamic content and a JSP file which will have the UI and act as a client to receive the content. Below are the code for these two files. I’m leaving other common stuffs (like web.xml entry etc) to you. Code for Servlet: package com.vraa.demo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class InfinitContentServlet extends HttpServlet { private static Integer counter = 1; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); try { String resp = ""; for (int i = 1; i <= 10; i++) { resp += "" + counter++ + " This is the dynamic content served freshly from server"; } out.write(resp); } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } } Code for JSP file: Demo page: Infinite Scroll with Java and JQuery This page is a demo for loading new content while scrolling. Credits: Veera Sundar | veerasundar.com | @vraa 1Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ornare facilisis mollis. Etiam non sem massa, a gravida nunc. Mauris lectus augue, posuere at viverra sed, dignissim sed libero. 2Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ornare facilisis mollis. Etiam non sem massa, a gravida nunc. Mauris lectus augue, posuere at viverra sed, dignissim sed libero. 3Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ornare facilisis mollis. Etiam non sem massa, a gravida nunc. Mauris lectus augue, posuere at viverra sed, dignissim sed libero. 4Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ornare facilisis mollis. Etiam non sem massa, a gravida nunc. Mauris lectus augue, posuere at viverra sed, dignissim sed libero. 5Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ornare facilisis mollis. Etiam non sem massa, a gravida nunc. Mauris lectus augue, posuere at viverra sed, dignissim sed libero. How it works? The secret behind this is the scrolltop property. By checking this value we can determine whether the scrollbar has reached near to the bottom or not. If it reached, send an AJAX request to server to get more content and append it to the page. Look at the following two lines which does this: $contentLoadTriggered = false; $("#content-box").scroll(function(){ if($("#content-box").scrollTop() >= ($("#content-wrapper").height() - $("#content-box").height()) && $contentLoadTriggered == false) { $contentLoadTriggered = true; $.get("infinitContentServlet", function(data){ $("#content-wrapper").append(data); $contentLoadTriggered = false; }); } }); From http://veerasundar.com/blog/2010/07/infinite-scroll-loading-content-while-scrolling-using-java-and-jquery/
August 12, 2010
by Veera Sundar
· 38,167 Views
article thumbnail
The Seven Wastes of Software Development
If you are not creating value in your product, consider whether your there are steps in your process that can be cut out to reduce waste.
August 11, 2010
by Matt Stine
· 139,391 Views · 4 Likes
article thumbnail
Practical PHP Patterns: Remote Facade
The Remote Facade pattern is a specialization of the Facade one which abstracts the interaction with a remote service (which is executed out of the PHP process, or out of the current machine). PHP applications usually aren't fond of transparent remote invocation, since the remote application is often not usually written in PHP (think of Twitter or Google web services). A Remote Facade provides a unique point of access to an external service (usually a web service, since it is so easy to connect to it with PHP code), with a coarse-grained interface that would not leak as a Proxy object would in some chatty use cases. Implementation The Remote Faced may create and manage a bunch of domain objects, which you can use to manipulate the returned data and prepare message to send; only when the Remote Facade is called network communication happens. Many small objects are the key to a resilient and easy to use object model. The Remote Facade hides the complexity of the communication, which involves mapping of objects to a data stream, and is built over this object model. Other responsibilities can be applied to the Facade, given its key position on a port of the application. For example security and access control can be applied by making checks in its methods. Also automatic transactional control can be implemented based on the semantics of the model: every method is a transaction, since you can never rely on the the calling order and consistency of client code. There are also responsibilities that a Remote Facade should not have. The main one is domain logic: it is a more orthogonal approach to model business logic in an external object model and leave only the translation mechanism in the Remote Facade (that way you would be even able to swap different Facades over the same domain model). Backends PHP has networking under its skin, so there are multiple ways to interact with remote servers. A common approach is using curl (it is implemented as an extension, but it is very common in PHP installations). The PHP extension is based on libcurl, a C library which according to php.net currently supports http, https, ftp, gopher, telnet, dict, file, and ldap protocols. And also HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, and user+password authentication. Another standard networking mechanism is using sockets and streams (stream_socket_client() and the related famiily of functions). The definition of stream in PHP is that of a resource (which is a PHP variable type) which exhibits streamable behavior, meaning that it can be written to or read from in a linear fashion. From PHP 4.3, streams unify all these resources under a common interface to reuse various functions orthogonally to the wrappers which identify the various types of sources, like the filesystem, HTTP and FTP, but also compression streams and Phar archives. The stream extension, which includes the set of functions that handle streams (comprehending the remote ones, via sockets), is even more common that the curl one. Advantages There are many advantages to insulate your application from external resources using a Remote Facade. For starters, you will keep network-related code in one place, so that it would be easy to change, cohesive and with no duplication in various parts of the codebase. You also easily obtain insulation during testing: you can run integration tests on the Facade itself, and unit-level ones on the few classes that use it. Usually domain classes are managed by the Facade for transmission but do not depend on it, so they don't need a fake implementation to be tested, like Entities do not need fake repositories for testing in general. Disadvantages It's hard to find a single disadvantage in the usage of this foundational pattern. The only problem I can think of is that remoting is not clearly expressed in the Api since all the networking code is hidden. Using the Facade carelessly could lead to very bad performance even with the precautions of a coarse interface which depends on domain objects, but it should be clear that if you're calling an external web site the speed of your scripts could be slower than when acting on in-memory objects... Example The sample implementation of a Remote Facade I'll present here is the Zend_Service_SlideShare component of Zend Framework: it hides interactions with slideshare.com under an object-oriented interface. It also has a domain model which contains business logic, via its Zend_Service_SlideShare_SlideShow class. This is one of the many Zend_Service classes which are currently being ported to Zend Framework 2. Here is the relevant code (the main Api methods plus a protected Factory Method and the constructor), taken from Zend Framework 1.x trunk. setApiKey($apikey) ->setSharedSecret($sharedSecret) ->setUserName($username) ->setPassword($password); $this->_httpclient = new Zend_Http_Client(); } ... /** * Uploads the specified Slide show the the server * * @param Zend_Service_SlideShare_SlideShow $ss The slide show object representing the slide show to upload * @param boolean $make_src_public Determines if the the slide show's source file is public or not upon upload * @return Zend_Service_SlideShare_SlideShow The passed Slide show object, with the new assigned ID provided */ public function uploadSlideShow(Zend_Service_SlideShare_SlideShow $ss, $make_src_public = true) { $timestamp = time(); $params = array('api_key' => $this->getApiKey(), 'ts' => $timestamp, 'hash' => sha1($this->getSharedSecret().$timestamp), 'username' => $this->getUserName(), 'password' => $this->getPassword(), 'slideshow_title' => $ss->getTitle()); $description = $ss->getDescription(); $tags = $ss->getTags(); $filename = $ss->getFilename(); if(!file_exists($filename) || !is_readable($filename)) { require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception("Specified Slideshow for upload not found or unreadable"); } if(!empty($description)) { $params['slideshow_description'] = $description; } else { $params['slideshow_description'] = ""; } if(!empty($tags)) { $tmp = array(); foreach($tags as $tag) { $tmp[] = "\"$tag\""; } $params['slideshow_tags'] = implode(' ', $tmp); } else { $params['slideshow_tags'] = ""; } $client = $this->getHttpClient(); $client->setUri(self::SERVICE_UPLOAD_URI); $client->setParameterPost($params); $client->setFileUpload($filename, "slideshow_srcfile"); require_once 'Zend/Http/Client/Exception.php'; try { $response = $client->request('POST'); } catch(Zend_Http_Client_Exception $e) { require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception("Service Request Failed: {$e->getMessage()}", 0, $e); } $sxe = simplexml_load_string($response->getBody()); if($sxe->getName() == "SlideShareServiceError") { $message = (string)$sxe->Message[0]; list($code, $error_str) = explode(':', $message); require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception(trim($error_str), $code); } if(!$sxe->getName() == "SlideShowUploaded") { require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception("Unknown XML Respons Received"); } $ss->setId((int)(string)$sxe->SlideShowID); return $ss; } /** * Retrieves a slide show's information based on slide show ID * * @param int $ss_id The slide show ID * @return Zend_Service_SlideShare_SlideShow the Slideshow object */ public function getSlideShow($ss_id) { $timestamp = time(); $params = array('api_key' => $this->getApiKey(), 'ts' => $timestamp, 'hash' => sha1($this->getSharedSecret().$timestamp), 'slideshow_id' => $ss_id); $cache = $this->getCacheObject(); $cache_key = md5("__zendslideshare_cache_$ss_id"); if(!$retval = $cache->load($cache_key)) { $client = $this->getHttpClient(); $client->setUri(self::SERVICE_GET_SHOW_URI); $client->setParameterPost($params); require_once 'Zend/Http/Client/Exception.php'; try { $response = $client->request('POST'); } catch(Zend_Http_Client_Exception $e) { require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception("Service Request Failed: {$e->getMessage()}", 0, $e); } $sxe = simplexml_load_string($response->getBody()); if($sxe->getName() == "SlideShareServiceError") { $message = (string)$sxe->Message[0]; list($code, $error_str) = explode(':', $message); require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception(trim($error_str), $code); } if(!$sxe->getName() == 'Slideshows') { require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception('Unknown XML Repsonse Received'); } $retval = $this->_slideShowNodeToObject(clone $sxe->Slideshow[0]); $cache->save($retval, $cache_key); } return $retval; } /** * Converts a SimpleXMLElement object representing a response from the service * into a Zend_Service_SlideShare_SlideShow object * * @param SimpleXMLElement $node The input XML from the slideshare.net service * @return Zend_Service_SlideShare_SlideShow The resulting object */ protected function _slideShowNodeToObject(SimpleXMLElement $node) { if($node->getName() == 'Slideshow') { $ss = new Zend_Service_SlideShare_SlideShow(); $ss->setId((string)$node->ID); $ss->setDescription((string)$node->Description); $ss->setEmbedCode((string)$node->EmbedCode); $ss->setNumViews((string)$node->Views); $ss->setPermaLink((string)$node->Permalink); $ss->setStatus((string)$node->Status); $ss->setStatusDescription((string)$node->StatusDescription); foreach(explode(",", (string)$node->Tags) as $tag) { if(!in_array($tag, $ss->getTags())) { $ss->addTag($tag); } } $ss->setThumbnailUrl((string)$node->Thumbnail); $ss->setTitle((string)$node->Title); $ss->setLocation((string)$node->Location); $ss->setTranscript((string)$node->Transcript); return $ss; } require_once 'Zend/Service/SlideShare/Exception.php'; throw new Zend_Service_SlideShare_Exception("Was not provided the expected XML Node for processing"); } }
August 10, 2010
by Giorgio Sironi
· 4,084 Views
article thumbnail
Unselect all Toggle Buttons of a Group
It’s summer and since I’m hearing more and more the sound of waves splashing instead of the sound of keyboards typing, I’m providing you with quick tricks instead of well-thought deep articles. This time, it’s about Swing. I’m doing Swing for a pet project… a lot. And I’m more of a web guy. So, I’m always butting my head against the wall trying to overcome problem people more experienced in Swing wouldn’t find a problem at all. This is good, since it teaches me another way too think (I as a web developer am not so much event-based, but it is coming to a change with frameworks such as Vaadin or standards like CDI). This said, my latest problem was the following. Most of the time, the toggle buttons are radio buttons: you programmatically select one radio before screen display and since all radios are in the same ButtonGroup, when the user selects one, it deselects the one previously selected. This is good but what if my default state would be that no radio be selected? In fact, to always select a radio means the default state should be displayed as a radio like the others. In my project, I want the default state to be no radio selected, but keep the classical behaviour where selecting a radio means deselecting the one before. Using Swing default classes, it doesn’t work, even if you replace the radio buttons by toggle buttons: when one is selected, it stays selected. Looking at the ButtonGroup code, one understands why: public void setSelected(ButtonModel m, boolean b) { if (b && m != null && m != selection) { ButtonModel oldSelection = selection; selection = m; if (oldSelection != null) { oldSelection.setSelected(false); } m.setSelected(true); } } The classical ButtonGroup only manages when the state goes from unselected to selected! This is cool when using radio buttons, not so with toggle buttons. In order to potentially have no selected buttons in your group, use the following class instead of ButtonGroup: public class NoneSelectedButtonGroup extends ButtonGroup { @Override public void setSelected(ButtonModel model, boolean selected) { if (selected) { super.setSelected(model, selected); } else { clearSelection(); } } } Note: clearSelection() is available only since Java 6 From http://blog.frankel.ch/unselect-all-toggle-buttons-of-a-group
August 10, 2010
by Nicolas Fränkel
· 30,253 Views
article thumbnail
Complex Line Command Syntaxes With JCommander
Complex tools such as git or svn understand a whole set of commands, each of which with their own specific syntax: git commit --amend -m "Bug fix" Words such as “commit” above are called “commands” in JCommander, and you can specify them by creating one arg object per command. For example, here is a the arg object for the commit command: @Parameters(separators = "=") public class CommandCommit { @Parameter(description = "Record changes to the repository") public List files; @Parameter(names = "--amend", description = "Amend") public Boolean amend = false; @Parameter(names = "--author") public String author; } And here is add: public class CommandAdd { @Parameter(description = "Add file contents to the index") public List patterns; @Parameter(names = "-i") public Boolean interactive = false; } Then you register these commands with your JCommander object. After the parsing phase, you call getParsedCommand() on your JCommander object, and based on the command that is returned, you know which arg object to inspect (you can still use a main arg object if you want to support options before the first command appears on the command line): // Options available before commands CommandMain cm = new CommandMain(); JCommander jc = new JCommander(cm); // Command: add CommandAdd add = new CommandAdd(); jc.addCommand("add", add); // Command: commit CommandCommit commit = new CommandCommit(); jc.addCommand("commit", commit); jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); Assert.assertTrue(cm.verbose); Assert.assertEquals(jc.getParsedCommand(), "commit"); Assert.assertTrue(commit.amend); Assert.assertEquals(commit.author, "cbeust"); Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); Support for complex commands is one of the new features available in JCommander 1.5. From http://beust.com/weblog/2010/08/08/complex-line-command-syntaxes-with-jcommander
August 9, 2010
by Cedric Beust
· 8,626 Views
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,225 Views
article thumbnail
Defect Driven Testing: Your Ticket Out the Door at Five O'Clock
Test automation is not a controversial topic in most circles. Even developers who don't write automated tests agree it's a great idea. They just don't have time to work on it very often. The idea of having your code verified automatically sounds great, but it never rises high enough on their priorities to ever get done, and that's a shame. Effective test automation is a remarkably effective way to keep your code clean, which helps you avoid those late night debugging sessions. It's my opinion that most developers don't get a good introduction to test automation. When most developers hear the phrase "test automation", they think only about Test Driven Development (TDD). Unfortunately, TDD is a difficult practice to learn. Don't misunderstand me though... TDD is a powerful technique. Developers that master it have put a valuable technique in their toolbox. It's just a difficult practice to pick up without help. I like to start developers with a different introduction to automated testing. Defect driven testing, or DDT. DDT is a fairly simple concept. When you find a bug, add a test. Why take this approach? First, no one can dispute the need for the test. If an issue was found, then it had been missed earlier. Perhaps the developer missed it and QA spotted it. Maybe it slipped past everyone and it was reported by your customer. Whenever it's reported, it needs to be fixed in a way that will prevent it from reappearing. Secondly, test automation is very expensive. It takes an investment of time from your company's most valuable resource. You. So how should you invest that time? As effectively as possible. When you're first starting your test automation work, you won't know where to focus your work. It takes time to understand how test automation can most effectively be used. Instead of trying to figure this out for yourself, let the problems in your product guide your work. DDT provides an extremely focused set of tests. Third, DDT is a gradual approach. TDD takes developers, who don't like being told where commas or brackets should be, and turns their entire development style upside down. While many, myself included, would argue that this needs to be done for many developers, I'm also very practical. If I lose your attention and you stop writing automated tests, then what have I accomplished? DDT lets you add another test every time you encounter a bug. This more gradual approach doesn't require an upfront investment. Instead you add to your test gradually. There's an additional trick you can use when using DDT. I call it testing jazz. Consider jazz to be variations on a theme, and apply that to your tests. Bugs tend to cluster, so never write one test to cover a single bug, then moving on. Instead stop and devote a bit more time. Instead of writing one test, try to add a dozen. Don't create completely different tests, but try to add minor variations to your original. If the bug is exposed by passing in a string with a single space in it (like "hello world"), then try to pass in "helloworld", "hello wor ld", " hello world ", "h e l l o w o r l d", and so on. Over time you'll find that DDT creates an extremely effective test suite that targets the most problematic parts of your code base. Run your defect driven tests inside of a continuous integration system and you'll find your code running more cleanly every day. Six months from now you'll look back and wonder why you ever had to work so much overtime.
August 4, 2010
by Jared Richardson
· 24,044 Views
article thumbnail
Faster Line Count With Grep Rather Than Wc
wc can be dramatically slower than desirable if all you want is a count of lines in a file (e.g., ~6 minutes vs. the grep technique shown below, which took 10 seconds). grep -c '\n' filename
August 4, 2010
by Albert Chou
· 8,987 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,161 Views
article thumbnail
Practical PHP Patterns: Application Controller
The Application Controller pattern is a subpattern used in Web implementations of the Model-View-Controller one. It prescribes to interpose an object between the HTTP-related controllers (like the Action Controllers and the Front Controller) and the rest of the MVC machine of an application, or to substitute them. This pattern involves an additional layer of complexity in an MVC implementation, but it is useful for modelling interactions as a (finite) state machine. By the way, when your project transition from a set of pages to a full featured web application, you can benefit from an Application Controller over the old page-based controllers. Dynamic pages are produced on the fly, and are not always available; they may have dependencies on other previous pages, or may not be accessible until other events have already happened. An Application Controller takes care of this business logic, while not intruding into the domain model responsibilities. User experience For example, in basic use cases the pages of an application are orthogonal and can be visited in any order. Other times the planned user experience requires a particular path to be followed from the user, and some pages can be visited and executed only upon particular events. They may be valid only in some cases, or incomplete until their dependencies are satisfied. Consider for example forms compiled in multiple steps, or application wizards. You'll never visit them out of order, and you must have some sort of mechanism to organize the single responses in a smooth flow. Application controllers centralize the logic relative to passing from one of the screens to another. Further logic should be encapsulated in the underlying domain objects, which the Application Controller drives with composition. State machine The interaction of every user with your application is in a certain state, and every state has predefined events that once happened may transition the application (for this particular user) to another state. Every transition is associated with a response, which is presented to the end user, with further orthogonal embellishment like a layout. Usually interactions and this ideal [finite] state machines have a session-like scope (related to the current user), but nothing prevents considering the whole application a state machine. Finite State Machines are the simplest model for these interactions, but they can be either more than one (one for each user, for each notification, for each form...) or a more complex, custom model can be used by the Application Controller. Implementation Application controllers live behind an Action Controller to analyze the requests further, or behind a Front Controller to substitute the classical Page Controllers it forwards to. They have references as collaborators both to domain classes (on which the events provoke method execution) and also to view classes, since they must render a response. Domain objects are juggled around by the Application Controller, created, stored and deleted from persistence. Even when using frameworks, view are usually scripts instead, driven by a generic View object that accepts the path as a parameter. Logic, and what to put in it Domain logic may scatter into the Application Controller. I usually prefer to keep as much as possible in the domain layer, but Application Controller is ideal for what we call application logic instead of domain logic: single interactions with the domain model. The boundary is not clearly defined here. That said, you can easily decide where to put a bit of business logic by knwoing that what you put in this application layer won't be reused: it is transaction-specific logic. What you push down in the domain layer will probably be reused throughout the application. For instance, you should put in an Application Controller: controller or view specific code, which doesn't fit into the domain layer particular use cases form objects management handling of multiple views infrastructure aspects. Multiple Application Controllers Multiple application controllers are the norm, unless your web application is fairly small. For example they are useful for dealing with different clients (mobile ones and ordinary browsers), since the user experience is likely to change between different devices (with more noisy or more optimized interactions). Another use case for multiple Application Controllers is obviously in assigning one to each member of a set of interactions (multiple forms, or wizards, or any kinds of processes to accomplish.) Example Here I'll present a small, high-level sample of an Application Controller that manages a form compilation in multiple steps. In Zend Framework, it can be thought of as homogeneous to Action Controllers (so that it can be easily put in an existing application's infrastructure.) It usually does not take advantage of automated mechanisms like the ViewRenderer plugin to achieve a finer control. In fact, it does not map to a single domain action or a single view: the view is chosen on the fly and the domain model is seen through a Facade. session->merge($this->request->getPost()); // this is our View change $step = $this->_request->getParam('step', 1); if ($step == self::LAST) { return $this->render('final.phtml'); } else { $this->view->form = $this->forms[$step]; } // the script is always the same but the form rendered changes $this->render('appcontroller.phtml'); } } You may go further in generalization, and code a generic Application Controller for this use case which can be fed metadata about the interaction (number of steps, Zend_Form objects, etc.)
August 3, 2010
by Giorgio Sironi
· 3,067 Views
article thumbnail
Achieving Immutability with Builder Design Pattern
Immutable classes define objects which, once created, never change their state.
August 3, 2010
by Shekhar Gulati
· 64,259 Views · 2 Likes
article thumbnail
512000 concurrent websockets with Groovy++ and Gretty
We are staying in front of new world - all major browsers either support already or plan to support in next major version HTML5 (not in scope of this article) & WebSockets (main subject of the article). In 6 to 9 months we as application developers will have in our hands extremely powerful client side tools to build new generation of the Web. But are we ready on server side? And if not, what the point in having powerful and reliable communication channel between browser and server and non-utilising it. In this article I will talk about my expirience of handling 512K concurrent websockets using Groovy++ & Gretty. Why 512K and not 1M? This is very fair question and my initial goal was to handle exactly 1M concurrent websockets on one machine. It seems that due my lack of knowledge of tuning TCP/IP on Linux I was not able to achieve more. I had enough free CPU power and a lot of free memory but after 524285 open connections (always the same number) the server stopped to accept new connections. The magical number 524285 is so close to 524288=512*1024 that I can guess (and only guess) that we deal either with some limitation of Linux setup or with something in settings of Amazon network infrastructure (where I run my tests) . So what was the experiment about? In general it was my way to estimate (or at least to have feeling) how many (virtual) hardware units do we need if we hope to handle A LOT of concurrent users. The server itself is very simple. It does the following: On HTTP request from a client it responds with text document containing Groovy script to be executed by client. It accepts and keeps websocket connections from clients and respond to every received message (just plain string) with the same string in upper case The client program (running on separate machine) request the server for a scenario and then compile and execute it. Why do we need this trick with sending script to client? Truly speaking we don't. When I started writing the application I had illusion that it will simplify deployment to many clients. In fact, it did not and I had rsync all clients with my development machine after recompilation anyway. The scenario itself is also very straight forward. Client program opens 64000 concurrent web socket connections and approximately every 25 seconds sends to the server short string (approximately 30 characters). So server need to handle around 20000 requests per second or around 600K/s traffic in and the same amount out. Someone can argue if such structure of traffic is realistic or not. I don't want to go in to deep dispute here as it simulates very well one of applications under development in my company. To emulate 512000 concurrent clients I used 8 machines and 1 machine was the server. All machine was of the same "m1.large" Amazon EC2 instances with 7.5GB memory and 2 virtual cores running Fedora 11. 2.5GB memory was used by Java heap (around 5K per connection but of course not including kernel structures) and total CPU utilization was under 30% The server is written on Groovy++ using Gretty, which is lightweight server based on brilliant Netty framework and developed as part of Groovy++ standard library. More information on both can be found at Groovy++ home Gretty is extremely lightweight and fully non-blocking event driven web server. Gretty itself is written on Groovy++ and fully utilize concurrency libabry. It is not servlet container or any other relative of JavaEE. Right now it supports only static files http requests (including modern /param1/param2 REST-like requests) web sockets (including long-polling emulation protocol for old browsers) Here is essentially the whole server code. Obviously it is statically typed Groovy++ code. GrettyServer server = [ webContexts: [ "/" : [ public: { get("/scenario") { response.text = """ .............. here is client scenario code ................... """ } websocket("/ws",[ onMessage: { msg -> socket.send(msg.toUpperCase()) }, onConnect: { socket.send("Welcome!") }, onDisconnect: { } ]) } ] ] ] server.start() I don't want to explain more than written in the code above because I really hope the code is self explaiining. I hope it was interesting. Get Gretty and Groovy++ a try and let us know what do you think. Till next time.
July 29, 2010
by Alex Tkachman
· 57,361 Views
article thumbnail
Profiling an application with Visual Studio – Concurrency
This is the last article in the profiling series, but not the least important. With the massive growth of multicore machines and the development of multi-threaded applications, an important need appeared - the need to trace the performance in order to create an effective multi-threaded environment, where threads are able to interact with the least impact on the machine performance. Visual Studio offers concurrency profiling tools, that allow developers to analyze data connected to thread interactions and activity. This time I am going to use the same sample application I’ve used in the first article, so that there will be a simulation of a multi-threaded environment with the same method being called multiple times from various threads.This will generate a set of results that can be used to realistically see the impact of a threaded application on the target computer performance, as well visuzlize the application performance indicators by themselves. Starting the process Once you start the Performance Wizard (via the Analyze menu), select the Concurrency method. To make the data set as descriptive as possible, I selected both options for collecting resource contention data and visualization of the behavior of a multithreaded application, since there are multiple experimental threads involved in my sample application. This will give us a detailed set of indicators regarding the application activity, CPU and thread-wise. IMPORTANT NOTE: Profiling your application using the Concurrency method requires elevated privileges for Visual Studio. If the profiling session is launched without elevated privileges, the following message will appear: I am using the default profiling settings, so I am going to leave the selections unchanged during the wizard setup. Click Next till you reach the final dialog. Make sure that the session will be launched once the wizard exits and click Finish. IMPORTANT NOTE: If you are running the session on an x64 machine, you might encounter this message if you have executive paging enabled. You can disable it by clicking on Yes (a restart will be required), however this is not a requirement for a sample session I am currently executing. Also, if you’ve had debugging symbols disabled, you might want to enable them by allowing debug symbols to be retrieved from Microsoft Symbol Servers: On a side note, if you aren’t aware of what debug symbols are, those are code indicators that basically allow tracking errors by allowing the debugger to read the code structures that generated the errors. This means that some variable or method names are exposed to the developer (or user) who attached the debugger to the process in test, in order for the person who debugs the code to directly see what the source of the error is. Analyzing the results Once the profiling session is complete, you will be presented with a completely different set of data compared to other methods. First of all, you will see that there are three additional views available: CPU Utilization, Threads and Cores. Before going into detailed review of what each of these represents, there is still some data available on the main report page (the Summary view). There is Most Contended Resources that shows resources with the most contentions. CONTENTIONS: Occur when a thread tries to acquire a lock held by another thread or resource (in this case, lock contentions). The less contentions there are in a process, the better. Note that the number of contentions here is quite high and this isn’t the best example. To avoid this, I could introduce a lock inside my testing method, so that the final indicators would look more like this: This is a much better-looking graph, since the number of contentions is reduced to a minimum. If you click on a handle, you are able to visually see the contentions separated into threads: Horizontal lines represent threads (recognized by their name or ID) and each block on a line is a contention. If you click on a thread, you are able to view the contentions only for that specific unit, as well as see the call stack for a contention – this might help you in determining where the possible source might be and where a lock should be in place. The Most Contended Threads view allows you to analyze the same data as the one shown above, only in the context of separate threads instead of resources. Since I am creating threads via ThreadPool, the thread names are automatically generated. This, however, can be changed if I would create the threads for each method call manually (via Thread instances). So, to show an example, here is how I modified the thread creation process: Program p = new Program(); string[] states = { "TX", "KS", "CA", "VA", "WA" }; foreach (string state in states) { Thread thread = new Thread(new ParameterizedThreadStart(p.Get)); thread.Name = state + " Thread"; thread.Start(state); } Here is what the profiling view shows now: Given that the threads are named, it is much easier to see which ones are contended the most. If you click on a thread, you see the contentions spread by resources (instead of threads, as in the previous view): The optimal usage of these views would be for determining the sections in code that require optimization. Also some interesting statistics are provided by the CPU Utilization view: Here I can see the application’s impact on the CPU, also being able to track the distribution of the load on multiple cores (in case those are present). Notice that not only the application performance is graphed here, but also the client system performance. In this case, it is easy to compare the application performance to the actual system activity that impacts the CPU load. Directly connected to this statistical indicator is the Cores view. This view displays the thread activity distribution among multiple logical cores (if those are present on the analyzed system). Although the number of cross-core context switches is pretty high, this is an expected indicator since there is a multitude of threads. Compared to an application without additional threads, you can see that the distribution is a bit different: Context switches generally have a negative impact on the application performance - the more switches, the more time it is allocated to actually perform the switches than real work. Therefore if there is very high number of context switches present, you might want to re-design the threaded architecture for your application. Last but not least, there is the Threads view that allows reviewing the thread performance and connected interactions. Each row here is displaying the thread activity. Various colors represent the type of thread activity, as set by the blocking call, that is also outlined in the Visible Timeline Profile box, where you can see the percentage for each operational type. For my application, most of the time is spent by threads for blocked in synchronization and memory management states. Please note that this not only applies to application-generated threads, but also to threads managed directly by the CLR. If you view the per thread summary, you will see that various threads have different operational sets: From this graph, it is clear that thread 5148 is blocked in a state that is considered as managing memory (for example, Paging) and is spending quite a lot of its functional time in that state, while other threads are mostly blocked on synchronization. Once you click on an operational type, you are able to review the blocking profile that reveals the calls that blocked the thread for the specific operation type. The current stack gives even more details about the given thread state: I can clearly see that it was the WaitForMultipleObjects API function that set the thread as in synchronization state. The unblocking stack, on the other side displays the opposite – the thread that unblocked the selected thread from the declared state and the associated calls. In the same Threads view developers are able to keep track of al file operations managed by the application. This includes not operations defined in the code, but also implied operations that are triggered by the CLR, like access to clr.dll or kernel32.dll.
July 28, 2010
by Denzel D.
· 13,702 Views
article thumbnail
Practical PHP Patterns: Transform View
The Transform View pattern involves a view mechanism that processes data structures one element at the time, and transforms them into an end-user representation like HTML. The Transform View usually takes the shape of a view class (or function) with these characterizing traits: its input is domain model data structure, or an infrastructure one that contains domain elements like a Collection class or an array. Its output is a presentational data structure like an HTML page or a page block. Recently, also XML or JSON have become output formats. In fact, the simplest example of a natively available Transform View in PHP is the function json_encode(): it takes an array of data as its argument, and boils it down to a JSON string. It is not capable of navigating a more complex object graph to render it, but the intent of this pattern is intact. Implementation The Transform View can act over multiple objects or a single one. Its main difference with a Template View is the mechanism for expressing the production of the response: the first is a series of operation to apply to domain elements, the second is the representation itself with several hooks where dynamic content is inserted. Concretely, we can think of the Template View as a PHP script, maybe driven by a generic class that renders it when a method is called; the Transform View is instead composed of programmatic (code): it can be a class or method. Since patterns may be rendered more complex at will, you can introduce implementations that use XSLT to generates HTML or other representations from an XML one (with the XSL extension); but you still have to get the original XML one, maybe by introspection of the domain structures. XSL essentially it is a way to define transformations declaratively, mixing the two approaches and producing a portable description of the transformation which data undergo; many times you're better off by simply defining your transformation in code and cover (or drive) it with tests. A trade-off is that you can always use this pattern only for some parts of the page (when the output is oriented to humans and not to machines), as in the Two Step View pattern which we'll see in the next article. These particular Transform Views are a subset of View Helpers, which take domain objects as their input. Data access Infrastructure classes are usually navigable via their own Api, which is very rich. Domain classes instead are focused on modelling and information hiding instead of navigability, and this may raise an issue for displaying them through every kind of view. When a set of properties is exposed by a domain object directly or via accessors, we have two choices in building a Transform View: the object can be introspected dynamically, by using reflection or other metadata (e.g. annotations) to list public properties or getters. more specific Transform Views can be written which are designed only for usage on a particular class. They will present a strong coupling with the original domain data structure but also a finer control on the presentation layer. Advantages An obvious advantage of this pattern is code reuse when the implementation is generic enough to be valid for more than one class. A more subtle advantage may be the homogeneity of the different Transform Views objects. For example you may end up swapping different Transform Views or chaining them, or relying on polymorphism to select the right rendering for a use case. In general, promoting the View mechanism to an object yields the advantages of object-orientation (inheritance, polymorphism, encapsulation), and these pros are more easily perceived with a logic-intensive approach like a Transform View. Disadvantages The issues of this pattern come up with markup-intensive pages which contain a lot of semi-static HTML code, or of another presentational format. Such pages are often much easier to produce with a Template View when dynamic bindings are submerged. Even XML sometimes it's easier to print out tag by tag with Template View instead of managing a DOM implementation. Examples The sample code of this article regards using reflection to gather getters of a domain object and display it. Of course it is not a complete implementation (it does not cover relationships), but in its limited scope is quite useful. As always, you may prefer more specific incarnation of the pattern, but they will have to be kept in sync with the related domain model and constitute a larger code footprint. However, they will give you more freedom to tune the result in specific cases. _name = $name; } public function getName() { return $this->_name; } public function setCity($city) { $this->_city = $city; } public function getCity() { return $this->_city; } } class TransformView { /** * Iterates through getters and calls them to display $entity. * @param object $entity * @return string */ public function display($entity) { $result = "\n"; $rc = new ReflectionClass(get_class($entity)); foreach ($rc->getMethods() as $method) { $methodName = $method->getName(); if (strstr($methodName, 'get') == $methodName) { $field = str_replace('get', '', $methodName); $result .= "\n"; $result .= "{$field}\n"; $result .= "" . $entity->$methodName() . "\n"; $result .= "\n"; } } $result .= "\n"; return $result; } } $user = new User('Giorgio'); $user->setCity('Como'); $view = new TransformView(); echo $view->display($user);
July 27, 2010
by Giorgio Sironi
· 4,690 Views
article thumbnail
Remove Empty Nodes From Dom Document
// Snippit to remove an empty node from the document. // Node node contains the node (or whole DOM document) from which you want to remove. // String nameToRemove is the name of the Node you want to remove. private static void removeEmptyNodes(Node node, String nameToRemove) { NodeList nodeList = node.getChildNodes(); for(int i=0; i < nodeList.getLength(); i++){ Node childNode = nodeList.item(i); String nodeName = childNode.getNodeName(); if(nodeName.equals(nameToRemove) && childNode.getTextContent().equals("")){ childNode.getParentNode().removeChild(childNode); i--; } removeEmptyNodes(childNode, nameToRemove); } }
July 27, 2010
by Egbert Minnaar
· 6,168 Views
  • Previous
  • ...
  • 1598
  • 1599
  • 1600
  • 1601
  • 1602
  • 1603
  • 1604
  • 1605
  • 1606
  • 1607
  • ...
  • 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
×