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

Events

View Events Video Library

The Latest Languages Topics

article thumbnail
Groovy Goodness: Find Non-Null Results After Transformation in a Collection
Since Groovy 1.8.1 we can use the findResults method and pass a closure to transform elements in a collection and get all non-null elements after transformation. We also have the findResult method to return the first non-null transformed element, but with findResults we get all non-null elements. def stuff = ['Groovy', 'Griffon', 'Gradle', 'Spock', 'Grails', 'GContracts'] def stuffResult = stuff.findResults { it.size() == 6 ? "$it has 6 characters" : null } assert stuffResult == ['Groovy has 6 characters', 'Gradle has 6 characters', 'Grails has 6 characters'] def map = [what: 'Finish blog post', priority: 1, when: new Date()] def mapResult = map.findResults { it.value instanceof String ? "Key $it.key is of type String" : null } assert mapResult == ['Key what is of type String'] From http://mrhaki.blogspot.com/2011/11/groovy-goodness-find-non-null-results.html
November 10, 2011
by Hubert Klein Ikkink
· 6,786 Views
article thumbnail
Dependency Injection for Dummies
Dependency injection is a very simple concept: if you have an object that interacts with other objects the responsibility of finding a reference to those objects at run time is moved outside of the object itself. What does it mean for an object to "interact" with other objects? Generally it means invoking methods or reading properties from those objects. So if we have a class A that invokes method Calculate on class B, we can say that A interacts with B. In the following example we show class A interacting with class B. We can equally say that A depends on class B to fulfill a responsibility. In this case, it not only invokes its method Calculate but it also creates a new instance of that class. class A { private B _b; public A { _b = new B(); } public int SomeMethod() { return (_b.Calculate() * 2); } } In the following example, on the other side, the responsibility of getting a reference to an implementation of a class of type B is moved outside of A: class A { private _b = B; public A(B b) { _b = b; } public int SomeMethod() { return _(b.Calculate * 2); } } In this case we say that a dependency (B) has been injected into A, via the constructor. Of course, you can also inject dependencies via a property (or even a regular method), like in the following example: class A { private _b = B; public B B { get { return _b; } set { _b = value; } } public int SomeMethod() { if (_b != null) return _b.RetrieveValue() * 2;} else // HANDLE THIS ERROR CASE return -1; } } So this is all there is about dependency injection. Everything else just builds on this core concept. Like for example Inversion Of Control (IoC) tools which helps you wiring together your objects at run time, injecting all dependencies as needed. So what exactly is Inversion of Control and how does it relate to Dependency Injection (DI)? I like to associate IoC to the Hollywood Principle: "Don't call us, we'll call you". IoC is a design principle where reusable generic code controls the execution of problem-specific code: it is a characteristic of many frameworks, where the application is built extending or customizing a common skeleton; you put your own classes at specific points and the framework will call you when needed. You can use an IoC container as a framework to perform Dependency Injection on your behalf: you tell the container which are the concrete implementation classes for your dependencies and the container will make sure that your constructors or setters will be called with the right objects. Therefore, IoC containers are just a convenience to simplify how dependency injection is handled. But even if you don't use one you could still manually perform dependency injection. (If you want to have a look at how an IoC container works you can jump to my mini tutorial on Ninject). Why is the concept of dependency injection important? Because by applying it, you simplify your design (separating the responsibility of using an object from the responsibility of using the object) and your code becomes much easier to test, since you can mock out the dependencies substituting them with fake (stub) objects. But that is the subject for another post.
November 8, 2011
by Stefano Ricciardi
· 11,167 Views · 28 Likes
article thumbnail
Selectable Shapes Part 2: Resizable, Movable Shapes on HTML5 Canvas
In the first tutorial I showed how to create a basic data structure for shapes on an HTML5 canvas and how to make them selectable, draggable, and movable. In this second part we’ll be reorganizing the code a little bit and adding selection handles so we can resize our Canvas objects. The finished canvas will look like this: Click to select a box. Click on a selection handle to resize. Double click to add new boxes. This article’s code is written primarily to be easy to understand. It isn’t optimized for performance because a little bit of the drawing is set up so that more complex shapes can easily be added in the future. In this tutorial we will add: Code for drawing the eight boxes that make up the selection handles Some small adjustments to the draw code Code to be run on every mouse move event Code for changing the mouse cursor when it is over a selection handle Code for resizing Drawing the selection handles The eight selection handles are unique in that each one allows you to resize an object in a different way. For instance clicking on the top-middle one will only let you make it taller or shorter, but the top-right one will allow you to make it taller, shorter, as well as more wide or narrow. Like all decidedly unique things, we’ll want to keep track of them. // New, holds the 8 tiny boxes that will be our selection handles // the selection handles will be in this order: // 0 1 2 // 3 4 // 5 6 7 var selectionHandles = []; Previously we had the variables mySelColor and mySelWidth for the selection’s color and width. Now we also add variables for selection box color and size: var mySelBoxColor = 'darkred'; // New for selection boxes var mySelBoxSize = 6; Draw’s new home Draw is still its own function but most of the code has been moved out of it. We’re going to make our Box class start to look a little more classy by letting boxes draw themselves. If you haven’t seen this syntax before, it adds the draw function to all instances of the Box class, creating a someBox.draw() we can call on boxes. To clear up confusion, our old draw loop will be renamed mainDraw. // New methods on the Box class Box.prototype = { // we used to have a solo draw function // but now each box is responsible for its own drawing // draw() will call this with the normal canvas // myDown will call this with the ghost canvas with 'black' draw: function(context, optionalColor) { // ... (draw code) ... } // end draw } This draw code is lifted from the old draw method but with a few additions for the selection handles. We check to see if the current box is selected, and if it is, we draw the selection outline as well as the eight selection boxes, their places based on the selected object’s bounds. In the Init() function we need to add the selectionHandles[] initialization as well as a new event. In the past, myMove was only activated if you pressed down with the mouse, and became deactivated as soon as the mouse was released. Now we need myMove to be active all the time. // new code in init() canvas.onmousemove = myMove; // set up the selection handle boxes for (var i = 0; i < 8; i ++) { var rect = new Box; selectionHandles.push(rect); } Our new main draw loop is now very slimmed down: function mainDraw() { if (canvasValid == false) { clear(ctx); // draw all boxes var l = boxes.length; for (var i = 0; i < l; i++) { boxes[i].draw(ctx); // we used to call drawshape, but now each box draws itself } canvasValid = true; } } Doing this reorganization isn’t too important now, but it will be useful later on if we have many different types of objects draw themselves. After all, rectangles and (for instance) lines are not drawn in the same way, so if we can put all the custom drawing code in the object’s own class we can keep things better organized. myMove revisited Before I talk about myMove lets take a look at two new variables added to the top of our code that signal whether or not a box is being dragged and if so, from which selection handle. var isResizeDrag = false; var expectResize = -1; // New, will save the # of the selection handle if the mouse is over one. isResizeDrag seems simple enough, it works almost identically to isDrag. expectResize will be a number between 0 and 7 to indicate which selection handle is currently active. If none is active (the default), we’ll set it to -1. In most programs that have selection handles (such as the edges of your browser) it is nice to have the mouse cursor change to show that an action can be performed. To do this we are going to have to ask where the mouse is located all the time and see if it is over one of our eight selection handles. Remember that above we made myMove active all of the time and Now we have to add code to it: // Happens when the mouse is moving inside the canvas function myMove(e){ if (isDrag) { getMouse(e); mySel.x = mx - offsetx; mySel.y = my - offsety; // something is changing position so we better invalidate the canvas! invalidate(); } else if (isResizeDrag) { // ... new code to talk about later. } getMouse(e); // if there's a selection see if we grabbed one of the selection handles if (mySel !== null && !isResizeDrag) { for (var i = 0; i < 8; i++) { // 0 1 2 // 3 4 // 5 6 7 var cur = selectionHandles[i]; // we dont need to use the ghost context because // selection handles will always be rectangles if (mx >= cur.x && mx <= cur.x + mySelBoxSize && my >= cur.y && my <= cur.y + mySelBoxSize) { // we found one! expectResize = i; invalidate(); switch (i) { case 0: this.style.cursor='nw-resize'; break; case 1: this.style.cursor='n-resize'; break; case 2: this.style.cursor='ne-resize'; break; case 3: this.style.cursor='w-resize'; break; case 4: this.style.cursor='e-resize'; break; case 5: this.style.cursor='sw-resize'; break; case 6: this.style.cursor='s-resize'; break; case 7: this.style.cursor='se-resize'; break; } return; } } // not over a selection box, return to normal isResizeDrag = false; expectResize = -1; this.style.cursor='auto'; } So if there is something selected and we are not already dragging, we will execute some code to see if the mouse position is over one of the selection boxes. If it is, give the mouse cursor the correct arrow. If the mouse isn’t over a selection box, make sure we change it back to the normal pointer. You’ll also notice that at the start, after “if (isDrag)” we have a new test, “else if (isResizeDrag).” isResizeDrag becomes true if two conditions are met: expectResize is set to one of the selection handle numbers (is not -1) we have pressed down the mouse In other words, it only happens if the mouse is over a selection handle and has been pressed. We add a tiny bit of code to myDown to make this work. // Happens when the mouse is clicked in the canvas function myDown(e){ getMouse(e); //we are over a selection box if (expectResize !== -1) { isResizeDrag = true; return; } // ... the rest of myDown } Anyway, getting back to myMove. We are looking for the “else if (isResizeDrag)” to see what happens when this is true. function myMove(e){ if (isDrag) { // ... } else if (isResizeDrag) { // time ro resize! var oldx = mySel.x; var oldy = mySel.y; // 0 1 2 // 3 4 // 5 6 7 switch (expectResize) { case 0: mySel.x = mx; mySel.y = my; mySel.w += oldx - mx; mySel.h += oldy - my; break; case 1: mySel.y = my; mySel.h += oldy - my; break; case 2: mySel.y = my; mySel.w = mx - oldx; mySel.h += oldy - my; break; case 3: mySel.x = mx; mySel.w += oldx - mx; break; case 4: mySel.w = mx - oldx; break; case 5: mySel.x = mx; mySel.w += oldx - mx; mySel.h = my - oldy; break; case 6: mySel.h = my - oldy; break; case 7: mySel.w = mx - oldx; mySel.h = my - oldy; break; } invalidate(); } // ... rest of myMove } We see a bunch of arithmetic dealing with precisely how each handle will resize the box. Handle #6 is middle-bottom, so it only resizes the height of the box. Handle #1, on the other hand, is the middle top. It has to resize both the Y-axis co-ordinate as well as the height. If #1 only changed the Y-axis, then dragging it upwards would just look like the entire box is being dragged upwards. If it just resized the height, the top of the box would stay in the same position and we certainly don’t want that if the top is what we intended to move! That’s pretty much everything. Try it out yourself above or see the demo and download the full source on this page. So that wasn’t too bad. A few long chunks were added but not because of complexity, just because each of the eight selection handles is uniquely placed and does a unique resizing task. If you would like to see this code enhanced in future posts (or have any fixes), let me know how in the comments.
November 7, 2011
by Simon Sarris
· 10,928 Views
article thumbnail
Using JSR-250's @PostConstruct Annotation to Replace Spring's InitializingBean
JSR-250 aka Common Annotations for the Java Platform was introduced as part of Java EE 5 an is usually used to annotated EJB3s. What’s not so well known is that Spring has supported three of the annotations since version 2.5. The annotations supported are: @PostContruct - This annotation is applied to a method to indicate that it should be invoked after all dependency injection is complete. @PreDestroy - This is applied to a method to indicate that it should be invoked before the bean is removed from the Spring context, i.e. just before it’s destroyed. @Resource - This duplicates the functionality of @Autowired combined with @Qualifier as you get the additional benefit of being able to name which bean you’re injecting, without the need for two annotations. This blog takes a quick look at the first annotation in the list @PostConstruct, demonstrating how it’s applied and comparing it to the equivalent InitializingBean interface. InitializingBean has one method, afterPropertiesSet(), and it does what it says on the tin. The afterPropertiesSet() method is called after Spring has completed wiring things together. The code snippet below demonstrates how InitializingBean is implemented. public class ImplementInitializingBean implements InitializingBean { private boolean result; public String businessMethod() { System.out.println("Inside - ImplementInitializingBean"); return "InitializingBeanResult"; } /** * This is part of the InitializingBean interface - called after the bean has been set-up. Use this method to check that the * bean has been set-up correctly. Also so use it to configure external resources such as databases etc. */ @Override public void afterPropertiesSet() throws Exception { result = true; System.out.println("In aferPropertiesSet() - check the set-up of the bean."); } public boolean getResult() { return result; } } Annotations are supposed to make life easier, but do they in this case? Firstly to use the @PostConstruct annotation you need to include the following dependencies your POM file: org.springframework spring-web ${spring.version} org.springframework spring-webmvc ${spring.version} javax.servlet servlet-api 2.5 provided You also need to tell Spring to use annotations by adding the following to your Spring config file: Having setup the environment, you can now use the @PostConstruct annotation. @Component public class ImplementPostConstruct implements MyPostConstructExample { private boolean result; @Override public String businessMethod() { System.out.println("Inside - ImplementPostConstruct"); return "ImplementPostConstruct"; } /** * @PostConstruct means that this is called after the bean has been set-up. * Use this method to check that the bean has been set-up * correctly. Also so use it to configure external resources * such as databases etc. */ @PostConstruct public void postConstruct() { result = true; System.out .println("In postConstruct() - check the set-up of the bean."); } @Override public boolean getResult() { return result; } } This is tested using the JUnit Test below: @Test public void postConstructTest() { instance1 = ctx.getBean(ImplementPostConstruct.class); String result = instance1.businessMethod(); assertEquals("ImplementPostConstruct", result); boolean var = instance1.getResult(); assertTrue(var); } The two clumps of code above do the same thing with postConstruct() being called at the same time asafterPropertiesSet(). It's easy to see that annotations look neater, but they are also more difficult to setup? I'll let you be the judge of that. Finally, one last thing to note, the JSR-250 annotations provide useful core functionality, but are part of Spring's MVC project warranting a possible superfluous dependency on the javax.servlet-api jar, so perhaps a little refactoring may be a good idea at some point. From http://www.captaindebug.com/2011/11/using-jsr-250s-postconstruct-annotation.html
November 6, 2011
by Roger Hughes
· 44,888 Views · 1 Like
article thumbnail
Creating a backup in Team Foundation Server 2010 using the Power Tools
over the last few years the product team has been putting their finishing touches on a backup module for the team foundation server administration console. why you might ask do you need another way to backup? surely you can just backup the bits? well, you could, but as tfs has a lot of moving parts it can get very complicated to creating a backup . required permissions identify databases create tables in databases create a stored procedure for marking tables create a stored procedure for marking all tables at once create a stored procedure to automatically mark tables create a scheduled job to run the table-marking procedure create a maintenance plan for full backups create a maintenance plan for differential backups create a maintenance plan for transaction backups back up additional lab management components -from “back up team foundation server” on msdn there are a heck of a lot of databases that, depending on your environment, might be spread over your entire network. figure: deployment topologies (where is my data?) from msdn so, how is this problem solved. well the tfs team have create a tool to create all of the backups and all of the job as well as managing the backup location for you. this sounds fantastic, but how about in practice. was it really that easy? well….not really…here is the extra stuff i found out: your account must own the share owning the folder does not cut it (see error #1- tf254027). sql must be running under a domain account or network service sql must also have permission to the share, and the validation will get confused if you use “localsystem” instead of network service or a domain account (see error #2- tf254027) the account running sql must have permission to create spn’s the account that is used for sql must be able to both see and create service principal names in active directory (see error #3: terminating your tfs server). once you learn how to google without keywords and read your servers mind you will have a nice backup system going… error #1- tf254027 i initially got an error because the accounts did not really have full control over the target location. this is a problem with the share. although i have full permission for \\fileserver1\share\tfsbackups it is just a folder under the \\fileserver1\share\ location and i do not have permission to change the sharing settings there. figure: tf254027 is caused by permission issues [info @16:36:34.342] granting account root_company\tfssqlbox$ permission on folder \\fileserver1\share\tfsbackups [info @16:36:34.348] system.unauthorizedaccessexception: attempted to perform an unauthorized operation. at system.security.accesscontrol.win32.setsecurityinfo(resourcetype type, string name, safehandle handle, securityinfos securityinformation, securityidentifier owner, securityidentifier group, genericacl sacl, genericacl dacl) at system.security.accesscontrol.nativeobjectsecurity.persist(string name, safehandle handle, accesscontrolsections includesections, object exceptioncontext) at system.security.accesscontrol.filesystemsecurity.persist(string fullpath) at microsoft.teamfoundation.powertools.admin.helpers.filehelper.grantfolderpermission(string account, string path) [info @16:36:34.350] granting account root_company\tfs.services permission on folder \\fileserver1\share\tfsbackups [info @16:36:34.352] system.unauthorizedaccessexception: attempted to perform an unauthorized operation. at system.security.accesscontrol.win32.setsecurityinfo(resourcetype type, string name, safehandle handle, securityinfos securityinformation, securityidentifier owner, securityidentifier group, genericacl sacl, genericacl dacl) at system.security.accesscontrol.nativeobjectsecurity.persist(string name, safehandle handle, accesscontrolsections includesections, object exceptioncontext) at system.security.accesscontrol.filesystemsecurity.persist(string fullpath) at microsoft.teamfoundation.powertools.admin.helpers.filehelper.grantfolderpermission(string account, string path) [error @16:36:34.352] granting permission to account root_company\tfssqlbox$ on path \\fileserver1\share\tfsbackups failed figure: the log files get to the root of the problem, but not the reason after much messing around i have found that you can’t use a sub-folder of a share that you do not have permission for. you require permission to the share itself to apply permissions. error #2- tf254027 lets try this again with a share that we control. i will create a backup share on the tfs server and at least then i control then permissions. figure: the next error looks the same, but it is subtly different [info @18:12:05.813] "verify: grant backup plan permissions\root\verifybackuppathpermissionsgrantedsuccessfully(verifybackuppathpermissionsgrantedsuccessfully): exiting verification with state completed and result success" [info @18:12:05.813] verify: grant backup plan permissions\root\verifydummybackupcreation(verifytestbackupcreatedsuccessfully): starting verification [info @18:12:05.813] verify test backup created successfully [info @18:12:05.813] starting creating backup test validation [error @18:12:06.132] microsoft.sqlserver.management.smo.failedoperationexception: backup failed for server 'sqlserver1'. ---> microsoft.sqlserver.management.common.executionfailureexception: an exception occurred while executing a transact-sql statement or batch. ---> system.data.sqlclient.sqlexception: cannot open backup device '\\tfsserver1\tfsbackup\temp_20111104111205.bak'. operating system error 5(access is denied.). backup database is terminating abnormally. at microsoft.sqlserver.management.common.connectionmanager.executetsql(executetsqlaction action, object execobject, dataset filldataset, boolean catchexception) at microsoft.sqlserver.management.common.serverconnection.executenonquery(string sqlcommand, executiontypes executiontype) --- end of inner exception stack trace --- at microsoft.sqlserver.management.common.serverconnection.executenonquery(string sqlcommand, executiontypes executiontype) at microsoft.sqlserver.management.common.serverconnection.executenonquery(stringcollection sqlcommands, executiontypes executiontype) at microsoft.sqlserver.management.smo.executionmanager.executenonquery(stringcollection queries) at microsoft.sqlserver.management.smo.backuprestorebase.executesql(server server, stringcollection queries) at microsoft.sqlserver.management.smo.backup.sqlbackup(server srv) --- end of inner exception stack trace --- at microsoft.sqlserver.management.smo.backup.sqlbackup(server srv) at microsoft.teamfoundation.powertools.admin.helpers.backupfactory.testbackupcreation(string path) [error @18:12:06.184] !verify error!: account root_comapny\martin.hinshelwood failed to create backups using path \\tfsserver1\tfsbackup [info @18:12:06.184] "verify: grant backup plan permissions\root\verifydummybackupcreation(verifytestbackupcreatedsuccessfully): exiting verification with state completed and result error" [info @18:12:06.184] !verify result!: 5 completed, 0 skipped: 4 success, 1 errors, 0 warnings [info @18:12:06.197] verify: backup tasks verifications(vcontainer): starting verification [info @18:12:06.197] a generic container node that does not contribute to results [info @18:12:06.197] "verify: backup tasks verifications(vcontainer): exiting verification with state ignore and result ignore" [info @18:12:06.197] verify: backup tasks verifications\root(vcontainer): starting verification [info @18:12:06.197] a generic container node that does not contribute to results [info @18:12:06.197] "verify: backup tasks verifications\root(vcontainer): exiting verification with state ignore and result ignore" [info @18:12:06.197] verify: backup tasks verifications\root\verifydummybackupcreation(verifytestbackupcreatedsuccessfully): starting verification [info @18:12:06.197] verify test backup created successfully [info @18:12:06.197] starting creating backup test validation [error @18:12:06.389] microsoft.sqlserver.management.smo.failedoperationexception: backup failed for server sqlserver1'. ---> microsoft.sqlserver.management.common.executionfailureexception: an exception occurred while executing a transact-sql statement or batch. ---> system.data.sqlclient.sqlexception: cannot open backup device '\\tfsserver1\tfsbackup\temp_20111104111206.bak'. operating system error 5(access is denied.). backup database is terminating abnormally. at microsoft.sqlserver.management.common.connectionmanager.executetsql(executetsqlaction action, object execobject, dataset filldataset, boolean catchexception) at microsoft.sqlserver.management.common.serverconnection.executenonquery(string sqlcommand, executiontypes executiontype) --- end of inner exception stack trace --- at microsoft.sqlserver.management.common.serverconnection.executenonquery(string sqlcommand, executiontypes executiontype) at microsoft.sqlserver.management.common.serverconnection.executenonquery(stringcollection sqlcommands, executiontypes executiontype) at microsoft.sqlserver.management.smo.executionmanager.executenonquery(stringcollection queries) at microsoft.sqlserver.management.smo.backuprestorebase.executesql(server server, stringcollection queries) at microsoft.sqlserver.management.smo.backup.sqlbackup(server srv) --- end of inner exception stack trace --- at microsoft.sqlserver.management.smo.backup.sqlbackup(server srv) at microsoft.teamfoundation.powertools.admin.helpers.backupfactory.testbackupcreation(string path) figure: this time the error is lying and is from sql not locally as it implies it looks like the problem is that sql server can’t write to that folder, but i can and the machine account can. lets try this from the sql server itself, and with a native backup. figure: sql server can’t write to that location dam… so even a native sql backup can’t write to this location. title: microsoft sql server management studio ------------------------------ backup failed for server 'sqlserver1'. (microsoft.sqlserver.smoextended) for help, click: http://go.microsoft.com/fwlink?prodname=microsoft+sql+server&prodver=10.50.2500.0+((kj_pcu_main).110617-0038+)&evtsrc=microsoft.sqlserver.management.smo.exceptiontemplates.failedoperationexceptiontext&evtid=backup+server&linkid=20476 ------------------------------ additional information: system.data.sqlclient.sqlerror: cannot open backup device '\\tfsserver1\tfsbackup\moo.bak'. operating system error 5(access is denied.). (microsoft.sqlserver.smo) for help, click: http://go.microsoft.com/fwlink?prodname=microsoft+sql+server&prodver=10.50.2500.0+((kj_pcu_main).110617-0038+)&linkid=20476 ------------------------------ buttons: ok ------------------------------ figure: sql server errors suck even more as it turns out, sql server is running under “localserivce” which is not authenticating against our share. so we need to change the service that tfs runs under. error #3: terminating your tfs server as we should always use the sql server configuration manager to change these things i fired it up and since i already have a domain account for running tfs under i decided to use that one. figure: this is easy when you apply it will ask you to restart sql, but it should be all complete. lets check tfs and make sure that everything is running… figure: omg! what just happened! oh shit: i think i just broke tfs. why can’t tfs connect? lets try the sql management studio and see. figure: what is a sspi? this does not look good… after i have hastily changed the service account back to the original value and made use that his fixed tfs i wanted to also figure out why it broke. usually i would just ask shad (one of my extremely technical colleagues) but alas he is on his honeymoon. some googling turned up an spn issue. the account that sql runs under must be able to both read and write service principal names for itself in active directory. this can be set, but only be a domain admin. dynamically set spn’s for sql service accounts so lets go with network service instead. if we change the account that sql server runs under to “network service” then i can add permission for “root_company\sqlserver1$” to my share and get it working. yes, servers have ad accounts as well.
November 5, 2011
by Martin Hinshelwood
· 10,029 Views
article thumbnail
Groovy: Creating an Interface Stub and Intercepting All Calls to It
It’s sometimes useful for unit testing to be able to create a simple no-op stub of an interface the class under test depends upon and to intercept all calls to the stub, for example to remember all the calls and parameters so that you can later verify that they’ve been invoked as expected. Often you’d use something like Mockito and its verify method but if you’re writing unit tests in Groovy as I recommend then there is a simpler and in a way a more powerful alternative. Solution 1 – When Calling the Stub From a Groovy Object @Before public void setUp() { this.collectedCalls = [] // The following works when a method on the listener is called from Groovy but not from Java: this.listener = {} as PageNodeListener listener.metaClass.invokeMethod = { name, args -> collectedCalls << new Call(method: name, args: args) // Call is a simple structure class } } @Test public void listener_stub_should_report_all_calls_to_it() throws Exception { listener.fileEntered("fileName.dummy") assert collectedCalls.find { it.equals(new Call(method: "fileEntered", args: ["fileName.dummy"]))} } Notes: 5: {} as PageNodeListener uses Groovy’s closure coercion – basically it creates an implementation of the interface which uses the (empty) closure whenever any method is called (we could capture its arguments but not the method name via {Object[] args -> /*...*/} as PageNodeListener) 6-7: We then specify an interceptor method that should be invoked whenever any method is called on the instance Groovy makes it very easy to create beans like Call with equals, toString etc. Beware that using a coerced closure as an interface implementation works only for methods that are either void or can return null (which is the return value of an empty closure, when invoked). Other methods will throw an NPE: def list = {} as java.util.List list.clear() // OK, void list.get(0) // OK, returns null list.isEmpty() // NullPointerException at $Proxy4.isEmpty Solution 2 – When Calling the Stub From a Java Object The solution 1 is small and elegant but for me it hasn’t worked when the stub was invoked by a Java object (a clarification of why that happened would be welcome). Fortunately Christoph Metzendorf proposed a solution at StackOverflow (adjusted): @Before public void setUp() { this.collectedCalls = [] PageNodeListener listener = createListenerLoggingCallsInto(collectedCalls) this.parser = new MyFaces21ValidatingFaceletsParser(TEST_WEBROOT, listener) } def createListenerLoggingCallsInto(collectedCalls) { def map = [:] PageNodeListener.class.methods.each() { method -> map."$method.name" = { Object[] args -> collectedCalls << new Call(method.name, args) } } return map.asType(PageNodeListener.class) } @Test public void should_notify_about_file_entered() throws Exception { parser.validateExpressionsInView(toUrl("empty.xhtml"), "/empty.xhtml") assert collectedCalls.find { it.equals(new Call(method: "fileEntered", args: ["/empty.xhtml"]))} } Notes: 12-13: We create a map containing {method name} -> {closure} for each of the interface’s method 17: The map is then coerced to the interface (the same as someMap as PageNodeListener). Notice that if it didn’t contain an entry for a method then it would throw a NullPointerException if the method was invoked on the stub. Notice that this version is more flexible than the Groovy-only one because we have full access to java.lang.reflect.Method when we create the map and thus can adjust the return value of the method closure w.r.t. what is expected. Thus it’s possible to stub any interface, even if it has methods returning primitive types. Conclusion This is a nice and simple way to stub an interface with methods that are void or return non-primitive values and collect all calls to the stub for a verification. If your requirements differ then you might be better of with a different type of mocking in Groovy or with a true mocking library. Additional Information Groovy version: 1.8.2, Java: 6.0. See the full source code in the JSF EL Validator’s NotifyingCompilationManagerTest.groovy. From http://theholyjava.wordpress.com/2011/11/02/groovy-creating-interface-stub-and-intercepting-all-calls-to-it/
November 4, 2011
by Jakub Holý
· 6,545 Views
article thumbnail
Building a RESTful Web Service with Spring 3.1 and Java based Configuration, part 2
1. Overview This is the second of a series of posts about setting up a RESTful web service using Spring 3.1 with Java based configuration. The first post of the series focused on bootstrapping the web application; this post will focus on setting up REST in Spring, the Controller and HTTP response codes, configuration of payload marshalling and content negotiation. 2. Understanding REST in Spring The Spring framework supports 2 ways of creating RESTful services: using MVC with ModelAndView using HTTP message converters The ModelAndView approach is older and much better documented, but also more verbose and configuration heavy. It tries to shoehorn the REST paradigm into the old model, which is not without problems. The Spring team understood this and provided first-class REST support starting with Spring 3.0. The new approach, based on HttpMessageConverter and annotations, is much more lightweight and easy to implement. Configuration is minimal and it provides sensible defaults for what you would expect from a RESTful service. It is however newer and a a bit on the light side concerning documentation; what’s more, the Spring reference doesn’t go out of it’s way to make the distinction and the tradeoffs between the two approaches as clear as they should be. Nevertheless, this is the way RESTful services should be build after Spring 3.0. 3. The Java configuration @Configuration @EnableWebMvc public class WebConfig{ // } The new @EnableWebMvc annotation does a number of useful things – specifically, in the case of REST, it detect the existence of Jackson and JAXB 2 on the classpath and automatically creates and registers default JSON and XML converters. The functionality of the annotation is equivalent to the XML version: This is a shortcut, and though it may be useful in many situations, it’s not perfect. When more complex configuration is needed, remove the annotation and extend WebMvcConfigurationSupport directly. 4. Testing the Spring context Starting with Spring 3.1, we get first-class testing support for @Configuration classes: @RunWith( SpringJUnit4ClassRunner.class ) @ContextConfiguration( classes = { ApplicationConfig.class, PersistenceConfig.class },loader = AnnotationConfigContextLoader.class ) public class SpringTest{ @Test public void whenSpringContextIsInstantiated_thenNoExceptions(){ // When } } The Java configuration classes are simply specified with the @ContextConfiguration annotation and the new AnnotationConfigContextLoader loads the bean definitions from the @Configuration classes. Notice that the WebConfig configuration class was not included in the test because it needs to run in a servlet context, which is not provided. 5. The Controller The @Controller is the central artifact in the entire Web Tier of the RESTful API. For the purpose of this post, the controller is modeling a simple REST resource – Foo: @Controller class FooController{ @Autowired IFooService service; @RequestMapping( value = "foo",method = RequestMethod.GET ) @ResponseBody public List< Foo > getAll(){ return this.service.getAll(); } @RequestMapping( value = "foo/{id}",method = RequestMethod.GET ) @ResponseBody public Foo get( @PathVariable( "id" ) Long id ){ return RestPreconditions.checkNotNull( this.service.getById( id ) ); } @RequestMapping( value = "foo",method = RequestMethod.POST ) @ResponseStatus( HttpStatus.CREATED ) @ResponseBody public Long create( @RequestBody Foo entity ){ RestPreconditions.checkNotNullFromRequest( entity ); return this.service.create( entity ); } @RequestMapping( value = "foo",method = RequestMethod.PUT ) @ResponseStatus( HttpStatus.OK ) public void update( @RequestBody Foo entity ){ RestPreconditions.checkNotNullFromRequest( entity ); RestPreconditions.checkNotNull( this.service.getById( entity.getId() ) ); this.service.update( entity ); } @RequestMapping( value = "foo/{id}",method = RequestMethod.DELETE ) @ResponseStatus( HttpStatus.OK ) public void delete( @PathVariable( "id" ) Long id ){ this.service.deleteById( id ); } } The Controller implementation is non-public – this is because there is no need for it to be. Usually the controller is the last in the chain of dependencies – it receives HTTP requests from the Spring front controller (the DispathcerServlet) and simply delegate them forward to a service layer. If there is no use case where the controller has to be injected or manipulated through a direct reference, then I prefer not to declare it as public. The request mappings are straightforward – as with any Spring controller, the actual value of the mapping as well as the HTTP method are used to determine the target method for the request. @RequestBody will bind the parameters of the method to the body of the HTTP request, whereas @ResponseBody does the same for the response and return type. They also ensure that the resource will be marshalled and unmarshalled using the correct HTTP converter. Content negotiation will take place to choose which one of the active converters will be used, based mostly on the Accept header, although other HTTP headers may be used to determine the representation as well. 6. Mapping the HTTP response codes The status codes of the HTTP response are one of the most important parts of the REST service, and the subject can quickly become very complex. Getting these right can be what makes or breaks the service. 6.1. Unmapped requests If Spring MVC receives a request which doesn’t have a mapping, it considers the request not to be allowed and returns a 405 METHOD NOT ALLOWED back to the client. It is also good practice to include the Allow HTTP header when returning a 405 to the client, in order to specify which operations are allowed. This is the standard behavior of Spring MVC and does not require any additional configuration. 6.2. Valid, mapped requests For any request that does have a mapping, Spring MVC considers the request valid and responds with 200 OK if no other status code is specified otherwise. It is because of this that controller declares different @ResponseStatus for the create, update and delete actions but not for get, which should indeed return the default 200 OK. 6.3. Client error In case of a client error, custom exceptions are defined and mapped to the appropriate error codes. Simply throwing these exceptions from any of the layers of the web tier will ensure Spring maps the corresponding status code on the HTTP response. @ResponseStatus( value = HttpStatus.BAD_REQUEST ) public class BadRequestException extends RuntimeException{ // } @ResponseStatus( value = HttpStatus.NOT_FOUND ) public class ResourceNotFoundException extends RuntimeException{ // } These exceptions are part of the REST API and, as such, should only be used in the appropriate layers corresponding to REST; if for instance a DAO/DAL layer exist, it should not use the exceptions directly. Note also that these are not checked exceptions but runtime exceptions – in line with Spring practices and idioms. 6.4. Using @ExceptionHandler Another option to map custom exceptions on specific status codes is to use the @ExceptionHandler annotation in the controller. The problem with that approach is that the annotation only applies to the controller in which it is defined, not to the entire Spring Container, which means that it needs to be declared in each controller individually. This quickly becomes cumbersome, especially in more complex applications which many controllers. There are a few JIRA issues opened with Spring at this time to handle this and other related limitations: SPR-8124, SPR-7278, SPR-8406. 7. Additional Maven dependencies In addition to the pom.xml from the first post, two dependencies need to be added: org.codehaus.jackson jackson-mapper-asl ${jackson-mapper-asl.version} runtime javax.xml.bind jaxb-api ${jaxb-api.version} runtime 1.9.12 2.2.4 These are the libraries used to convert the representation of the REST resource to either JSON or XML. 8. Conclusion This post covered the configuration and implementation of a RESTful service using Spring 3.1 and Java based configuration, discussing HTTP response codes, basic content negotiation and marshaling. In the next articles of the series I will focus on discoverability of the API, advanced content negotiation and working with additional representations of a resource. In the meantime, check out the github project.
November 2, 2011
by Eugen Paraschiv
· 48,696 Views · 1 Like
article thumbnail
Making and Moving Selectable Shapes on an HTML5 Canvas: A Simple Example
This is part one in a series. Part 2 can be found here. This tutorial will show you how to create a simple data structure for shapes on an HTML5 canvas and how to have them be selectable. The finished canvas will look like this: This text is displayed if your browser does not support HTML5 Canvas. You'll be able to click to drag boxes and double click to add new boxes. This article’s code is written primarily to be easy to understand. It isn’t optimized for performance, though a little bit of the drawing is set up so that more complex shapes can easily be added in the future. We’ll be going over a few things that are also essential to game-development (drawing loop, hit testing), and in later tutorials I will probably turn this example into a small game. The HTML5 Canvas A Canvas is made by using the tag in HTML: This text is displayed if your browser does not support HTML5 Canvas. A canvas isn’t smart: it’s just a place for drawing pixels. If you ask it to draw something it will do so and then immediately forget everything about what you have just done. Because of this we have to keep track ourselves of all the things we want to draw (and re-draw) each frame. So we’ll need to add: Code for keeping track of objects Code for initialization Code for drawing the objects as they are made and move around Code for mouse events Keeping track of what we draw To keep things simple for this example we will just make a rectangular object called Box. We’ll also make a method for creating Boxes a little easier. // holds all our rectangles var boxes = []; //Box object to hold data for all drawn rects function Box() { this.x = 0; this.y = 0; this.w = 1; // default width and height? this.h = 1; this.fill = '#444444'; } //Initialize a new Box, add it, and invalidate the canvas function addRect(x, y, w, h, fill) { var rect = new Box; rect.x = x; rect.y = y; rect.w = w rect.h = h; rect.fill = fill; boxes.push(rect); invalidate(); } Initialization I’m going to add a bunch of variables for keeping track of the drawing and mouse state. I already added boxes[] to keep track of each object, but we’ll also need a var for the canvas, the canvas’ 2d context (where wall drawing is done), whether the mouse is dragging, width/height of the canvas, and so on. We’ll also want to make a second canvas, for selection purposes, but I’ll talk about that later. var canvas; var ctx; var WIDTH; var HEIGHT; var INTERVAL = 20; // how often, in milliseconds, we check to see if a redraw is needed var isDrag = false; var mx, my; // mouse coordinates // when set to true, the canvas will redraw everything // invalidate() just sets this to false right now // we want to call invalidate() whenever we make a change var canvasValid = false; // The node (if any) being selected. // If in the future we want to select multiple objects, this will get turned into an array var mySel; // The selection color and width. Right now we have a red selection with a small width var mySelColor = '#CC0000'; var mySelWidth = 2; // we use a fake canvas to draw individual shapes for selection testing var ghostcanvas; var gctx; // fake canvas context // since we can drag from anywhere in a node // instead of just its x/y corner, we need to save // the offset of the mouse when we start dragging. var offsetx, offsety; // Padding and border style widths for mouse offsets var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; // initialize our canvas, add a ghost canvas, set draw loop // then add everything we want to intially exist on the canvas function init() { canvas = document.getElementById('canvas'); HEIGHT = canvas.height; WIDTH = canvas.width; ctx = canvas.getContext('2d'); ghostcanvas = document.createElement('canvas'); ghostcanvas.height = HEIGHT; ghostcanvas.width = WIDTH; gctx = ghostcanvas.getContext('2d'); //fixes a problem where double clicking causes text to get selected on the canvas canvas.onselectstart = function () { return false; } // fixes mouse co-ordinate problems when there's a border or padding // see getMouse for more detail if (document.defaultView && document.defaultView.getComputedStyle) { stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0; stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0; styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0; styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0; } // make draw() fire every INTERVAL milliseconds. setInterval(draw, INTERVAL); // add our events. Up and down are for dragging, // double click is for making new boxes canvas.onmousedown = myDown; canvas.onmouseup = myUp; canvas.ondblclick = myDblClick; // add custom initialization here: // add an orange rectangle addRect(200, 200, 40, 40, '#FFC02B'); // add a smaller blue rectangle addRect(25, 90, 25, 25, '#2BB8FF'); } Drawing Since our canvas is animated (boxes move over time), we have to set up a draw loop as I did in the init() function. We have to draw at a frame rate, maybe every 20 milliseconds or so. However, redrawing doesn’t just mean drawing the shapes over and over; we also have to clear the canvas before every redraw. If we don’t clear it, dragging will look like the box is making a solid line because none of the old box-positions will go away. Because of this, we clear the entire canvas before each Draw frame. This can get expensive, and we only want to draw if something has actually changed within our framework, so we will consider the canvas to be either valid or invalid. If everything just got drawn, the canvas is valid and there’s no need to draw again. However, if we do something like add a new Box or try to move a box by dragging it, the canvas will get invalidated and draw() will do a clear-redraw-validate. This isn’t the only way to optimize drawing, after all clearing and redrawing the entire canvas when one little box moves is excessive, but canvas invalidation is the only optimization we’re going to use for now. // While draw is called as often as the INTERVAL variable demands, // It only ever does something if the canvas gets invalidated by our code function draw() { if (canvasValid == false) { clear(ctx); // Add stuff you want drawn in the background all the time here // draw all boxes var l = boxes.length; for (var i = 0; i < l; i++) { drawshape(ctx, boxes[i], boxes[i].fill); } // draw selection // right now this is just a stroke along the edge of the selected box if (mySel != null) { ctx.strokeStyle = mySelColor; ctx.lineWidth = mySelWidth; ctx.strokeRect(mySel.x,mySel.y,mySel.w,mySel.h); } // Add stuff you want drawn on top all the time here canvasValid = true; } } As you can see, we go through all of boxes[] and draw each one, in order from first to last. This will give the nice appearance of later boxes looking as if they are on top of earlier boxes. After all the boxes are drawn, a selection handle (if there’s a selection) gets drawn around the box that mySel references. If you wanted a background (like a city) or a foreground (like clouds), one way to add them is to put them before or after the main two drawing bits. There are better ways though, like using multiple canvases, but we won’t go over that here. Mouse events Now we have objects, initialization, and a loop that will constantly re-draw when needed. All thats left is to make the mouse do things upon pressing, releasing, and double clicking. With our MouseDown event we need to see if there are any objects we could have clicked on. And we don’t want just any object; selections make the most sense when we only grab the top-most object. Now we could do something very easy and just check the bounds of each of our boxes – see if the mouse co-ordinates lie within the boxes width and height range – but that isn’t as extendable as I’d like. After all, What if later we want to select lines instead of boxes? Or select triangles? Or select text? So we’re going to do selection in a more general way: We will draw each shape, one at a time, onto a “ghost” canvas, and see if the mouse co-ordinates lie on a drawn pixel or not. A ghost canvas (or fake canvas, or temporary canvas) is a second canvas that we created in the same size and shape as our normal one. Only nothing from it will ever get seen, because we only created it in code and never added it to the page. Go back and look at ghostcanvas and its context (gctx) in the init() function to see how it was made. // Happens when the mouse is clicked in the canvas function myDown(e){ getMouse(e); clear(gctx); // clear the ghost canvas from its last use // run through all the boxes var l = boxes.length; for (var i = l-1; i >= 0; i--) { // draw shape onto ghost context drawshape(gctx, boxes[i], 'black'); // get image data at the mouse x,y pixel var imageData = gctx.getImageData(mx, my, 1, 1); var index = (mx + my * imageData.width) * 4; // if the mouse pixel exists, select and break if (imageData.data[3] > 0) { mySel = boxes[i]; offsetx = mx - mySel.x; offsety = my - mySel.y; mySel.x = mx - offsetx; mySel.y = my - offsety; isDrag = true; canvas.onmousemove = myMove; invalidate(); clear(gctx); return; } } // havent returned means we have selected nothing mySel = null; // clear the ghost canvas for next time clear(gctx); // invalidate because we might need the selection border to disappear invalidate(); } myMove and myUp are pretty self explanatory. the var isDrag becomes true if myDown found something to select, and it becomes false again when the mouse is released (myUp). // Happens when the mouse is moving inside the canvas function myMove(e){ if (isDrag){ getMouse(e); mySel.x = mx - offsetx; mySel.y = my - offsety; // something is changing position so we better invalidate the canvas! invalidate(); } } function myUp(){ isDrag = false; canvas.onmousemove = null; } There are a few little methods I added that are not shown, such as one to correctly get the mouse position in a canvas. You can see and download the full demo source here. Now that we have a basic structure down, it is easy to write code that handles more complex shapes, like paths or images or video. Rotation and scaling these things takes a bit more work, but is quite doable with the Canvas and our selection method is already set up to deal with them. If you would like to see this code enhanced in future posts (or have any fixes), let me know how in the comments. Part 2 of this tutorial is about resizing the shapes and can be found here. Source: http://simonsarris.com/blog/140-canvas-moving-selectable-shapes
November 2, 2011
by Simon Sarris
· 40,265 Views
article thumbnail
Updating the Duct Tape for HTML5: Websockets in Perl (Mojolicious)
Perl was easy to use, wildly popular, and lots of fun. The Camel Book introduced many coders to a powerful new language (and the whimsically-covered O'Reilly series), and offered access to web programming via CGI. Plenty of people still develop in Perl ('the duct tape of the Internet'), although lately some criticism of Perl programmers has surfaced. No doubt about one thing, though: CGI is just too old. Sensing a need, Sebastian Ridel created Mojolicious to fill CGI's place, satisfying Perl programmers' desire for a more modern web framework Yesterday Sebastian showed off some of Mojolicious' simplicity and power: By now you've probably heard about WebSockets, and that they are the future of web development, but so far there are very little examples that really show how easy to use they actually are. So today we are going to explore the wonderful world of events in Mojolicious a bit and build a little application that forwards all framework log messages to a browser window. The script is short and sweet and, if you still love Perl, will warm your HTML5 heart. Check it out here.
November 1, 2011
by John Esposito
· 8,085 Views
article thumbnail
Grails – Groovy – Alternative to HttpBuilder – adding headers to your HTTP request
Developing with Grails and Groovy can be a blessing and and pain all at the same time. The development moves at a rapid rate but when you decide to include libraries that depend on other libraries, your pain starts to build up. For example, when you include the module “HttpBuilder”in your project you may run into issues with Xerces and xml-apis, especially when you attempt to deploy the WAR file under Tomcat. These libraries are included as part of Tomcat and so an older version of those classes may give you a heartburn. If your objective is to use some raw HTTP classes to create your requests and responses, then you can use the basic URL class to do most of the raw connection options. Although using HttpBuilder makes it a clean implementation, the URL class gives you very similar power without all the overhead of including the dependency classes. def urlConnect = new URL(url) def connection = urlConnect.openConnection() //Set all of your needed headers connection.setRequestProperty("X-Forwarded-For", "") if(connection.responseCode == 200){ responseText = connection.content.text } else{ println "An error occurred:" println connection.responseCode println connection.responseMessage } So the trick to the Groovy URL class is to use the “openConnection()” method and then gain access to some of the raw functionality. Cheers. From http://mythinkpond.wordpress.com/2011/10/24/grails-groovy-alternative-to-httpbuilder-adding-headers-to-your-http-request/
October 30, 2011
by Venkatt Guhesan
· 14,402 Views
article thumbnail
Just in Time Compiler (JIT) in Hotspot
What is JIT Compiler? The Just In Time Compiler (JIT) concept and more generally adaptive optimization is well known concept in many languages besides Java (.Net, Lua, JRuby). In order to explain what is JIT Compiler I want to start with a definition of compiler concept. According to wikipedia compiler is "a computer program that transforms the source language into another computer language (the target language)". We are all familiar with static java compiler (javac) that compiles human readable .java files to a byte code that can be interpreted by JVM - .class files. Then what does JIT compile? The answer will given a moment later after explanation of what is "Just in Time". According to most researches, 80% of execution time is spent in executing 20% of code. That would be great if there was a way to determine those 20% of code and to optimize them. That's exactly what JIT does - during runtime it gathers statistics, finds the "hot" code compiles it from JVM interpreted bytecode (that is stored in .class files) to a native code that is executed directly by Operating System and heavily optimizes it. Smallest compilation unit is single method. Compilation and statistics gathering is done in parallel to program execution by special threads. During statistics gathering the compiler makes hypotheses about code function and as the time passes tries to prove or to disprove them. If the hypothesis is dis-proven the code is deoptimized and recompiled again. The name "Hotspot" of Sun (Oracle) JVM is chosen because of the ability of this Virtual Machine to find "hot" spots in code. What optimizations does JIT? Let's look closely at more optimizations done by JIT. Inline methods - instead of calling method on an instance of the object it copies the method to caller code. The hot methods should be located as close to the caller as possible to prevent any overhead. Eliminate locks if monitor is not reachable from other threads Replace interface with direct method calls for method implemented only once to eliminate calling of virtual functions overhead Join adjacent synchronized blocks on the same object Eliminate dead code Drop memory write for non-volatile variables Remove prechecking NullPointerException and IndexOutOfBoundsException Et cetera When the Java VM invokes a Java method, it uses an invoker method as specified in the method block of the loaded class object. The Java VM has several invoker methods, for example, a different invoker is used if the method is synchronized or if it is a native method. The JIT compiler uses its own invoker. Sun production releases check the method access bit for value ACC_MACHINE_COMPILED to notify the interpreter that the code for this method has already been compiled and stored in the loaded class. JIT compiler compiles the method block into native code for this method and stores that in the code block for that method. Once the code has been compiled the ACC_MACHINE_COMPILED bit, which is used on the Sun platform, is set. How do we know what JIT is doing in our program and how can it be controlled? First of all to disable JIT Djava.compiler=NONE parameter can be used. There are 2 types of JIT compilers in Hotspot - one is used for client program and one for server (-server option in VM parameters). Program, running on server enjoys usually from more resources than program running on client and to server program top throughput is usually more important. Hence JIT in server is more resource consuming and gathering statistics takes more time to make the statistics more accurate. For client program gathering statics for a method lasts 1500 method calls, for server 15000. These default values can be changed by -XX:CompileThreshold=XXX VM parameter. In order to find out whether default value is good for you try enabling "XX:+PrintCompilation" and "-XX:-CITime" parameters that print JIT statistics and time CPU spent by JIT. Benchmarks Most of the benchmarks show that JITed code runs 10 to 20 times faster than interpreted code. There are many benchmarks done. Below given result graphs of two of them: Its worth to mention that programs that run in JIT mode, but are still in "learning mode" run much slower than non JITed programs. Drawbacks of JIT JIT Increases level of unpredictability and complexity in Java program. It adds another layer that developers don't really understand. Example of possible bugs - 'happens before relations" in concurrency. JIT can easily reorder code if the change is safe for a program running in single thread. To solve this problem developers make hints to JIT using "synchronized" word or explicit locking. Increases non heap memory footprint - JITed code is stored in "Code Cache" generation. Advanced JIT JIT and garbage collection. For GC to occur program must reach safe points. For this purpose JIT injects yieldpoints at regular intervals in native code. In addition to scanning of stack to find root references, registers must be scanned as they may hold objects created by JIT Comments are appresiated. The article can be found also at: artiomg.blogspot.com/2011/10/just-in-time-compiler-jit-in-hotspot.html
October 29, 2011
by Artiom Gourevitch
· 39,327 Views · 1 Like
article thumbnail
Magic: The Gathering in JavaScript and HTML5
as a user interface fan, i could not miss the development with html 5. so the goal of this post is to walk through a graphic application that uses javascript and html 5. we will see through examples one way (among others) to develop this kind of project. application overview tools the html 5 page data gathering cards loading & cache handling cards display mouse management state storage animations handling multi-devices conclusion to go further application overview we will produce an application that will let us display a magic the gathering ©(courtesy of www.wizards.com/magic ) cards collection. users will be able to scroll and zoom using the mouse (like bing maps, for example). you can see the final result here: http://bolaslenses.catuhe.com the project source files can be downloaded here: http://www.catuhe.com/msdn/bolaslenses.zip cards are stored on windows azure storage and use the azure content distribution network ( cdn : a service that deploys data near the final users) in order to achieve maximum performances. an asp.net service is used to return cards list (using json format). tools to write our application, we will use visual studio 2010 sp1 with web standards update . this extension adds intellisense support in html 5 page (which is a really important thing ). so, our solution will contain an html 5 page side by side with .js files (these files will contain javascript scripts). about debug, it is possible to set a breakpoint directly in the .js files under visual studio. it is also possible to use the developer bar of internet explorer 9 (use f12 key to display it). debug with visual studio 2010 debug with internet explorer 9 (f12/developer bar) so, we have a modern developer environment with intellisense and debug support. therefore, we are ready to start and first of all, we will write the html 5 page. the html 5 page our page will be built around an html 5 canvas which will be used to draw the cards: cards scanned by mwshq team magic the gathering official site : http://www.wizards.com/magic bolas lenses your browser does not support html5 canvas. loading data... if we dissect this page, we can note that it is divided into two parts: the header part with the title, the logo and the special mentions the main part (section) holds the canvas and the tooltips that will display the status of the application. there is also a hidden image ( backimage ) used as source for not yet loaded cards. to build the layout of the page, a style sheet ( full.css ) is applied. style sheets are a mechanism used to change the tags styles (in html, a style defines the entire display options for a tag): html, body { height: 100%; } body { background-color: #888888; font-size: .85em; font-family: "segoe ui, trebuchet ms" , verdana, helvetica, sans-serif; margin: 0; padding: 0; color: #696969; } a:link { color: #034af3; text-decoration: underline; } a:visited { color: #505abc; } a:hover { color: #1d60ff; text-decoration: none; } a:active { color: #12eb87; } header, footer, nav, section { display: block; } table { width: 100%; } header, #header { position: relative; margin-bottom: 0px; color: #000; padding: 0; } #title { font-weight: bold; color: #fff; border: none; font-size: 60px !important; vertical-align: middle; margin-left: 70px } #legal { text-align: right; color: white; font-size: 14px; width: 50%; position: absolute; top: 15px; right: 10px } #leftheader { width: 50%; vertical-align: middle; } section { margin: 20px 20px 20px 20px; } #maincanvas{ border: 4px solid #000000; } #cardscount { font-weight: bolder; font-size: 1.1em; } .tooltip { position: absolute; bottom: 5px; color: black; background-color: white; margin-right: auto; margin-left: auto; left: 35%; right: 35%; padding: 5px; width: 30%; text-align: center; border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; box-shadow: 2px 2px 2px #333333; } #bolaslogo { width: 64px; height: 64px; } #picturecell { float: left; width: 64px; margin: 5px 5px 5px 5px; vertical-align: middle; } thus, this sheet is responsible for setting up the following display: style sheets are powerful tools that allow an infinite number of displays. however, they are sometimes complicated to setup (for example if a tag is affected by a class, an identifier and its container). to simplify this setup, the development bar of internet explorer 9 is particularly useful because we can use it to see styles hierarchy that is applied to a tag. for example let’s take a look at the waittext tooltip with the development bar. to do this, you must press f12 in internet explorer and use the selector to choose the tooltip: once the selection is done, we can see the styles hierarchy: thus, we can see that our div received its styles from the body tag and the . tooltip entry of the style sheet. with this tool, it becomes possible to see the effect of each style (which can be disabled). it is also possible to add new style on the fly. another important point of this window is the ability to change the rendering mode of internet explorer 9. indeed, we can test how, for example, internet explorer 8 will handle the same page. to do this, go to the [ browser mode ] menu and select the engine of internet explorer 8. this change will especially impact our tooltip as it uses border-radius (rounded edge) and box-shadow that are features of css 3: internet explorer 9 internet explorer 8 our page provides a graceful degradation as it still works (with no annoying visual difference) when the browser does not support all the required technologies. now that our interface is ready, we will take a look at the data source to retrieve the cards to display. the server provides the cards list using json format on this url: http://bolaslenses.catuhe.com/ home/listofcards/?colorstring=0 it takes one parameter ( colorstring ) to select a specific color (0 = all). when developing with javascript, there is a good reflex to have (reflex also good in other languages too, but really important in javascript): one must ask whether what we want to develop has not been already done in an existing framework. indeed, there is a multitude of open source projects around javascript. one of them is jquery which provides a plethora of convenient services. thus, in our case to connect to the url of our server and get the cards list, we could go through a xmlhttprequest and have fun to parse the returned json. or we can use jquery . so we will use the getjson function which will take care of everything for us: function getlistofcards() { var url = "http://bolaslenses.catuhe.com/home/listofcards/?jsoncallback=?"; $.getjson(url, { colorstring: "0" }, function (data) { listofcards = data; $("#cardscount").text(listofcards.length + " cards displayed"); $("#waittext").slidetoggle("fast"); }); } as we can see, our function stores the cards list in the listofcards variable and calls two jquery functions: text that change the text of a tag slidetoggle that hides (or shows) a tag by animating its height the listofcards list contains objects whose format is: id : unique identifier of the card path : relative path of the card (without the extension) it should be noted that the url of the server is called with the “ ?jsoncallback=? ” suffix. indeed, ajax calls are constrained in terms of security to connect only to the same address as the calling script. however, there is a solution called jsonp that will allow us to make a concerted call to the server (which of course must be aware of the operation). and fortunately, jquery can handle it all alone by just adding the right suffix. once we have our cards list, we can set up the pictures loading and caching. cards loading & cache handling the main trick of our application is to draw only the cards effectively visible on the screen. the display window is defined by a zoom level and an offset (x, y) in the overall system. var visucontrol = { zoom : 0.25, offsetx : 0, offsety : 0 }; the overall system is defined by 14819 cards that are spread over 200 columns and 75 rows. also, we must be aware that each card is available in three versions: high definition: 480x680 without compression (.jpg suffix) medium definition: 240x340 with standard compression (.50.jpg suffix) low definition: 120x170 with strong compression (.25.jpg suffix) thus, depending on the zoom level, we will load the correct version to optimize networks transfer. to do this we will develop a function that will give an image for a given card. this function will be configured to download a certain level of quality. in addition it will be linked with lower quality level to return it if the card for the current level is not yet uploaded: function imagecache(substr, replacementcache) { var extension = substr; var backimage = document.getelementbyid("backimage"); this.load = function (card) { var localcache = this; if (this[card.id] != undefined) return; var img = new image(); localcache[card.id] = { image: img, isloaded: false }; currentdownloads++; img.onload = function () { localcache[card.id].isloaded = true; currentdownloads--; }; img.onerror = function() { currentdownloads--; }; img.src = "http://az30809.vo.msecnd.net/" + card.path + extension; }; this.getreplacementfromlowercache = function (card) { if (replacementcache == undefined) return backimage; return replacementcache.getimageforcard(card); }; this.getimageforcard = function(card) { var img; if (this[card.id] == undefined) { this.load(card); img = this.getreplacementfromlowercache(card); } else { if (this[card.id].isloaded) img = this[card.id].image; else img = this.getreplacementfromlowercache(card); } return img; }; } an imagecache is built by giving the associated suffix and the underlying cache. here you can see two important functions: load : this function will load the right picture and will store it in a cache (the msecnd.net url is the azure cdn address of the cards) getimageforcard : this function returns the card picture from the cache if already loaded. otherwise it requests the underlying cache to return its version (and so on) so to handle our 3 levels of caches, we have to declare three variables: var imagescache25 = new imagecache(".25.jpg"); var imagescache50 = new imagecache(".50.jpg", imagescache25); var imagescachefull = new imagecache(".jpg", imagescache50); selecting the right cover is only depending on zoom: function getcorrectimagecache() { if (visucontrol.zoom <= 0.25) return imagescache25; if (visucontrol.zoom <= 0.8) return imagescache50; return imagescachefull; } to give a feedback to the user, we will add a timer that will manage a tooltip that indicates the number of images currently loaded: function updatestats() { var stats = $("#stats"); stats.html(currentdownloads + " card(s) currently downloaded."); if (currentdownloads == 0 && statsvisible) { statsvisible = false; stats.slidetoggle("fast"); } else if (currentdownloads > 1 && !statsvisible) { statsvisible = true; stats.slidetoggle("fast"); } } setinterval(updatestats, 200); again we note the use of jquery to simplify animations. we will now discuss the display of cards. cards display to draw our cards, we need to actually fill the canvas using its 2d context (which exists only if the browser supports html 5 canvas): var maincanvas = document.getelementbyid("maincanvas"); var drawingcontext = maincanvas.getcontext('2d'); the drawing will be made by processlistofcards function (called 60 times per second): function processlistofcards() { if (listofcards == undefined) { drawwaitmessage(); return; } maincanvas.width = document.getelementbyid("center").clientwidth; maincanvas.height = document.getelementbyid("center").clientheight; totalcards = listofcards.length; var localcardwidth = cardwidth * visucontrol.zoom; var localcardheight = cardheight * visucontrol.zoom; var effectivetotalcardsinwidth = colscount * localcardwidth; var rowscount = math.ceil(totalcards / colscount); var effectivetotalcardsinheight = rowscount * localcardheight; initialx = (maincanvas.width - effectivetotalcardsinwidth) / 2.0 - localcardwidth / 2.0; initialy = (maincanvas.height - effectivetotalcardsinheight) / 2.0 - localcardheight / 2.0; // clear clearcanvas(); // computing of the viewing area var initialoffsetx = initialx + visucontrol.offsetx * visucontrol.zoom; var initialoffsety = initialy + visucontrol.offsety * visucontrol.zoom; var startx = math.max(math.floor(-initialoffsetx / localcardwidth) - 1, 0); var starty = math.max(math.floor(-initialoffsety / localcardheight) - 1, 0); var endx = math.min(startx + math.floor((maincanvas.width - initialoffsetx - startx * localcardwidth) / localcardwidth) + 1, colscount); var endy = math.min(starty + math.floor((maincanvas.height - initialoffsety - starty * localcardheight) / localcardheight) + 1, rowscount); // getting current cache var imagecache = getcorrectimagecache(); // render for (var y = starty; y < endy; y++) { for (var x = startx; x < endx; x++) { var localx = x * localcardwidth + initialoffsetx; var localy = y * localcardheight + initialoffsety; // clip if (localx > maincanvas.width) continue; if (localy > maincanvas.height) continue; if (localx + localcardwidth < 0) continue; if (localy + localcardheight < 0) continue; var card = listofcards[x + y * colscount]; if (card == undefined) continue; // get from cache var img = imagecache.getimageforcard(card); // render try { if (img != undefined) drawingcontext.drawimage(img, localx, localy, localcardwidth, localcardheight); } catch (e) { $.grep(listofcards, function (item) { return item.image != img; }); } } }; // scroll bars drawscrollbars(effectivetotalcardsinwidth, effectivetotalcardsinheight, initialoffsetx, initialoffsety); // fps computefps(); } this function is built around many key points: if the cards list is not yet loaded, we display a tooltip indicating that download is in progress: var pointcount = 0; function drawwaitmessage() { pointcount++; if (pointcount > 200) pointcount = 0; var points = ""; for (var index = 0; index < pointcount / 10; index++) points += "."; $("#waittext").html("loading...please wait" + points); subsequently, we define the position of the display window (in terms of cards and coordinates), then we proceed to clean the canvas: function clearcanvas() { maincanvas.width = document.body.clientwidth - 50; maincanvas.height = document.body.clientheight - 140; drawingcontext.fillstyle = "rgb(0, 0, 0)"; drawingcontext.fillrect(0, 0, maincanvas.width, maincanvas.height); } then we browse the cards list and call the drawimage function of the canvas context. the current image is provided by the active cache (depending on the zoom): // get from cache var img = imagecache.getimageforcard(card); // render try { if (img != undefined) drawingcontext.drawimage(img, localx, localy, localcardwidth, localcardheight); } catch (e) { $.grep(listofcards, function (item) { return item.image != img; }); we also have to draw the scroll bar with the roundedrectangle function that uses quadratic curves: function roundedrectangle(x, y, width, height, radius) { drawingcontext.beginpath(); drawingcontext.moveto(x + radius, y); drawingcontext.lineto(x + width - radius, y); drawingcontext.quadraticcurveto(x + width, y, x + width, y + radius); drawingcontext.lineto(x + width, y + height - radius); drawingcontext.quadraticcurveto(x + width, y + height, x + width - radius, y + height); drawingcontext.lineto(x + radius, y + height); drawingcontext.quadraticcurveto(x, y + height, x, y + height - radius); drawingcontext.lineto(x, y + radius); drawingcontext.quadraticcurveto(x, y, x + radius, y); drawingcontext.closepath(); drawingcontext.stroke(); drawingcontext.fill(); } function drawscrollbars(effectivetotalcardsinwidth, effectivetotalcardsinheight, initialoffsetx, initialoffsety) { drawingcontext.fillstyle = "rgba(255, 255, 255, 0.6)"; drawingcontext.linewidth = 2; // vertical var totalscrollheight = effectivetotalcardsinheight + maincanvas.height; var scaleheight = maincanvas.height - 20; var scrollheight = maincanvas.height / totalscrollheight; var scrollstarty = (-initialoffsety + maincanvas.height * 0.5) / totalscrollheight; roundedrectangle(maincanvas.width - 8, scrollstarty * scaleheight + 10, 5, scrollheight * scaleheight, 4); // horizontal var totalscrollwidth = effectivetotalcardsinwidth + maincanvas.width; var scalewidth = maincanvas.width - 20; var scrollwidth = maincanvas.width / totalscrollwidth; var scrollstartx = (-initialoffsetx + maincanvas.width * 0.5) / totalscrollwidth; roundedrectangle(scrollstartx * scalewidth + 10, maincanvas.height - 8, scrollwidth * scalewidth, 5, 4); } and finally, we need to compute the number of frames per second: function computefps() { if (previous.length > 60) { previous.splice(0, 1); } var start = (new date).gettime(); previous.push(start); var sum = 0; for (var id = 0; id < previous.length - 1; id++) { sum += previous[id + 1] - previous[id]; } var diff = 1000.0 / (sum / previous.length); $("#cardscount").text(diff.tofixed() + " fps. " + listofcards.length + " cards displayed"); } drawing cards relies heavily on the browser's ability to speed up canvas rendering. for the record, here are the performances on my machine with the minimum zoom level (0.05): browser fps internet explorer 9 30 firefox 5 30 chrome 12 17 ipad (with a zoom level of 0.8) 7 windows phone mango (with a zoom level of 0.8) 20 (!!) the site even works on mobile phones and tablets as long as they support html 5. here we can see the inner power of html 5 browsers that can handle a full screen of cards more than 30 times per second! mouse management to browse our cards collection, we have to manage the mouse (including its wheel). for the scrolling, we'll just handle the onmouvemove , onmouseup and onmousedown events. onmouseup and onmousedown events will be used to detect if the mouse is clicked or not: var mousedown = 0; document.body.onmousedown = function (e) { mousedown = 1; getmouseposition(e); previousx = posx; previousy = posy; }; document.body.onmouseup = function () { mousedown = 0; }; the onmousemove event is connected to the canvas and used to move the view: var previousx = 0; var previousy = 0; var posx = 0; var posy = 0; function getmouseposition(eventargs) { var e; if (!eventargs) e = window.event; else { e = eventargs; } if (e.offsetx || e.offsety) { posx = e.offsetx; posy = e.offsety; } else if (e.clientx || e.clienty) { posx = e.clientx; posy = e.clienty; } } function onmousemove(e) { if (!mousedown) return; getmouseposition(e); mousemovefunc(posx, posy, previousx, previousy); previousx = posx; previousy = posy; } this function (onmousemove) calculates the current position and provides also the previous value in order to move the offset of the display window: function move(posx, posy, previousx, previousy) { currentaddx = (posx - previousx) / visucontrol.zoom; currentaddy = (posy - previousy) / visucontrol.zoom; } mousehelper.registermousemove(maincanvas, move); note that jquery also provides tools to manage mouse events. for the management of the wheel, we will have to adapt to different browsers that do not behave the same way on this point: function wheel(event) { var delta = 0; if (event.wheeldelta) { delta = event.wheeldelta / 120; if (window.opera) delta = -delta; } else if (event.detail) { /** mozilla case. */ delta = -event.detail / 3; } if (delta) { wheelfunc(delta); } if (event.preventdefault) event.preventdefault(); event.returnvalue = false; } we can see that everyone does what he wants :). the function to register with this event is: mousehelper.registerwheel = function (func) { wheelfunc = func; if (window.addeventlistener) window.addeventlistener('dommousescroll', wheel, false); window.onmousewheel = document.onmousewheel = wheel; }; and we will use this function to change the zoom with the wheel: // mouse mousehelper.registerwheel(function (delta) { currentaddzoom += delta / 500.0; }); finally we will add a bit of inertia when moving the mouse (and the zoom) to give some kind of smoothness: // inertia var inertia = 0.92; var currentaddx = 0; var currentaddy = 0; var currentaddzoom = 0; function doinertia() { visucontrol.offsetx += currentaddx; visucontrol.offsety += currentaddy; visucontrol.zoom += currentaddzoom; var effectivetotalcardsinwidth = colscount * cardwidth; var rowscount = math.ceil(totalcards / colscount); var effectivetotalcardsinheight = rowscount * cardheight var maxoffsetx = effectivetotalcardsinwidth / 2.0; var maxoffsety = effectivetotalcardsinheight / 2.0; if (visucontrol.offsetx < -maxoffsetx + cardwidth) visucontrol.offsetx = -maxoffsetx + cardwidth; else if (visucontrol.offsetx > maxoffsetx) visucontrol.offsetx = maxoffsetx; if (visucontrol.offsety < -maxoffsety + cardheight) visucontrol.offsety = -maxoffsety + cardheight; else if (visucontrol.offsety > maxoffsety) visucontrol.offsety = maxoffsety; if (visucontrol.zoom < 0.05) visucontrol.zoom = 0.05; else if (visucontrol.zoom > 1) visucontrol.zoom = 1; processlistofcards(); currentaddx *= inertia; currentaddy *= inertia; currentaddzoom *= inertia; // epsilon if (math.abs(currentaddx) < 0.001) currentaddx = 0; if (math.abs(currentaddy) < 0.001) currentaddy = 0; } this kind of small function does not cost a lot to implement, but adds a lot to the quality of user experience. state storage also to provide a better user experience, we will save the display window’s position and zoom. to do this, we will use the service of localstorage (which saves pairs of keys / values for the long term (the data is retained after the browser is closed) and only accessible by the current window object): function saveconfig() { if (window.localstorage == undefined) return; // zoom window.localstorage["zoom"] = visucontrol.zoom; // offsets window.localstorage["offsetx"] = visucontrol.offsetx; window.localstorage["offsety"] = visucontrol.offsety; } // restore data if (window.localstorage != undefined) { var storedzoom = window.localstorage["zoom"]; if (storedzoom != undefined) visucontrol.zoom = parsefloat(storedzoom); var storedoffsetx = window.localstorage["offsetx"]; if (storedoffsetx != undefined) visucontrol.offsetx = parsefloat(storedoffsetx); var storedoffsety = window.localstorage["offsety"]; if (storedoffsety != undefined) visucontrol.offsety = parsefloat(storedoffsety); } animations to add even more dynamism to our application we will allow our users to double-click on a card to zoom and focus on it. our system should animate three values: the two offsets (x, y) and the zoom. to do this, we will use a function that will be responsible of animating a variable from a source value to a destination value with a given duration: var animationhelper = function (root, name) { var paramname = name; this.animate = function (current, to, duration) { var offset = (to - current); var ticks = math.floor(duration / 16); var offsetpart = offset / ticks; var tickscount = 0; var intervalid = setinterval(function () { current += offsetpart; root[paramname] = current; tickscount++; if (tickscount == ticks) { clearinterval(intervalid); root[paramname] = to; } }, 16); }; }; the use of this function is: // prepare animations parameters var zoomanimationhelper = new animationhelper(visucontrol, "zoom"); var offsetxanimationhelper = new animationhelper(visucontrol, "offsetx"); var offsetyanimationhelper = new animationhelper(visucontrol, "offsety"); var speed = 1.1 - visucontrol.zoom; zoomanimationhelper.animate(visucontrol.zoom, 1.0, 1000 * speed); offsetxanimationhelper.animate(visucontrol.offsetx, targetoffsetx, 1000 * speed); offsetyanimationhelper.animate(visucontrol.offsety, targetoffsety, 1000 * speed); the advantage of the animationhelper function is that it is able to animate as many parameters as you wish (and that only with the settimer function!) handling multi-devices finally we will ensure that our page can also be seen on tablets pc and even on phones. to do this, we will use a feature of css 3: the media-queries . with this technology, we can apply style sheets according to some queries such as a specific display size: here we see that if the screen width is less than 480 pixels, the following style sheet will be added: #legal { font-size: 8px; } #title { font-size: 30px !important; } #waittext { font-size: 12px; } #bolaslogo { width: 48px; height: 48px; } #picturecell { width: 48px; } finally we will ensure that our page can also be seen on tablets pc and even on phones. to do this, we will use a feature of css 3: #legal { font-size: 8px; } #title { font-size: 30px !important; } #waittext { font-size: 12px; } #bolaslogo { width: 48px; height: 48px; } #picturecell { width: 48px; } conclusion html 5 / css 3 / javascript and visual studio 2010 allow to develop portable and efficient solutions (within the limits of browsers that support html 5 of course) with some great features such as hardware accelerated rendering. this kind of development is also simplified by the use of frameworks like jquery. also, i am especially fan of javascript that turns out to be a very powerful dynamic language. of course, c# or vb.net developers have to change theirs reflexes but for the development of web pages it's worth. in conclusion, i think that the best to be convinced is to try! to go further internet explorer test drive: http://ie.microsoft.com/testdrive/ internet explorer 9 guide for developer : http://msdn.microsoft.com/en-us/ie/ff468705 w3c site for html 5 : http://dev.w3.org/html5/spec/overview.html internet explorer site : http://msdn.microsoft.com/en-us/ie/aa740469 about the author david catuhe is a developer evangelist for microsoft france in charge of user experience development tools (from xaml to directx/xna and html5). he defines himself as a geek and likes coding all that refer to graphics. before working for microsoft, he founded a company that developed a realtime 3d engine written with directx ( www.vertice.fr ). source: http://blogs.msdn.com/b/eternalcoding/archive/2011/07/25/feedback-of-a-graphic-development-using-html5-amp-javascript.aspx
October 24, 2011
by David Catuhe
· 25,204 Views · 1 Like
article thumbnail
How to Create a Simple PHP Text Counter
After learning the basics of PHP's basic file system functions, the first thing you'll want to do is put it to use. One of the easiest and flashiest things you can create is a page counting script. I'll show you how to create a page hit script that is easy to create and even easier to implement. This is the entire script. Let's go through it line by line. $filename = "counter.txt"; This assigns the filename to a variable to be used throughout the rest of the script. In this case I used counter.txt. The first thing to do after implementing this script is to create counter.txt on your server in the same directory as this script and chmod is to 777 so that PHP may write to the file later on. Here is a great tutorial on how to chmod files: http://support.discusware.com/center/resources/howto/chmod.html $count = file_get_contents($filename); This line stores in entire contents of counter.txt into the variable $count. In this case there is only a number inside counter.txt so $count holds that number. if ($count == null) $count = 0; If the file is empty we need to make a case for that or problems will come up later. If $count does not contain anything than we go ahead and set $count to 0. echo $count; This will display the number inside the text file. $count++; This adds 1 to the current $count. $handle = fopen($filename, "w+"); The next thing to do is to open the file for writing and to truncate it (erase its contents), that's why I choose w+. Please see my article on file system basics for an explanation on other modes. fopen() requires that we assign a resource handle to be referenced in the future. fwrite($handle, $count); This line writes the variable $count to our file represented by $handle. fclose($handle); This is the final line of the script where we do some cleanup. This closes the file we opened earlier. It isn't essential to the script what its always nice to cover all bases. Now that you understand how the script works it's time to implement it. This assumes you name the script above counter.php. Wherever you put this in your page is where the script will echo the page hit count. It's as easy as that.
October 24, 2011
by Michael Bernat
· 16,370 Views
article thumbnail
Practical PHP Refactoring: Replace Conditional with Polymorphism
In the scenario of today, an if chooses to execute different behavior depending on the type of an object. We should define "type" very looosely; for example, it may be: the class of the object or one of the interfaces it implements (instanceof). The value of one of the object's fields (usually enumerative). The result of a query method, such as isXXX() or getTotalValue(). Each of these discriminants has the power to be used in dozens of identical conditionals throughout the codebase. Why eliminating this conditional? And by replacing it with what? We can replace easily this kind of conditionals with polymorphism: we move the relevant logic in the object whose type is queried. This object becomes an instance of a subclass of the original one: the different legs of the conditional become different subclasses. In case the subclasses already exist, it's even easier as it's just a movement of code at the method scale. Typically polymorphism allows to remove the conditional or to put it at the instantiation time of the new object. It's an expression of the Tell, Don't Ask principle, where instead of asking repeatedly (in different places of client code) the object what to do, you simply tell the object to do something and pass in some references if necessary. The end result is that the duplication of the conditional is eliminated as it is splitted into the various classes of the hierarchy. The addition or removal of a new type impacts just a subclass, which has to be created anew or thrown away. You don't have to grep all your application looking for if()s involving a field. Note that this refactoring works not only for ifs and elses, but also for selects. The missing step A prerequisite for this refactoring is having an existing inheritance structure where the dependency of client code is on the parent, but different instances of the child can be passed in. If there is not already a hierarchy, you have two choices as preliminary refactorings: inheritance: Replace Type code with Subclasses. The current class gains new children; it is a less invasive approach but also but less clear. Inheritance is a one shot strategy as you won't be able to use it for other axis of change. composition: Replace type code with State or Strategy. A new class is extracted, which gains the bew children. More flexible as you can extract many collaborators like this, and forces to name the new concept and its new hierarchy. The steps in the rest of the article presume you already have this hierarchy, so let these two refactorings guide you into extracting the classes (even if they come up empty initially). This refactoring then only focuses on breaking up the conditional code. The previous refactorings allow you to tackle the hierarchy and the instantiation code instead. Steps Extract a method containing the conditional. Move this method to the top of the inheritance hierarchy. Copy the original method into each subclass, and eliminate all machinery to leave just one leg. Some data of the original class may become protected instead of private. Remove the copied leg and repeat with the next subclass until the method in the superclass is empty and the overrides do not contain references to classes different from the current one. Example In the initial state of the example, the Renderer class has a kind of switch where it generates different HTML depending on the class of the object to render: Brand pages can have custom URLs, while user profile must follow the standard naming scheme and use their nick. assertEquals('giorgio', $renderer->__toString()); } public function testABrandPageShouldHaveACustomURL() { $renderer = new Renderer(new Brand('Coca Cola', 'coke')); $this->assertEquals('Coca Cola', $renderer->__toString()); } } class User { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } } class Brand { private $name; private $url; public function __construct($name, $url) { $this->name = $name; $this->url = $url; } public function getName() { return $this->name; } public function getURL() { return $this->url; } } class Renderer { private $domainObject; public function __construct($domainObject) { $this->domainObject = $domainObject; } public function __toString() { if ($this->domainObject instanceof User) { return '' . $this->domainObject->getName() . ''; } if ($this->domainObject instanceof Brand) { return '' . $this->domainObject->getName() . ''; } } } There are two issues with this design: if we add a new domain object (e.g. Group, with its own page) we have to open up the hood and insert new code in an already existing class. It's generally easier to deal with a change by adding brand new classes, since we can't break existing code if we do not touch it. Not only Renderer contains these different cases, but probably many objects composing Brand and User. The first move is to isolate the variability into a single hierarchy of classes.Since there is no common ancestor, we create a common superclass in Brand and User. getURL() would be better named as getSlug() actually (an url-friendly label). abstract class Addressable { public function render($template) { if ($this instanceof User) { return sprintf($template, $this->getName(), $this->getName()); } if ($this instanceof Brand) { return sprintf($template, $this->getUrl(), $this->getName()); } } } We only hid the mess, not resolved it: the base class is still a single point that knows everything about the subclasses. At least there would be no duplication if someone wants to use name or URL in other HTML fragments. We copy the method into the various subclasses. In this case we augment duplication, but that's a temporary move since we will eliminate most of the code in the methods shortly. class User extends Addressable { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function render($template) { if ($this instanceof User) { return sprintf($template, $this->getName(), $this->getName()); } if ($this instanceof Brand) { return sprintf($template, $this->getUrl(), $this->getName()); } } } class Brand extends Addressable { private $name; private $url; public function __construct($name, $url) { $this->name = $name; $this->url = $url; } public function getName() { return $this->name; } public function getURL() { return $this->url; } public function render($template) { if ($this instanceof User) { return sprintf($template, $this->getName(), $this->getName()); } if ($this instanceof Brand) { return sprintf($template, $this->getUrl(), $this->getName()); } } } In the next step, we make the original method abstract: since each concrete class has its own copy, it will never be executed. abstract class Addressable { public abstract function render($template); } We eliminate impossible cases: now dynamic dispatch is doing the work of choosing which method to execute (instead of a chain of ifs). Brand and User only refer to their own methods and do not know anything about each other's presence. abstract class Addressable { public abstract function render($template); } class User extends Addressable { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function render($template) { return sprintf($template, $this->getName(), $this->getName()); } } class Brand extends Addressable { private $name; private $url; public function __construct($name, $url) { $this->name = $name; $this->url = $url; } public function getName() { return $this->name; } public function getURL() { return $this->url; } public function render($template) { return sprintf($template, $this->getUrl(), $this->getName()); } } The last step, although not strictly part of this refactoring, is to eliminate the getters since no one calls them from outside the class in this particular example. class User extends Addressable { private $name; public function __construct($name) { $this->name = $name; } public function render($template) { return sprintf($template, $this->name, $this->name); } } class Brand extends Addressable { private $name; private $url; public function __construct($name, $url) { $this->name = $name; $this->url = $url; } public function render($template) { return sprintf($template, $this->url, $this->name); } } We have now a solution where new classes can be added freely, and new Renderer can use all Addressable classes. It's a Bridge pattern, or just good factoring.
October 24, 2011
by Giorgio Sironi
· 11,991 Views
article thumbnail
How to Load or Save Image using Hibernate – MySQL
This tutorial will walk you throughout how to save and load an image from database (MySQL) using Hibernate. Requirements For this sampel project, we are going to use: Eclipse IDE (you can use your favorite IDE); MySQL (you can use any other database, make sure to change the column type if required); Hibernate jars and dependencies (you can download the sample project with all required jars); JUnit - for testing (jar also included in the sample project). PrintScreen When we finish implementing this sample projeto, it should look like this: Database Model Before we get started with the sample projet, we have to run this sql script into MySQL: DROP SCHEMA IF EXISTS `blog` ; CREATE SCHEMA IF NOT EXISTS `blog` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ; USE `blog` ; -- ----------------------------------------------------- -- Table `blog`.`BOOK` -- ----------------------------------------------------- DROP TABLE IF EXISTS `blog`.`BOOK` ; CREATE TABLE IF NOT EXISTS `blog`.`BOOK` ( `BOOK_ID` INT NOT NULL AUTO_INCREMENT , `BOOK_NAME` VARCHAR(45) NOT NULL , `BOOK_IMAGE` MEDIUMBLOB NOT NULL , PRIMARY KEY (`BOOK_ID`) ) ENGINE = InnoDB; This script will create a table BOOK, which we are going to use in this tutorial. Book POJO We are going to use a simple POJO in this project. A Book has an ID, a name and an image, which is represented by an array of bytes. As we are going to persist an image into the database, we have to use the BLOB type. MySQLhas some variations of BLOBs, you can check the difference between them here. In this example, we are going to use the Medium Blob, which can store L + 3 bytes, where L < 2^24. Make sure you do not forget to add the column definition on the Column annotation. package com.loiane.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; @Entity @Table(name="BOOK") public class Book { @Id @GeneratedValue @Column(name="BOOK_ID") private long id; @Column(name="BOOK_NAME", nullable=false) private String name; @Lob @Column(name="BOOK_IMAGE", nullable=false, columnDefinition="mediumblob") private byte[] image; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public byte[] getImage() { return image; } public void setImage(byte[] image) { this.image = image; } } Hibernate Config This configuration file contains the required info used to connect to the database. com.mysql.jdbc.Driver jdbc:mysql://localhost/blog root root org.hibernate.dialect.MySQLDialect 1 true Hibernate Util The HibernateUtil class helps in creating the SessionFactory from the Hibernate configuration file. package com.loiane.hibernate; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import com.loiane.model.Book; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { sessionFactory = new AnnotationConfiguration() .configure() .addPackage("com.loiane.model") //the fully qualified package name .addAnnotatedClass(Book.class) .buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } DAO In this class, we created two methods: one to save a Book instance into the database and another one to load a Book instance from the database. package com.loiane.dao; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import com.loiane.hibernate.HibernateUtil; import com.loiane.model.Book; public class BookDAOImpl { /** * Inserts a row in the BOOK table. * Do not need to pass the id, it will be generated. * @param book * @return an instance of the object Book */ public Book saveBook(Book book) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); session.save(book); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } return book; } /** * Delete a book from database * @param bookId id of the book to be retrieved */ public Book getBook(Long bookId) { Session session = HibernateUtil.getSessionFactory().openSession(); try { Book book = (Book) session.get(Book.class, bookId); return book; } catch (HibernateException e) { e.printStackTrace(); } finally { session.close(); } return null; } } Test To test it, first we need to create a Book instance and set an image to the image attribute. To do so, we need to load an image from the hard drive, and we are going to use the one located in the images folder. Then we can call the DAO class and save into the database. Then we can try to load the image. Just to make sure it is the same image we loaded, we are going to save it in the hard drive. package com.loiane.test; import static org.junit.Assert.assertNotNull; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.loiane.dao.BookDAOImpl; import com.loiane.model.Book; public class TestBookDAO { private static BookDAOImpl bookDAO; @BeforeClass public static void runBeforeClass() { bookDAO = new BookDAOImpl(); } @AfterClass public static void runAfterClass() { bookDAO = null; } /** * Test method for {@link com.loiane.dao.BookDAOImpl#saveBook()}. */ @Test public void testSaveBook() { //File file = new File("images\\extjsfirstlook.jpg"); //windows File file = new File("images/extjsfirstlook.jpg"); byte[] bFile = new byte[(int) file.length()]; try { FileInputStream fileInputStream = new FileInputStream(file); fileInputStream.read(bFile); fileInputStream.close(); } catch (Exception e) { e.printStackTrace(); } Book book = new Book(); book.setName("Ext JS 4 First Look"); book.setImage(bFile); bookDAO.saveBook(book); assertNotNull(book.getId()); } /** * Test method for {@link com.loiane.dao.BookDAOImpl#getBook()}. */ @Test public void testGetBook() { Book book = bookDAO.getBook((long) 1); assertNotNull(book); try{ //FileOutputStream fos = new FileOutputStream("images\\output.jpg"); //windows FileOutputStream fos = new FileOutputStream("images/output.jpg"); fos.write(book.getImage()); fos.close(); }catch(Exception e){ e.printStackTrace(); } } } To verify if it was really saved, let’s check the table Book: and if we right click… and choose to see the image we just saved, we will see it: Source Code Download You can download the complete source code (or fork/clone the project – git) from: Github: https://github.com/loiane/hibernate-image-example BitBucket: https://bitbucket.org/loiane/hibernate-image-example/downloads Happy Coding! From http://loianegroner.com/2011/10/how-to-load-or-save-image-using-hibernate-mysql/
October 24, 2011
by Loiane Groner
· 98,102 Views · 2 Likes
article thumbnail
Using a Java Servlet Filter to intercept the response HTTP status code with NetBeans IDE 7 and Maven
Version 2.3 of the Java servlet spec introduced the concept of filters. According to the documentation from Oracle’s site: “A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses”. Today I’ll show you how to build a simple filter to intercept the response HTTP response code using annotations introduced in the Servlet 3.0 specification. With NetBeans IDE 7 create a new Maven Java Web Application called: Intercept Delete the index.jsp file under the Web Pages folder. Right-click on the project and add a new servlet called: MainServlet Since we are using the new Servlet 3 annotations we don’t need to set a whole lot of properties. Maven generates a decent MainServlet.java file for us, I just removed the comments for the output. My file looks like this: package com.giantflyingsaucer.intercept; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "MainServlet", urlPatterns = {"/"}) public class MainServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println("Servlet MainServlet"); out.println(""); out.println(""); } finally { out.close(); } } // /** * Handles the HTTP GET method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP POST method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// } Right-click on the project and add a Filter called: InterceptFilter We will add the following two lines to the doFilter method. HttpServletResponse hsr = (HttpServletResponse) response; System.out.println("HTTP Status: " + hsr.getStatus()); My doFilter method looks like this: @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (debug) { log("InterceptFilter:doFilter()"); } doBeforeProcessing(request, response); HttpServletResponse hsr = (HttpServletResponse) response; System.out.println("HTTP Status: " + hsr.getStatus()); Throwable problem = null; try { chain.doFilter(request, response); } catch (Throwable t) { problem = t; t.printStackTrace(); } doAfterProcessing(request, response); if (problem != null) { if (problem instanceof ServletException) { throw (ServletException) problem; } if (problem instanceof IOException) { throw (IOException) problem; } sendProcessingError(problem, response); } } Clean and Build the project and deploy it to Apache Tomcat. Access the URL with a browser and take a look at your catalina.out file and you should see the HTTP response code. Note: You shouldn’t need to do any changes to the web.xml file for this project to work. From http://www.giantflyingsaucer.com/blog/?p=3279
October 23, 2011
by Chad Lung
· 43,941 Views
article thumbnail
JAXB (XJC) Imported Schemas and XML Catalogs
Import allows one XML schema to reference elements and types from another XML schema.
October 22, 2011
by Blaise Doughan
· 38,804 Views
article thumbnail
OpenStreetMap API framework for PHP
OpenStreetMap is a global project with an aim of collaboratively collecting map data, and today Ken Guest has submitted his PHP package for communitcating with the OSM API to the public and the PEAR PEPr review process: So over the last while, I’ve been working on a PHP package imaginatively named Services_Openstreetmap, for interacting with the openstreetmap API. I initially needed it so I could search for certain POIs and tabulate the results; it’s now also capable of adding data to the openstreetmap database – nodes and other elements can be created, updated and so on. It will even access the details of the user that is being used to modify that data, which is one difference between it and the other single purpose OSM frameworks. --Ken Guest You can view the submission here, and you should definitely take a look at openstreetmap.org if you haven't already. Good news for PHP developers looking to use this project more heavily in their applications.
October 22, 2011
by Mitch Pronschinske
· 16,324 Views
article thumbnail
Developing with HTML5, CoffeeScript and Twitter's Bootstrap
this article is the fourth in a series about my adventures developing a fitness tracking application with html5, play scala, coffeescript and jade. previous articles can be found at: integrating scalate and jade with play 1.2.3 trying to make coffeescript work with scalate and play integrating html5 boilerplate with scalate and play developing features after getting my desired infrastructure setup, i started coding like a madman. the first feature i needed was a stopwatch to track the duration of a workout, so i started writing one with coffeescript. after spending 20 minutes playing with dates and settimeout, i searched and found a stopwatch jquery plug-in . i added this to my app, deployed it to heroku , brought up the app on my iphone 3g, clicked start and started riding my bike to work. when i arrived, i unlocked my phone and discovered that the time had stopped. at first, i thought this was a major setback. my disappointed disappeared when i found a super neat javascript stopwatch and kåre byberg's version that worked just fine. this stopwatch used settimeout, so by keeping the start time, the app on the phone would catch up as soon as you unlocked it. i ported kåre's script to coffeescript and rejoiced in my working stopwatch. # created by kåre byberg © 21.01.2005. please acknowledge if used # on other domains than http://www.timpelen.com. # ported to coffeescript by matt raible. also added hours support. flagclock = 0 flagstop = 0 stoptime = 0 refresh = null clock = null start = (button, display) -> clock = display startdate = new date() starttime = startdate.gettime() if flagclock == 0 $(button).html("stop") flagclock = 1 counter starttime, display else $(button).html("start") flagclock = 0 flagstop = 1 counter = (starttime) -> currenttime = new date() timediff = currenttime.gettime() - starttime timediff = timediff + stoptime if flagstop == 1 if flagclock == 1 $(clock).val formattime timediff, "" callback = -> counter starttime refresh = settimeout callback, 10 else window.cleartimeout refresh stoptime = timediff formattime = (rawtime, roundtype) -> if roundtype == "round" ds = math.round(rawtime / 100) + "" else ds = math.floor(rawtime / 100) + "" sec = math.floor(rawtime / 1000) min = math.floor(rawtime / 60000) hour = math.floor(rawtime / 3600000) ds = ds.charat(ds.length - 1) start() if hour >= 24 sec = sec - 60 * min + "" sec = prependzerocheck sec min = min - 60 * hour + "" min = prependzerocheck min hour = prependzerocheck hour hour + ":" + min + ":" + sec + "." + ds prependzerocheck = (time) -> time = time + "" # convert from int to string unless time.charat(time.length - 2) == "" time = time.charat(time.length - 2) + time.charat(time.length - 1) else time = 0 + time.charat(time.length - 1) reset = -> flagstop = 0 stoptime = 0 window.cleartimeout refresh if flagclock == 1 resetdate = new date() resettime = resetdate.gettime() counter resettime else $(clock).val "00:00:00.0" @stopwatch = { start: start reset: reset } the scalate/jade template to render this stopwatch looks as follows: script(type="text/javascript" src={uri("/public/javascripts/stopwatch.coffee")}) #display input(id="clock" class="xlarge" type="text" value="00:00:00.0" readonly="readonly") #controls button(id="start" type="button" class="btn primary") start button(id="reset" type="button" class="btn :disabled") reset :plain next, i wanted to create a map that would show your location. for this, i used merge design's html 5 geolocation demo as a guide. the html5 geo api is pretty simple, containing only three methods: // gets the users current position navigator.geolocation.getcurrentposition(successcallback, errorcallback, options); // request repeated updates of position watchid = navigator.geolocation.watchposition(successcallback, errorcallback); // cancel the updates navigator.geolocation.clearwatch(watchid); after rewriting the geolocation example in coffeescript, i ended up with the following code in my map.coffee script. you'll notice it uses google maps javascript api to show an actual map with a marker. # geolocation with html 5 and google maps api based on example from maxheapsize: # http://maxheapsize.com/2009/04/11/getting-the-browsers-geolocation-with-html-5/ # this script is by merge database and design, http://merged.ca/ -- if you use some, # all, or any of this code, please offer a return link. map = null mapcenter = null geocoder = null latlng = null timeoutid = null initialize = -> if modernizr.geolocation navigator.geolocation.getcurrentposition showmap showmap = (position) -> latitude = position.coords.latitude longitude = position.coords.longitude mapoptions = { zoom: 15, maptypeid: google.maps.maptypeid.roadmap } map = new google.maps.map(document.getelementbyid("map"), mapoptions) latlng = new google.maps.latlng(latitude, longitude) map.setcenter(latlng) geocoder = new google.maps.geocoder() geocoder.geocode({'latlng': latlng}, addaddresstomap) addaddresstomap = (results, status) -> if (status == google.maps.geocoderstatus.ok) if (results[1]) marker = new google.maps.marker({ position: latlng, map: map }) $('#location').html('your location: ' + results[0].formatted_address) else alert "sorry, we were unable to geocode that address." start = -> timeoutid = settimeout initialize, 500 reset = -> if (timeoutid) cleartimeout timeoutid @map = { start: start reset: reset } the template to show the map is a mere 20 lines of jade: script(type="text/javascript" src="http://www.google.com/jsapi") script(type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false") :css .demo-map { border: 1px solid silver; height: 200px; margin: 10px auto; width: 280px; } #map(class="demo-map") p(id="location") span(class="label success") new | fetching your location with html 5 geolocation... script(type="text/javascript" src={uri("/public/javascripts/map.coffee")}) :javascript map.start(); the last two features i wanted were 1) distance traveled and 2) drawing the route taken on the map. for this i learned from a simple trip meter using the geolocation api . as i was beginning to port the js to coffeescript, i thought, "there's got to be a better way." i searched and found js2coffee to do most of the conversion for me. if you know javascript and you're learning coffeescript, this is an invaluable tool. i tried out the trip meter that night evening on a bike ride and noticed it said i'd traveled 3 miles when i'd really gone 6. i quickly figured out it was only calculating start point to end point and not taking into account all the turns in between. to view what was happening, i integrated my odometer.coffee with my map using google maps polylines . upon finishing the integration, i discovered two things, 1) html5 geolocation was highly inaccurate and 2) geolocation doesn't run in the background . i was able to solve the first problem by passing in {enablehighaccuracy: true} to navigator.geolocation.watchposition(). below are two screenshots showing before high accuracy and after. both screenshots are from the same two-block walk. the second issue is a slight show-stopper. phonegap might be able to solve the problem, but i'm currently using a workaround → turning off auto-lock and keeping safari in the foreground. making it look good after i got all my desired features developed, i moved onto making the app look good. i started by using sass for my css and installed play's sass module . i then switched to less when i discovered and added twitter's bootstrap to my project. at first i used play's less module (version 0.3), but ran into compilation issues . i then tried play's greenscript module , but gave up on it when i found it was incompatible with the coffeescript module . switching back to the less module and using the "0.3.compatibility" version solved all remaining issues. you might remember that i integrated html5 boilerplate and wondering why i have both bootstrap and boilerplate in my project. at this point, i don't think boilerplate is needed, but i've kept it just in case it's doing something for html5 cross-browser compatibility. i've renamed its style.css to style.less and added the following so it has access to bootstrap's variables. /* variables from bootstrap */ @import "libs/variables.less"; then i made my app look a lot better with layouts, stylish forms , a fixed topbar and alerts . for example, here's the coffeescript i wrote to display geolocation errors: geolocationerror = (error) -> msg = 'unable to locate position. ' switch error.code when error.timeout then msg += 'timeout.' when error.position_unavailable then msg += 'position unavailable.' when error.permission_denied then msg += 'please turn on location services.' when error.unknown_error then msg += error.code $('.alert-message').remove() alert = $('') alert.html('×' + msg); alert.insertbefore($('.span10')) then i set about styling up the app so it looked good on a smartphone with css3 media queries . below is the less code i used to hide elements and squish the widths for smaller devices. @media all and (max-device-width: 480px) { /* hide scrollbar on mobile */ html { overflow-y:hidden } /* hide sidebar on mobile */ .home .span4, .home .page-header, .topbar form { display: none } .home .container { width: 320px; } .about { .container, .span10 { width: 280px; } .span10 { padding-top: 0px; } } tools in the process of developing a stopwatch, odometer, displaying routes and making everything look good, i used a number of tools. i started out primarily with textmate and its bundles for less , coffeescript and jade . when i started writing more scala, i installed the scala textmate bundle . when i needed some debugging, i switched to intellij and installed its scala plugin. coffeescript, less and haml plugins (for jade) were already installed by default. i also used james ward's setup play framework with scala in intellij . issues i think it's obvious that my biggest issue so far is the fact that a webapp can't multitask in the background like a native app can. beyond that, there's accuracy issues with html5's geolocation that i haven't seen in native apps. i also ran into a caching issue when calling getcurrentposition(). it only worked the first time and i had to refresh my browser to get it to work again. strangely enough, this only happened on my desktop (in safari and firefox) and worked fine on my iphone. unfortunately, it looks like phonegap has issues similar to this. my workaround for no webapp multitasking is turning off auto-lock and leaving the browser in the foreground while i exercise. the downside to this is it really drains the battery quickly (~ 3 hours). i constantly have to charge my phone if i'm testing it throughout the day. the testing is a real pain too. i have to deploy to heroku (which is easy enough), then go on a walk or bike ride. if something's broke, i have to return home, tweak some things, redeploy and go again. also, there's been a few times where safari crashes halfway through and i lose all the tracking data. this happens with native apps too, but seemingly not as often. if you'd like to try the app on your mobile phone and see if you experience these issues, checkout play-more.com . summary going forward, there's still more html5 features i'd like to use. in particular, i'd like to play music while the fitness tracker is running. i'd love it if cloud music services (e.g. pandora or spotify) had an api i could use to play music in a webapp. soundcloud might be an option, but i've also thought of just uploading some mp3s and playing them with the tag. i've really enjoyed developing with all these technologies and haven't experienced much frustration so far. the majority has come from integrating scalate into play, but i've resolved most problems. next, i'll talk about how i've improved play's scalate support and my experience working with anorm . source: http://raibledesigns.com/rd/entry/developing_with_html5_coffeescript_and
October 21, 2011
by Matt Raible
· 17,483 Views · 1 Like
article thumbnail
Dynamic subtyping in Java
Subtyping Issues in Java Behavior customization is a common requirement for large software systems. A software product cannot fully satisfy requirements of all customers; there are always differences that must be implemented, which are specific to each customer. Thus, software products must be flexible enough to allow these customizations in behavior even without changes in product's source code. In Java-based software products, a solution for such problems is usually based on a principle called subtyping. Subtyping can be defined on an example of two types A and B: if type B is a subtype of type A, then all code that operates correctly on objects of type A will operate correctly on objects of type B. Naturally, a software product behavior can be customized by replacing some default class A with custom class B where B is a subtype of A. If subtyping is based on an interface, then implementations of the interface can be independent of each other, which decreases complexity of the system and benefits modularity. At the same time such independence limits code reusability. A custom implementation can use Delegation pattern to call methods, but it is impossible to override a method in the base class. Another approach for subtyping is direct subclassing of the implementation class. Subclassing allows method overriding in the base class and also introduces design-time dependencies on that class. These dependencies limit subclass reusability. As you can see standard Java subtyping techniques limit reusability of either a base class or a subclass. Dynamic subtyping The approach described below combines the advantages of standard Java subtyping techniques. It allows creation of a new class, which can override methods in an original class, but at the same time, is dependent only on the interface of the original. Let's start with the following example: Suppose we have an interface Action as described below and its implementation in form of class ActionImpl. //This is an interface of Action public interface Action{ void doAction1(); void doAction2(); void doAll(); } //This is a default implementation of the interface Action class ActionImpl implements Action{ public void doAction1(){ ... } public void doAction2(){ ... } public void doAll(){ doAction1(); doAction2(); } } Class ActionImpl implements all methods of the interface and is used as a default implementation. Now let's suppose we want to override method doAction2 in the ActionImpl in such a way that the new class won't depend on ActionImpl. Let's create a new class ActionExtension as the following: //This is a custom implementation that overrides one method. abstract class ActionExtension extends ImplementationOf implements Action{ public void doAction2(){ … Super.doAction2(); } } This class extends a simple base class which looks like this: //This is base class for dynamic subclasses public abstract class ImplementationOf{ /** * A field for calling super class methods. * Should be used only in expressions where super keyword can be used. * */ protected final T Super = null; } Note that ActionExtension class is an abstract class, so we don't have to define all methods, just those that we want to override in ActionImpl. That's all we need to do at design time. Now let's look how it works at run-time. At the point of code where instance of Action is expected we need to create a new class: //Fragment of code that creates dynamic subclass of ActionImpl Class dynamicSubclass = DynamicClassExtender.extend(ActionImpl.class, Action.class, ActionExtension.class); The created class is a subclass of ActionImpl and contains all methods copied from ActionExtension class and modified in such a way that all calls to methods of Super field are directed to ActionImpl class. This class can be used to create an instance which can be used instead of instance of ActionImpl class: Action action = (Action) dynamicSubclass.newInstance(); In the real product the code above should be integrated into a dependency injection framework of your choice, and actual mapping of extension classes to implementations should be configurable. Dynamic class extender From the previous chapter we saw that all the complexities of dynamic subclassing are hidden in DynamicClassExtender class, which uses a byte code manipulation library to create a direct subclass of ActionImpl from ActionExtension class. In order to see what kind of byte code manipulation is involved let's start with ActionExtender class decompiled using standard javap utility: public abstract class ActionExtension extends ImplementationOf implements Action{ public ActionExtension(); Code: 0: aload_0 1: invokespecial #10; //Method ImplementationOf."":()V 4: return public void doAction2(); Code: 0: aload_0 1: getfield #17; //Field Super:Ljava/lang/Object; 4: checkcast #5; //class Action 7: invokeinterface #21, 1; //InterfaceMethodAction.doAction2:()V 12: return } Now if we manually create a class that extends ActionImpl and overrides doAction2 method and then decompile it with javap we'll see the following byte code: public class ActionExtension$ActionImpl extends ActionImpl{ public ActionExtension$ActionImpl(); Code: 0: aload_0 1: invokespecial #8; //Method ActionImpl."":()V 4: return public void doAction2(); Code: 0: aload_0 1: invokespecial #15; //Method ActionImpl.doAction2:()V 4: return } After comparing byte codes from both classes we can figure out a list of manipulations that DynamicClassExtender must apply on ActionExtension class in order to create a dynamic subclass of ActionImpl: change class name to ActionExtension$ActionImpl change access attribute to public, remove abstract attribute change super class name to ActionImpl replace references to ImplementationOf with references to ActionImpl replace method invocations on Super field (instructions 1,4,7 in ActionExtension.doAction2) with method invocations in super class (instruction 1 in ActionExtension$ActionImpl.doAction2) You can find a proof-of-concept implementation of DynamicClassExtender in the zip file attached to this article. The source code is distributed under the terms of BSD License. Conclusion The dynamic approach for subtyping, presented above, may help to create customizable Java applications without sharing implementation source code and without sacrificing code reusability.
October 20, 2011
by Alex Antonau
· 11,971 Views · 2 Likes
  • Previous
  • ...
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • ...
  • 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
×