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

Events

View Events Video Library

Latest Articles - DZone

article thumbnail
All the mouse events in JavaScript
The HTML 5 specification is full of definitions of new events, but it gathers them in a long list only divided by the category of support: some must be supported by all elements, some by window and derivatives, and so on. Unfortunately this style mixes up many different kinds of events, like the multimedia (canplay) and keyboard-based ones (keyup). In this article, I have collected all events that can be generated with a mouse. In HTML 4 There are a few well-supported events ported by the previous version of the specification. Everyone would expect a browser to correctly fire these events: click: the simplest event. dblclick: fired on a double click on an HTML element. mousedown: fired when the button is pressed. mouseup: fired when the button is released. mouseover: fired when the cursor passes over an HTML element. mouseout: fired when the cursor leaves the displaying area of an HTML element; the inverse of mouseover. mousemove: fired everytime the cursor moves one pixel. It's very easy to hang the browser by targeting this event. In any case, window.addEventListener and element.addEventListener (where element is a reference to a DOM element) are the functions to call to setup event handlers. You could also use the on$eventName HTML attribute or property (e.g. onclick, onmouseover), but addEventListener is more flexible as it allows for many different listeners to work on the same event, without one silently replacing the other. HTML 5: dragging Most of the new mouse events (but not necessarily the most interesting ones) deal with drag and drop support: drag: fired frequently on a dragged element (which must define the *draggable* attribute.) dragstart: fired when the mouse is held down on an element and the movement starts. dragend: fired when the element is released. dragenter: fired when an element enters the displayed area of another one. dragleave: fired when an element exits the displayed area, as the inverse of dragenter. dragover: fired frequently when an element is over another. drop: fired when an element is released over another. drag, dragstart, and dragend are fired on the dragged element, while dragenter, dragleave, dragover and drop are fired on the target one. Here is a self-contained example of their usage: One of the common usages of the Drag and Drop API is the integration with the File API to allow for upload of files by dragging into the browser's window. HTML 5: the wheel The mousewheel event is fired upon the usage of the wheel over an element or the window. Here is an example that zooms in or out of an HTML element by modifying its size: The scroll event instead works at an higher-level of abstraction: it is not really a mouse-specific event, as it can be generated by the mouse but also by pressing scrolling keys. What the event models is a change in the visible section of an element, generated by a movement in the vertical or horizontal scrollbars: Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... Lorem ipsum dolor amet... HTML 5: right click The contextmenu event is fired upon a right click, that opens a contextual menu centered on the mouse pointer. Here is an example of interception: If you want to display an alternate contextual menu, you would also probably want to cancel the event; however, many browsers allow the user to override these manipulations and always show the original menu (think of websites hiding the View Source entry).
March 7, 2012
by Giorgio Sironi
· 79,769 Views
article thumbnail
Connecting to Multiple Databases Using Hibernate
In a recent project, I had a requirement of connecting to multiple databases using hibernate. As tapestry-hibernate module does not provide an out-of-box support, I thought of adding one. https://github.com/tawus/tapestry5 Now that the application is in production, I thought of writing a simple “How to”. I have cloned the latest stable(5.3.2) tapestry project at https://github.com/tawus/tapestry5 and have added multiple database support to it. Single Database It is almost fully compatible with the previous integration when using a single database except for a few things 1) HibernateConfigurer has changed public interface HibernateConfigurer { /** * Passed the configuration so as to make changes. */ void configure(Configuration configuration); /** * Factory Id for which this configurer is meant for */ Class getMarker(); /** * Entity package names * * @return */ String[] getPackageNames(); } 2) There is no HibernateEntityPackageManager, as the packages can be contributed by adding more HibernateConfigurers with the same Markers. Multiple databases For multiple database, a marker has to be used for accessing Session or HibernateSessionManager @Inject @XDB private Session session; @Inject @YDB private HibernateSessionManager sessionManager; @XDB @CommitAfter void myMethod(){ } Also you have to define a HibernateSessionManager and a Session for the secondary database in the Module class. @Scope(ScopeConstants.PERTHREAD) @Marker(DatabaseTwo.class) public static HibernateSessionManager buildHibernateSessionManagerForFinacle( HibernateSessionSource sessionSource, PerthreadManager perthreadManager) { HibernateSessionManagerImpl service = new HibernateSessionManagerImpl(sessionSource, DatabaseTwo.class); perthreadManager.addThreadCleanupListener(service); return service; } @Marker(DatabaseTwo.class) public static Session buildSessionForFinacle( @Local HibernateSessionManager sessionManager, PropertyShadowBuilder propertyShadowBuilder) { return propertyShadowBuilder.build(sessionManager, "session", Session.class); } Notice an annotation @DatabaseTwo.class. This is a Factory marker and is used to identify a service related to a particular SessionFactory. @Retention(RetentionPolicy.RUNTIME) @Target( {ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @FactoryMarker @Documented public @interface DatabaseTwo { } A typical AppModule for two databases will be public class AppModule { public static void bind(ServiceBinder binder) { binder.bind(DemoService.class, DemoServiceImpl.class); } @Contribute(HibernateSessionSource.class) public static void configureHibernateSources(OrderedConfiguration configurers) { configurers.add("databaseOne", new HibernateConfigurer() { public void configure(org.hibernate.cfg.Configuration configuration) { configuration.configure("/databaseOne.xml"); } public Class getMarker() { return DefaultFactory.class; } public String[] getPackageNames() { return new String[] {"org.example.demo.one"}; } }); configurers.add("databaseTwo", new HibernateConfigurer() { public void configure(org.hibernate.cfg.Configuration configuration) { configuration.configure("/databaseTwo.xml"); } public Class getMarker() { return DatabaseTwo.class; } public String[] getPackageNames() { return new String[] {"org.example.demo.two"}; } }); } @Contribute(SymbolProvider.class) @ApplicationDefaults public static void addSymbols(MappedConfiguration configuration) { configuration.add(HibernateSymbols.DEFAULT_CONFIGURATION, "false"); configuration.add("tapestry.app-package", "org.example.demo"); } @Scope(ScopeConstants.PERTHREAD) @Marker(DatabaseTwo.class) public static HibernateSessionManager buildHibernateSessionManagerForFinacle( HibernateSessionSource sessionSource, PerthreadManager perthreadManager) { HibernateSessionManagerImpl service = new HibernateSessionManagerImpl(sessionSource, DatabaseTwo.class); perthreadManager.addThreadCleanupListener(service); return service; } @Marker(DatabaseTwo.class) public static Session buildSessionForFinacle( @Local HibernateSessionManager sessionManager, PropertyShadowBuilder propertyShadowBuilder) { return propertyShadowBuilder.build(sessionManager, "session", Session.class); } } Injecting into Services You can inject a session in a service using the marker. As DatabaseOne is being used as the default configuration, in order to inject its Session, you have to annotate it with @DefaultFactory. For DatabaseTwo, you can use @DatabaseTwo annotation. public class DemoServiceImpl implements DemoService { private Session sessionOne; private Session sessionTwo; public DemoServiceImpl( @DefaultFactory Session sessionOne, @DatabaseTwo Session sessionTwo) { this.sessionOne = sessionOne; this.sessionTwo = sessionTwo; } @SuppressWarnings("unchecked") public List listOnes() { return sessionOne.createCriteria(EntityOne.class).list(); } @SuppressWarnings("unchecked") public List listTwos() { return sessionTwo.createCriteria(EntityTwo.class).list(); } public void save(EntityOne entityOne) { sessionOne.saveOrUpdate(entityOne); } public void save(EntityTwo entityTwo) { sessionTwo.saveOrUpdate(entityTwo); } } Using @CommitAfter You can add an advice the same way you used to. The only change is in @CommitAfter. You have to additionally annotate the method with the respective marker. public interface DemoService { List listOnes(); List listTwos(); @CommitAfter @DefaultFactory void save(EntityOne entityOne); @CommitAfter @DatabaseTwo void save(EntityTwo entityTwo); } Here is an example. From http://tawus.wordpress.com/2012/03/03/tapestry-hibernate-multiple-databases/
March 7, 2012
by Taha Siddiqi
· 100,334 Views · 3 Likes
article thumbnail
The Two Hand Rule for Meandering Stand Ups
when working with agile teams the daily stand up meeting provides a heart beat to the day and an opportunity for team members to share information. stand up meetings work best when they are short and balance the inputs across all the people in the team. a common problem is stand ups that start running too long. when two hands are raised then it's a signal to move the stand up meeting on the two hands rule sometimes the conversations at stand up can get too detailed or go on too long. for these situations we’ve introduced the “two hands” rule; if anyone thinks the current conversation has gone off topic, or is no longer effective, then they raise a hand. once a second person raises a hand then that’s a sign to stop the conversation and continue with the rest of the stand up. those speaking can continue the conversation after the stand up has finished. this approach makes it easy for people to share their view on the effectiveness of the conversation in a way that reduces the risk of causing offence. it also provides a way for the team to detect and correct its own behaviour. i introduced this idea recently to a team who agreed to give it a try. in a stand up a few days later i was talking with a team member and didn’t realise that our conversation had got too detailed and gone on too long. i missed seeing that two other team members had put their hands up. it wasn’t until one of them spoke up that i noticed! this is one of the characteristics of difficult conversations; we often become blind to signs, easily spotted by others, that the conversation has become ineffective. by agreeing with the team to use the “two hands” rule they helped me detect when they thought i’d become ineffective. the technique can have some downsides though. it can feel direct or confrontational, especially when people first experience it. it’s important to discuss any issues after the stand up and consider reviewing the practice in a retrospective. i’d like to hear your thoughts. have you had stand up meetings that have taken too long? what approaches have you used? if you’ve tried something like the “two hands” rule, how did it go?
March 6, 2012
by Benjamin Mitchell
· 9,083 Views · 1 Like
article thumbnail
Blobs and More: Storing Images and Files in IndexedDB
The desired future approach for storing things client-side in web browsers is utilizing IndexedDB. Here I’ll walk you through how to store images and files in IndexedDB and then present them through an ObjectURL. The general approach First, let’s talk about the steps we will go through to create an IndexedDB data base, save the file into it and then read it out and present in the page: Create or open a database. Create an objectStore (if it doesn’t already exist) Retrieve an image file as a blob Initiate a database transaction Save that blob into the database Read out that saved file and create an ObjectURL from it and set it as the src of an image element in the page Creating the code Let’s break down all parts of the code that we need to do this: Create or open a database. // IndexedDB var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB, IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction, dbVersion = 1; // Create/open database var request = indexedDB.open("elephantFiles", dbVersion); request.onsuccess = function (event) { console.log("Success creating/accessing IndexedDB database"); db = request.result; db.onerror = function (event) { console.log("Error creating/accessing IndexedDB database"); }; // Interim solution for Google Chrome to create an objectStore. Will be deprecated if (db.setVersion) { if (db.version != dbVersion) { var setVersion = db.setVersion(dbVersion); setVersion.onsuccess = function () { createObjectStore(db); getImageFile(); }; } else { getImageFile(); } } else { getImageFile(); } } // For future use. Currently only in latest Firefox versions request.onupgradeneeded = function (event) { createObjectStore(event.target.result); }; The intended way to use this is to have the onupgradeneeded event triggered when a database is created or gets a higher version number. This is currently only supported in Firefox, but will soon be in other web browsers. If the web browser doesn’t support this event, you can use the deprecated setVersion method and connect to its onsuccess event. Create an objectStore (if it doesn’t already exist) // Create an objectStore console.log("Creating objectStore") dataBase.createObjectStore("elephants"); Here you create an ObjectStore that you will store your data – or in our case, files – and once created you don’t need to recreate it, just update its contents. Retrieve an image file as a blob // Create XHR var xhr = new XMLHttpRequest(), blob; xhr.open("GET", "elephant.png", true); // Set the responseType to blob xhr.responseType = "blob"; xhr.addEventListener("load", function () { if (xhr.status === 200) { console.log("Image retrieved"); // File as response blob = xhr.response; // Put the received blob into IndexedDB putElephantInDb(blob); } }, false); // Send XHR xhr.send(); This code gets the contents of a file as a blob directly. Currently that’s only supported in Firefox. Once you have received the entire file, you send the blob to the function to store it in the database. Initiate a database transaction // Open a transaction to the database var transaction = db.transaction(["elephants"], IDBTransaction.READ_WRITE); To start writing something to the database, you need to initiate a transaction with an objectStore name and the type of action you want to do – in this case read and write. Save that blob into the database // Put the blob into the dabase transaction.objectStore("elephants").put(blob, "image"); Once the transaction is in place, you get a reference to the desired objectStore and then put your blob into it and give it a key. Read out that saved file and create an ObjectURL from it and set it as the src of an image element in the page // Retrieve the file that was just stored transaction.objectStore("elephants").get("image").onsuccess = function (event) { var imgFile = event.target.result; console.log("Got elephant!" + imgFile); // Get window.URL object var URL = window.URL || window.webkitURL; // Create and revoke ObjectURL var imgURL = URL.createObjectURL(imgFile); // Set img src to ObjectURL var imgElephant = document.getElementById("elephant"); imgElephant.setAttribute("src", imgURL); // Revoking ObjectURL URL.revokeObjectURL(imgURL); }; Use the same transaction to get the image file you just stored, and then create an objectURL and set it to the src of an image in the page. This could just as well, for instance, have been a JavaScript file that you attached to a script element, and then it would parse the JavaScript. The complete code So, here’s the complete working code: (function () { // IndexedDB var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB, IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction, dbVersion = 1.0; // Create/open database var request = indexedDB.open("elephantFiles", dbVersion), db, createObjectStore = function (dataBase) { // Create an objectStore console.log("Creating objectStore") dataBase.createObjectStore("elephants"); }, getImageFile = function () { // Create XHR var xhr = new XMLHttpRequest(), blob; xhr.open("GET", "elephant.png", true); // Set the responseType to blob xhr.responseType = "blob"; xhr.addEventListener("load", function () { if (xhr.status === 200) { console.log("Image retrieved"); // Blob as response blob = xhr.response; console.log("Blob:" + blob); // Put the received blob into IndexedDB putElephantInDb(blob); } }, false); // Send XHR xhr.send(); }, putElephantInDb = function (blob) { console.log("Putting elephants in IndexedDB"); // Open a transaction to the database var transaction = db.transaction(["elephants"], IDBTransaction.READ_WRITE); // Put the blob into the dabase var put = transaction.objectStore("elephants").put(blob, "image"); // Retrieve the file that was just stored transaction.objectStore("elephants").get("image").onsuccess = function (event) { var imgFile = event.target.result; console.log("Got elephant!" + imgFile); // Get window.URL object var URL = window.URL || window.webkitURL; // Create and revoke ObjectURL var imgURL = URL.createObjectURL(imgFile); // Set img src to ObjectURL var imgElephant = document.getElementById("elephant"); imgElephant.setAttribute("src", imgURL); // Revoking ObjectURL URL.revokeObjectURL(imgURL); }; }; request.onerror = function (event) { console.log("Error creating/accessing IndexedDB database"); }; request.onsuccess = function (event) { console.log("Success creating/accessing IndexedDB database"); db = request.result; db.onerror = function (event) { console.log("Error creating/accessing IndexedDB database"); }; // Interim solution for Google Chrome to create an objectStore. Will be deprecated if (db.setVersion) { if (db.version != dbVersion) { var setVersion = db.setVersion(dbVersion); setVersion.onsuccess = function () { createObjectStore(db); getImageFile(); }; } else { getImageFile(); } } else { getImageFile(); } } // For future use. Currently only in latest Firefox versions request.onupgradeneeded = function (event) { createObjectStore(event.target.result); }; })(); Web browser support IndexedDB Supported since long (a number of versions back) in Firefox and Google Chrome. Planned to be in IE10, unclear about Safari and Opera. onupgradeneeded Supported in latest Firefox. Planned to be in Google Chrome soon and hopefully IE10. Unclear about Safari and Opera. Storing files in IndexedDB Supported in Firefox 11 and later. Planned to be supported in Google Chrome. Hopefully IE10 will support it. Unclear about Safari and Opera. XMLHttpRequest Level 2 Supported in Firefox and Google Chrome since long, Safari 5+ and planned to be in IE10 and Opera 12. responseType “blob” Currently only supported in Firefox. Will soon be in Google Chrome and is planned to be in IE10. Unclear about Safari and Opera. Demo and code I’ve put together a demo with IndexedDB and saving images and files in it where you can see it all in action. Make sure to use any Developer Tool to Inspect Element on the image to see the value of its src attribute. Also make sure to check the console.log messages to follow the actions. The code for storing files in IndexedDB is also available on GitHub, so go play now!
March 6, 2012
by Robert Nyman
· 23,910 Views
article thumbnail
Viewing JavaFX 2 Standard Colors
The JavaFX 2 class javafx.scene.paint.Color includes several fields that are static Color members. I have taken advantage of the convenience of these publicly available static fields in many of my JavaFX 2 examples shown in this blog. There is a lengthy list of these predefined Color fields ranging (in alphabetical order) from Color.ALICEBLUE to Color.YELLOWGREEN. I have sometimes thought it would be nice to quickly see what some of the less obvious colors look like and the simple JavaFX 2 application featured in this post provides a sampling of those colors. The sample JavaFX 2 application shown here uses simple Java reflection to introspect the JavaFX Color class for its public fields that themselves of type Color. The application then iterates over those public fields, providing information about each color such as the color's field name, a sample of the color, and the red/green/blue components of that color. The final row allows the user to specify red/green/blue values to see how such a color is rendered. This is useful if the user sees a standard color that is close to what he or she wants and the user wants to try adjusting it slightly. To ensure meaningful values for displaying a color based on provided red/green/blue values, the application ensures that entered values are treated as doubles between 0.0 and 1.0 even if they are not numbers or are numbers outside of that range. The simple JavaFX 2 application showing standard Color fields is shown in the next code listing. JavaFxColorDemo.java package dustin.examples; import static java.lang.System.err; import java.lang.reflect.Field; import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.scene.shape.RectangleBuilder; import javafx.stage.Stage; /** * Simple JavaFX 2 application that prints out values of standardly available * Color fields. * * @author Dustin */ public class JavaFxColorDemo extends Application { /** Width of label for colorn name. */ private final static int COLOR_NAME_WIDTH = 150; /** Width of rectangle that displays color. */ private final static int COLOR_RECT_WIDTH = 50; /** Height of rectangle that displays color. */ private final static int COLOR_RECT_HEIGHT = 25; private final TextField redField = TextFieldBuilder.create() .text("Red Value").build(); private final TextField greenField = TextFieldBuilder.create() .text("Green Value").build(); private final TextField blueField = TextFieldBuilder.create() .text("Blue Value").build(); private final Rectangle customColorRectangle = RectangleBuilder.create() .width(COLOR_RECT_WIDTH).height(COLOR_RECT_HEIGHT) .fill(Color.WHITE).stroke(Color.BLACK).build(); /** * Build a pane containing details about the instance of Color provided. * * @param color Instance of Color about which generated Pane should describe. * @return Pane representing information on provided Color instance. */ private Pane buildColorBox(final Color color, final String colorName) { final HBox colorBox = new HBox(); final Label colorNameLabel = new Label(colorName); colorNameLabel.setMinWidth(COLOR_NAME_WIDTH); colorBox.getChildren().add(colorNameLabel); final Rectangle colorRectangle = new Rectangle(COLOR_RECT_WIDTH, COLOR_RECT_HEIGHT); colorRectangle.setFill(color); colorRectangle.setStroke(Color.BLACK); colorBox.getChildren().add(colorRectangle); final String rgbString = String.valueOf(color.getRed()) + " / " + String.valueOf(color.getGreen()) + " / " + String.valueOf(color.getBlue()) + " // " + String.valueOf(color.getOpacity()); final Label rgbLabel = new Label(rgbString); rgbLabel.setTooltip(new Tooltip("Red / Green / Blue // Opacity")); colorBox.getChildren().add(rgbLabel); return colorBox; } /** * Extracts a double between 0.0 and 1.0 inclusive from the provided String. * * @param colorString String from which a double is extracted. * @return Double between 0.0 and 1.0 inclusive based on provided String; * will be 0.0 if provided String cannot be parsed. */ private double extractValidColor(final String colorString) { double colorValue = 0.0; try { colorValue = Double.valueOf(colorString); } catch (Exception exception) { colorValue = 0.0; err.println("Treating '" + colorString + "' as " + colorValue); } finally { if (colorValue < 0) { colorValue = 0.0; err.println("Treating '" + colorString + "' as " + colorValue); } else if (colorValue > 1) { colorValue = 1.0; err.println("Treating '" + colorString + "' as " + colorValue); } } return colorValue; } /** * Build pane with ability to specify own RGB values and see color. * * @return Pane with ability to specify colors. */ private Pane buildCustomColorPane() { final HBox customBox = new HBox(); final Button button = new Button("Display Color"); button.setPrefWidth(COLOR_NAME_WIDTH); button.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent t) { final Color customColor = new Color(extractValidColor(redField.getText()), extractValidColor(greenField.getText()), extractValidColor(blueField.getText()), 1.0); customColorRectangle.setFill(customColor); } }); customBox.getChildren().add(button); customBox.getChildren().add(this.customColorRectangle); customBox.getChildren().add(this.redField); customBox.getChildren().add(this.greenField); customBox.getChildren().add(this.blueField); return customBox; } /** * Build the main pane indicating JavaFX 2's pre-defined Color instances. * * @return Pane containing JavaFX 2's pre-defined Color instances. */ private Pane buildColorsPane() { final VBox colorsPane = new VBox(); final Field[] fields = Color.class.getFields(); // only want public for (final Field field : fields) { if (field.getType() == Color.class) { try { final Color color = (Color) field.get(null); final String colorName = field.getName(); colorsPane.getChildren().add(buildColorBox(color, colorName)); } catch (IllegalAccessException illegalAccessEx) { err.println( "Securty Manager does not allow access of field '" + field.getName() + "'."); } } } colorsPane.getChildren().add(buildCustomColorPane()); return colorsPane; } /** * Start method overridden from parent Application class. * * @param stage Primary stage. * @throws Exception JavaFX application exception. */ @Override public void start(final Stage stage) throws Exception { final Group rootGroup = new Group(); final Scene scene = new Scene(rootGroup, 700, 725, Color.WHITE); final ScrollPane scrollPane = new ScrollPane(); scrollPane.setPrefWidth(scene.getWidth()); scrollPane.setPrefHeight(scene.getHeight()); scrollPane.setContent(buildColorsPane()); rootGroup.getChildren().add(scrollPane); stage.setScene(scene); stage.setTitle("JavaFX Standard Colors Demonstration"); stage.show(); } /** * Main function for running JavaFX application. * * @param arguments Command-line arguments; none expected. */ public static void main(final String[] arguments) { Application.launch(arguments); } } The snapshots shown next demonstrate this simple application. The first snapshot shows the application after loading. The second snapshot shows the application after scrolling down to the bottom and demonstrates use of the Tooltip and of the TextField.setPrompt(String) method. The third image shows the results of providing red/green/blue values and clicking on the button to see the corresponding color. The simple JavaFX 2 application shown in this post makes it easy to get an idea of what colors are available as standard JavaFX 2 public static Color fields. It also allows one to enter red/green/blue values that might be provided to the Color constructor to obtain an instance of Color. From http://marxsoftware.blogspot.com/2012/02/viewing-javafx-2-standard-colors.html
March 6, 2012
by Dustin Marx
· 24,624 Views · 1 Like
article thumbnail
A Hard Fact About Transaction Management In Spring
In my Hibernate hard facts article series, I tackled some misconceptions about Hibernate: there are plenty of developers using Hibernate (myself including) that do not use it correctly, sometimes from a lack of knowledge. The same can be said about many complex products, but I was dumbfounded this week when I was faced with such a thing in the Spring framework. Surely, something as pragmatic as Spring couldn’t have shadowy areas in some corner of its API. About Spring’s declarative transaction boundaries Well, I’ve found at least one, in regard to declarative transaction boundaries: Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad. From Spring’s documentation Guess what? Even though it would be nice to have transactional behavior as part of the contract, it’s sadly not the case as it depends on your context configuration, as stated in the documentation! To be sure, I tried and it’s (sadly) true. Consider the following contract and implementation : public interface Service { void forcedTransactionalMethod(); @Transactional void questionableTransactionalMethod(); } public class ImplementedService implements Service { private DummyDao dao; public void setDao(DummyDao dao) { this.dao = dao; } @Transactional public void forcedTransactionalMethod() { dao.getJdbcTemplate().update("INSERT INTO PERSON (NAME) VALUES ('ME')"); } public void questionableTransactionalMethod() { dao.getJdbcTemplate().update("INSERT INTO PERSON (NAME) VALUES ('YOU')"); } } Now, depending on whether we activate the CGLIB proxy, the questionableTransactionMethod behaves differently, committing in one case and not in the other. Note: for Eclipse users – even without Spring IDE, this is shown as a help popup when CTRL-spacing for a new attribute (it doesn’t show when the attribute already exists in the XML though). Additional facts for proxy mode Spring’s documentation also documents two other fine points that shouldn’t be lost on developers when using proxies (as opposed to AspectJ weaving): Only annotate public methods. Annotating methods with other visibilities will do nothing – truly nothing – as no errors will be raised to warn you something is wrong Be wary of self-invocation. Since the transactional behavior is based on proxys, a method of the target object calling another of its method won’t lead to transactional behavior even though the latter method is marked as transactional Both those limitations can be removed by weaving the transactional behavior inside the bytecode instead of using proxies (but not the first limitation regarding annotations on interfaces). To go further: Spring’s documentation regarding transaction management You can found the sources for this article in Eclipse/Maven format here (but you’ll have to configure a MySQL database instance). From http://blog.frankel.ch/a-spring-hard-fact-about-transaction-management
March 5, 2012
by Nicolas Fränkel
· 17,776 Views
article thumbnail
Why Having "DevOps" in a Job Title Makes Sense
We’ve been trying to grow our team for a few months now and the title we’re hiring for is Devops Engineer. One of the candidates our recruiters reached out to, let’s call him John, came back to us with a bunch of questions including: How do you feel about hiring someone with a devops title? It’s a very legittimate question, Devops is a cultural and professional movement, so how could it be a job title? What I argued in my reply to this fella is that Devops isn’t the job title, Devops Engineer is, and in this sense Devops is just a qualifier and I strongly believe a very useful one. I really sympathise with those that are fighting hard to keep Devops real and avoid the same faith that some refer to as the sad commercialisation of Agile. My campaign to make of devops a job title isn’t a campaign to come up with a set of bullet points that define Devops as a job so that I can put it on a resume or build it into a product. My argument here is that the guy I’m trying to hire, John, I want him to be a certain kind of guy and the best way I have to describe what I want is Devops Engineer. I’m looking for an operations guy , but I want him to be open to developers, consider engineering and the company as a whole, be focused on delivering value and not rathole into fights about technology or claim root access only on principle. I want that guy to have great communication skills and the interest to explore what’s besides his infrastructure, to be wanting to borrow as much good he can find in other disciplines across the organisation. And then of course there is the practical part, the desire to automate and escape a boring manual routine, the familiarity with cloud that willing or not has powered the movement, and even more specific things like configuration management. You may argue that this is just a good engineer or what systems engineers are becoming, in other words nothing new under the sun. And you may be right, but job titles are in many ways just another way to communicate, to broadcast an intent and a need. So you know what I told John about hiring Devops Engineers? That I felt pretty damn proud about it. The true ones, not the ones slapping it on their CV to get a job, are fantastic engineers and I can’t but encourage them to start to respond to that qualifier. Likewise the companies and individuals seeking them out are likely the ones building great groups those people will want to be members of. Yes, the moment it becomes a keyword recruiters start to match against we’re likely to see a spur of fakes trying to land a job, but that’s nothing new under the sun. Signed, a Devops manager Source: http://www.spikelab.org/devops-job-title/
March 5, 2012
by Spike Morelli
· 10,759 Views
article thumbnail
Sketching with HTML5 Canvas and “Brush Images”
In a previous post on capturing user signatures in mobile applications, I explored how you capture user input from mouse or touch events and visualize that in a HTML5 Canvas. Inspired by activities with my daughter, I decided to take this signature capture component and make it a bit more fun & exciting. My daughter and I often draw and sketch together… whether its a magnetic sketching toy, doodling on the iPad, or using a crayon and a placemat at a local pizza joint, there is always something to draw. (Note: I never said I was actually good at drawing.) You can take that exact same signature capture example, make the canvas bigger, and then combine it with a tablet and a stylus, and you’ve got a decent sketching application. However, after doodling a bit you will quickly notice that your sketches leave something to be desired. When you are drawing on a canvas using moveTo(x,y) and lineTo(x,y), you are somewhat limited in what you can do. You have lines which can have consisten thickness, color, and opacity. You can adjust these, however in the end, they are only lines. If you switch your approach away from moveTo and lineTo, then things can get interesting with a minimal amount of changes. You can use images to create “brushes” for drawing strokes in a HTML5 canvas element and add a lot of style and depth to your sketched content. This is an approach that I’ve adapted to JavaScript from some OpenGL drawing applications that I’ve worked on in the past. Take a look at the video below to get an idea what I mean. Examining the sketches side by side, it is easy to see the difference that this makes. The variances in stroke thickness, opacity & angle add depth and style, and provide the appearance of drawing with a magic marker. It’s hard to see the subtleties in this image, so feel free to try out the apps on your own using an iPad or in a HTML5 Canvas-capable browser: Simple Sketch Using lineTo Stylistic Sketches Using a Brush Just click/touch and drag in the gray rectangle area to start drawing. Now, let’s examine how it all works. Both approaches use basic drawing techniques within the HTML5 Canvas element. If you aren’t familiar with the HTML5 Canvas, you can quickly get up to speed from the tutorials from Mozilla. moveTo, lineTo The first technique uses the canvas’s drawing context moveTo(x,y) and lineTo(x,y) to draw line segments that correspond to the mouse/touch coordinates. Think of this as playing “connect the dots” and drawing a solid line between two points. The code for this approach will look something like the following: var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); context.beginPath(); context.moveTo(a.x, a.y); context.lineTo(b.x, b.y); context.lineTo(c.x, c.y); context.closePath(); context.stroke(); Brush Images The technique for using brush images is identical in concept to the previous example – you are drawing a line from point A to point B. However, rather than using the built-in drawing APIs, you are programmatically repeating an image (the brush) from point A to point B. First, take a look at the brush image shown below at 400% of the actual scale. It is a simple image that is a diagonal shape that is thicker and more opaque on the left side. By itself, this will just be a mark on the canvas. When you repeat this image from point A to point B, you will get a “solid” line. However the opacity and thickness will vary depending upon the angle of the stroke. Take a look at the sample below (approximated, and zoomed). The question is… how do you actually do this in JavaScript code? First, create an Image instance to be used as the brush source. brush = new Image(); brush.src="assets/brush2.png"; Once the image is loaded, the image can be drawn into the canvas’ context using the drawImage() function. The trick here is that you will need to use some trigonometry to determine how to repeat the image. In this case, you can calculate the angle and distance from the start point to the end point. Then, repeat the image based on that distance and angle. var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var halfBrushW = brush.width/2; var halfBrushH = brush.height/2; var start = { x:0, y:0 }; var end = { x:200, y:200 }; var distance = parseInt( Trig.distanceBetween2Points( start, end ) ); var angle = Trig.angleBetween2Points( start, end ); var x,y; for ( var z=0; (z<=distance || z==0); z++ ) { x = start.x + (Math.sin(angle) * z) - halfBrushW; y = start.y + (Math.cos(angle) * z) - halfBrushH; context.drawImage(this.brush, x, y); } For the trigonometry functions, I have a simple utility class to calculate the distance between two points, and the angle between two points. This is all based upon the good old Pythagorean theorem. var Trig = { distanceBetween2Points: function ( point1, point2 ) { var dx = point2.x - point1.x; var dy = point2.y - point1.y; return Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) ); }, angleBetween2Points: function ( point1, point2 ) { var dx = point2.x - point1.x; var dy = point2.y - point1.y; return Math.atan2( dx, dy ); } } The full source for both of these examples is available on github at: https://github.com/triceam/HTML5-Canvas-Brush-Sketch This example uses the twitter bootstrap UI framework, jQuery, and Modernizr. Both the lineTo.html and brush.html apps use the exact same code, which just uses a separate rendering function based upon the use case. Feel free to try out the apps on your own using an iPad or in a HTML5 Canvas-capable browser: Simple Sketch Using lineTo Stylistic Sketches Using a Brush Just click/touch and drag in the gray rectangle area to start drawing.
March 4, 2012
by Andrew Trice
· 18,247 Views
article thumbnail
Allowing Duplicate Keys in Java Collections
Java Collections allows you to add one or more elements with the same key by using the MultiValueMap class, found in the Apache org.apache.commons.collections package (http://commons.apache.org/collections/): package multihashmap.example; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.collections.map.MultiValueMap; public class MultiHashMapExample { public static void main(String[] args) { List list; MultiValueMap map = new MultiValueMap(); map.put("A", 4); map.put("A", 6); map.put("B", 7); map.put("C", 1); map.put("B", 9); map.put("A", 5); Set entrySet = map.entrySet(); Iterator it = entrySet.iterator(); System.out.println(" Object key Object value"); while (it.hasNext()) { Map.Entry mapEntry = (Map.Entry) it.next(); list = (List) map.get(mapEntry.getKey()); for (int j = 0; j < list.size(); j++) { System.out.println("\t" + mapEntry.getKey() + "\t " + list.get(j)); } } } } Since Java Core does’t come with some solutions for supporting multiple keys, using the org.apache.commons.collections seems to be a proper way to deal with multiple keys. And the output is: From http://e-blog-java.blogspot.com/2012/02/how-to-allow-duplicate-key-in-java.html
March 3, 2012
by A. Programmer
· 100,451 Views · 5 Likes
article thumbnail
Why You Need a Git Pre-Commit Hook and Why Most Are Wrong
a pre-commit hook is a piece of code that runs before every commit and determines whether or not the commit should be accepted. think of it as the gatekeeper to your codebase. want to ensure you didn’t accidentally leave any pdb s in your code? pre-commit hook. want to make sure your javascript is jshint approved? pre-commit hook. want to guarantee clean, readable pep8 -compliant code? pre-commit hook. want to pipe all of the comments in your codebase through strunk & white ? please don’t. the pre-commit hook is just an executable file that runs before every commit. if it exits with zero status, the commit is accepted. if it exits with a non-zero status, the commit is rejected. (note: a pre-commit hook can be bypassed by passing the --no-verify argument.) along with the pre-commit hook there are numerous other git hooks that are available: post-commit, post-merge, pre-receive, and others that can be found here . why most pre-commit hooks are wrong be wary of the above’s example as the majority of pre-commit hooks you’ll see on the web are wrong. most test against whatever files are currently on disk, not what is in the staging area (the files actually being committed). we avoid this in our hook by stashing all changes that are not part of the staging area before running our checks and then popping the changes afterwards. this is very important because a file could be fine on disk while the changes that are being committed are wrong. the code below is the pre-commit hook we use at yipit. our hook is simply a set of checks to be run against any files that have been modified in this commit. each check can be configured to include/exclude particular types of files. it is designed for a django environment, but should be adaptable to other environments with minor changes. note that you need git 1.7.7+ #!/usr/bin/env python import os import re import subprocess import sys modified = re.compile('^(?:m|a)(\s+)(?p.*)') checks = [ { 'output': 'checking for pdbs...', 'command': 'grep -n "import pdb" %s', 'ignore_files': ['.*pre-commit'], 'print_filename': true, }, { 'output': 'checking for ipdbs...', 'command': 'grep -n "import ipdb" %s', 'ignore_files': ['.*pre-commit'], 'print_filename': true, }, { 'output': 'checking for print statements...', 'command': 'grep -n print %s', 'match_files': ['.*\.py$'], 'ignore_files': ['.*migrations.*', '.*management/commands.*', '.*manage.py', '.*/scripts/.*'], 'print_filename': true, }, { 'output': 'checking for console.log()...', 'command': 'grep -n console.log %s', 'match_files': ['.*yipit/.*\.js$'], 'print_filename': true, }, { 'output': 'checking for debugger...', 'command': 'grep -n debugger %s', 'match_files': ['.*\.js$'], 'print_filename': true, }, { 'output': 'running jshint...', # by default, jshint prints 'lint free!' upon success. we want to filter this out. 'command': 'jshint %s | grep -v "lint free!"', 'match_files': ['.*yipit/.*\.js$'], 'print_filename': false, }, { 'output': 'running pyflakes...', 'command': 'pyflakes %s', 'match_files': ['.*\.py$'], 'ignore_files': ['.*settings/.*', '.*manage.py', '.*migrations.*', '.*/terrain/.*'], 'print_filename': false, }, { 'output': 'running pep8...', 'command': 'pep8 -r --ignore=e501,w293 %s', 'match_files': ['.*\.py$'], 'ignore_files': ['.*migrations.*'], 'print_filename': false, }, { 'output': 'checking for sass changes...', 'command': 'sass --quiet --update %s', 'match_files': ['.*\.scss$'], 'print_filename': true, }, ] def matches_file(file_name, match_files): return any(re.compile(match_file).match(file_name) for match_file in match_files) def check_files(files, check): result = 0 print check['output'] for file_name in files: if not 'match_files' in check or matches_file(file_name, check['match_files']): if not 'ignore_files' in check or not matches_file(file_name, check['ignore_files']): process = subprocess.popen(check['command'] % file_name, stdout=subprocess.pipe, stderr=subprocess.pipe, shell=true) out, err = process.communicate() if out or err: if check['print_filename']: prefix = '\t%s:' % file_name else: prefix = '\t' output_lines = ['%s%s' % (prefix, line) for line in out.splitlines()] print '\n'.join(output_lines) if err: print err result = 1 return result def main(all_files): # stash any changes to the working tree that are not going to be committed subprocess.call(['git', 'stash', '-u', '--keep-index'], stdout=subprocess.pipe) files = [] if all_files: for root, dirs, file_names in os.walk('.'): for file_name in file_names: files.append(os.path.join(root, file_name)) else: p = subprocess.popen(['git', 'status', '--porcelain'], stdout=subprocess.pipe) out, err = p.communicate() for line in out.splitlines(): match = modified.match(line) if match: files.append(match.group('name')) result = 0 print 'running django code validator...' return_code = subprocess.call('$virtual_env/bin/python manage.py validate', shell=true) result = return_code or result for check in checks: result = check_files(files, check) or result # unstash changes to the working tree that we had stashed subprocess.call(['git', 'reset', '--hard'], stdout=subprocess.pipe, stderr=subprocess.pipe) subprocess.call(['git', 'stash', 'pop', '-q'], stdout=subprocess.pipe, stderr=subprocess.pipe) sys.exit(result) if __name__ == '__main__': all_files = false if len(sys.argv) > 1 and sys.argv[1] == '--all-files': all_files = true main(all_files) to use this hook or a hook that you create yourself, simply copy the file to .git/hooks/pre-commit inside of your project and make sure that it is executable or add in to your git repo and setup a symlink.
March 3, 2012
by Steve Pulec
· 23,570 Views · 1 Like
article thumbnail
HTML5 Image Effects: Sepia
Today we continue our HTML5 canvas examples. Today I want to share with you a method of applying a sepia effect to images. This is not a very difficult method, anyone can repeat it. In our demo we can play with different images by adding a sepia effect to them, as well as ‘export’ our result on the image element (). Here are our demo and downloadable package: Live Demo download in package Ok, download the example files and lets start coding ! Step 1. HTML Markup This is the markup of our demo page. Here it is: index.html HTML5 Image Effects - Sepia Back to original tutorial on Script Tutorials Canvas Object Image Object Next imageApply Sepia EffectTo Image Basically – it contains just one canvas object, one image, and three ‘buttons’ (div elements). Step 2. CSS Here are our stylesheets: css/main.css *{ margin:0; padding:0; } body { background-image:url(../images/bg.png); color:#fff; font:14px/1.3 Arial,sans-serif; } header { background-color:#212121; box-shadow: 0 -1px 2px #111111; display:block; height:70px; position:relative; width:100%; z-index:100; } header h2{ font-size:22px; font-weight:normal; left:50%; margin-left:-400px; padding:22px 0; position:absolute; width:540px; } header a.stuts,a.stuts:visited { border:none; text-decoration:none; color:#fcfcfc; font-size:14px; left:50%; line-height:31px; margin:23px 0 0 110px; position:absolute; top:0; } header .stuts span { font-size:22px; font-weight:bold; margin-left:5px; } .container { color: #000000; margin: 20px auto; overflow: hidden; position: relative; width: 1005px; } table { background-color: rgba(255, 255, 255, 0.7); } table td { border: 1px inset #888888; position: relative; text-align: center; } table td p { display: block; padding: 10px 0; } .button { cursor: pointer; height: 20px; padding: 15px 0; position: relative; text-align: center; width: 500px; -moz-user-select: none; -khtml-user-select: none; user-select: none; } Step 3. JS Finally – our Javascript code generating the sepia effect: js/script.js // variables var canvas, ctx; var imgObj; // set of sepia colors var r = [0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 44, 45, 47, 48, 49, 52, 54, 55, 57, 59, 60, 62, 65, 67, 69, 70, 72, 74, 77, 79, 81, 83, 86, 88, 90, 92, 94, 97, 99, 101, 103, 107, 109, 111, 112, 116, 118, 120, 124, 126, 127, 129, 133, 135, 136, 140, 142, 143, 145, 149, 150, 152, 155, 157, 159, 162, 163, 165, 167, 170, 171, 173, 176, 177, 178, 180, 183, 184, 185, 188, 189, 190, 192, 194, 195, 196, 198, 200, 201, 202, 203, 204, 206, 207, 208, 209, 211, 212, 213, 214, 215, 216, 218, 219, 219, 220, 221, 222, 223, 224, 225, 226, 227, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 244, 244, 245, 245, 245, 246, 247, 247, 248, 248, 249, 249, 249, 250, 251, 251, 252, 252, 252, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], g = [0, 0, 1, 2, 2, 3, 5, 5, 6, 7, 8, 8, 10, 11, 11, 12, 13, 15, 15, 16, 17, 18, 18, 19, 21, 22, 22, 23, 24, 26, 26, 27, 28, 29, 31, 31, 32, 33, 34, 35, 35, 37, 38, 39, 40, 41, 43, 44, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 83, 84, 85, 86, 88, 89, 90, 92, 93, 94, 95, 96, 97, 100, 101, 102, 103, 105, 106, 107, 108, 109, 111, 113, 114, 115, 117, 118, 119, 120, 122, 123, 124, 126, 127, 128, 129, 131, 132, 133, 135, 136, 137, 138, 140, 141, 142, 144, 145, 146, 148, 149, 150, 151, 153, 154, 155, 157, 158, 159, 160, 162, 163, 164, 166, 167, 168, 169, 171, 172, 173, 174, 175, 176, 177, 178, 179, 181, 182, 183, 184, 186, 186, 187, 188, 189, 190, 192, 193, 194, 195, 195, 196, 197, 199, 200, 201, 202, 202, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 232, 232, 232, 233, 234, 235, 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 241, 242, 242, 242, 243, 244, 245, 245, 246, 246, 247, 247, 248, 249, 249, 249, 250, 251, 251, 252, 252, 252, 253, 254, 255], b = [53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 61, 61, 61, 62, 62, 63, 63, 63, 64, 65, 65, 65, 66, 66, 67, 67, 67, 68, 69, 69, 69, 70, 70, 71, 71, 72, 73, 73, 73, 74, 74, 75, 75, 76, 77, 77, 78, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 85, 85, 86, 86, 87, 87, 88, 89, 89, 90, 90, 91, 91, 93, 93, 94, 94, 95, 95, 96, 97, 98, 98, 99, 99, 100, 101, 102, 102, 103, 104, 105, 105, 106, 106, 107, 108, 109, 109, 110, 111, 111, 112, 113, 114, 114, 115, 116, 117, 117, 118, 119, 119, 121, 121, 122, 122, 123, 124, 125, 126, 126, 127, 128, 129, 129, 130, 131, 132, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 140, 141, 142, 142, 143, 144, 145, 145, 146, 146, 148, 148, 149, 149, 150, 151, 152, 152, 153, 153, 154, 155, 156, 156, 157, 157, 158, 159, 160, 160, 161, 161, 162, 162, 163, 164, 164, 165, 165, 166, 166, 167, 168, 168, 169, 169, 170, 170, 171, 172, 172, 173, 173, 174, 174, 175, 176, 176, 177, 177, 177, 178, 178, 179, 180, 180, 181, 181, 181, 182, 182, 183, 184, 184, 184, 185, 185, 186, 186, 186, 187, 188, 188, 188, 189, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 193, 194, 194, 194, 195, 196, 196, 196, 197, 197, 197, 198, 199]; // noise value var noise = 20; function processSepia() { // get current image data var imageData = ctx.getImageData(0,0,canvas.width,canvas.height); for (var i=0; i < imageData.data.length; i+=4) { // change image colors imageData.data[i] = r[imageData.data[i]]; imageData.data[i+1] = g[imageData.data[i+1]]; imageData.data[i+2] = b[imageData.data[i+2]]; // apply noise if (noise > 0) { var noise = Math.round(noise - Math.random() * noise); for(var j=0; j<3; j++){ var iPN = noise + imageData.data[i+j]; imageData.data[i+j] = (iPN > 255) ? 255 : iPN; } } } // put image data back to context ctx.putImageData(imageData, 0, 0); }; $(function () { // create canvas and context objects canvas = document.getElementById('source'); ctx = canvas.getContext('2d'); // load source image imgObj = new Image(); imgObj.onload = function () { // draw image ctx.drawImage(this, 0, 0, this.width, this.height, 0, 0, canvas.width, canvas.height); } imgObj.src="images/pic1.jpg"; // different onclick handlers var iCur = 1; $('#next').click(function () { iCur++; if (iCur > 6) iCur = 1; imgObj.src="images/pic" + iCur + '.jpg'; }); $('#sepia').click(function () { processSepia(); }); $('#toImage').click(function () { $('#img').attr('src', canvas.toDataURL('image/jpeg')); }); }); Main idea: as we know – sepia images have their own, quite predefined colors. So our script will walk through all pixels of the original image, and change the pixel color to the corresponding sepia color. Plus, we will add a little of noise to our image. Live Demo download in package Conclusion I hope that our demo looks fine. Today we have added a new interesting effect to our html5 application – Sepia. I will be glad to see your thanks and comments. Good luck!
March 2, 2012
by Andrei Prikaznov
· 11,888 Views
article thumbnail
Gradient descent in Octave
Gradient descent is one of the simplest method to fit a model of a given form from a bunch of data. For example, you may want to know which is the best (in terms of mean squared error) line fitting a series of points. In that case, you're trying to fit: y = m * x + q where y and x are known vectors, collected from some source: y = [1 2 3.1 4 5.5] x = [0 1 2 3 4] and m and q are the parameters you want to discover. In reality, the function may be the predicted rating of a book or movie given the preferences of a user, or the number of views of a page as a function of length and tags. The (high-school) mathematics behind it Given a vector of parameters, in the one-dimension linear case [m, q], one way to quantify the error on the training set is to calculate the (mean) squared error: SE = sum{[y(i) - m * x(i) - q]^2} where i varies from 1 to the number of samples N. The mean error should be divided by N, but for the purpose of our discussion nothing changes as minimizing this error or its quotient by N is the same. When you wanted to minimize a function in high-school, what you do is to take the derivatives with respect to the variables you have to find: dSE/dm = sum{2*[y(i) - m * x(i) - q]*(-x(i))} dSE/dq = sum{2*[y(i) - m * x(i) - q]*(-1)} These expressions are usually too difficult to minimize globally in a closed form (coming up with an algebric solution), but we can use iterative methods to get close to a point where the gradient G = [dSE/dm dSE/dq] is close as possible to [0 0], which means the SE is at a local minimum. There's no way to be sure it is the unique minimum or that it is the global one without exploring the whole domain. Our iterative solution, gradient descent, is to: pick starting points at random for m and q. Move a bit into the opposite direction of the gradient G (which is the fastest direction to decrease SE). If we have not reached a fixed number of iterations or an acceptable value for SE, we restart from the new values of m and q. We moderate this movement by multiplying the gradient for a small number called learning rate, essentially to avoid big jumps that miss a minimum. A complete example With this Octave code, we try to fit a parabola of the form y = a*x^2 + c. We could do the same with y = a*x^2 + b*x + c, and hopefully we would find b would be close to 0 for these data. This is the training set (it is usually bigger): % training set: samples from the real world x = [-4, -3, -2, -1, 0, 1, 2, 3, 4]; y = [26.1, 19, 14.1, 10.9, 10.1, 11.1, 13.9, 19.1, 25.9]; % our true model would produce: 26, 19, 14, 11, 10, 11, 14, 19, 26 % it is in fact y = x^2 + 10 It is handy to be able to calculate the MSE: % looking for a model y = f(x) = a*x^2 + c % MSE = sum{[y-f(x)]^2} function result = mse(y, x, a, c) result = 0; for i=1:size(x, 2) % could be done with matrices, but I prefer to be clear result = result + (y(i) - (a * x(i)^2 + c))^2; end result = result / size(x, 2); end Since the number of samples is constant, we can minimize the SE instead of the MSE. These are the derivatives with respect to the parameters to be found, a and c: % MSE derivative with respect to a: sum{2[y-f(x)]*(-2x)} function d = a_direction_component(y, x, a, c) d = sum(2*(y - a * (x .^ 2) - c) .* (-2 * x .^ 2)); end % MSE derivative with respect to c: sum{2[y-f(x)]*(-1)} function d = c_direction_component(y, x, a, c) d = sum(2*(y - a * x .^ 2 - c) .* (-1)); end We start from [0, 0], but we there is no preferred point and we could pick a 2D point at random. The learning rate step is a small number: % initialization a = 0; c = 0; step = 0.0001; mse(y, x, a, c) We perform some thosands iteration, as gradient descent is one of the slowest methods to converge: for i=1:10000 sprintf("Iteration %d", i) gradient = [a_direction_component(y, x, a, c) c_direction_component(y, x, a, c)] a = a - step * gradient(1); c = c - step * gradient(2); sprintf("Model learned: y = %f.2 * x^2 + %f.2", a, c) current_mse = mse(y, x, a, c) end The execution is the following: ans = Iteration 1 gradient = -5235.60 -300.40 ans = Model learned: y = 0.523560 * x^2 + 0.030040 current_mse = 181.14 ans = Iteration 2 gradient = -3745.67 -237.03 ans = Model learned: y = 0.898127 * x^2 + 0.053743 current_mse = 113.73 ans = Iteration 3 gradient = -2679.21 -191.66 ans = Model learned: y = 1.166047 * x^2 + 0.072909 current_mse = 79.155 ... ans = Iteration 10000 gradient = 0.0026914 -0.0316712 ans = Model learned: y = 0.998938 * x^2 + 10.027546 current_mse = 0.0083345 Conclusions Gradient descent is a very simple method to implement, and can in theory learn any model with any number of parameters (linear, quadratic, exponential...). However, it is prone to slow convergence and to fall into local minima of the MSE (think of holes in a garden) without being able to escape, since it's like a ball rolling down a slope. In any case, the basic flow of iterative algorithms that try to improve a metric on a training set is very popular in machine learning and gradient descent is the first example of them.
March 1, 2012
by Giorgio Sironi
· 19,278 Views · 1 Like
article thumbnail
Client-side server monitoring with Jolokia and JMX
The choice of Java monitoring tools is tremendous (random selection and order powered by Google): javamelody psi-probe JVisualVM jconsole JAMon Java JMX Nagios Plugin N/A Besides, there are various dedicated tools e.g. for ActiveMQ, JBoss, Quartz scheduler, Tomcat/tcServer... So which one should you use as an ultimate monitoring dashboard? Well, none of them provide out-of-the-box features you might require. In some applications you have to constantly monitor the contents and size of a given JMS queue. Others are known to have memory or CPU problems. I have also seen software where system administrators had to constantly run some SQL query and check the results or even parse the logs to make sure some essential background process is running. Possibilities are endless, because it really depends on the software and its use-cases. To make matters worse, your customer doesn't care about GC activity, number of open JDBC connections and whether this nasty batch process is not hanging. It should just work. In this post we will try to develop easy, cheap, but yet powerful management console. It will be built around the idea of a single binary result – it works or not. If this single health indicator is green, no need to go deeper. But! If it turned red, we can easily drill-down. It is possible because instead of showing hundreds of unrelated metrics we will group them in a tree-like structure. The health status of each node in a tree is as bad as the worst child. This way if anything bad happens with our application, it will bubble-up. We are not forcing system administrator to constantly monitor several metrics. We decide what is important and if even tiniest piece of our software is malfunctioning, it will pop-up. Compare this to a continuous integration server that does not have green/red builds and e-mail notifications. Instead you have to go to the server every other build and manually check whether the code is compiling and all tests were green. The logs and results are there, but why parse them and aggregate manually? This is what we are trying to avoid in our home-grown monitoring solution. As a foundation I have chosen (not for the first time) Jolokia JMX to HTTP bridge. JVM already provides the monitoring infrastructure so why reinvent it? Also thanks to Jolokia the whole dashboard can be implemented in JavaScript on the client side. This has several advantages: server footprint is minimal, also it allows us to rapidly tune metrics by adding them or changing alert thresholds. We'll start by downloading various JMX metrics onto the client (browser). I have developed some small application for demonstration purposes employing as many technologies as possible – Tomcat, Spring, Hibernate, ActiveMQ, Quartz, etc. I am not using the built-in JavaScript client library for Jolokia as I found it a bit cumbersome. But as you can see it is just a matter of a single AJAX call to fetch great deal of metrics. function request() { var mbeans = [ "java.lang:type=Memory", "java.lang:type=MemoryPool,name=Code Cache", "java.lang:type=MemoryPool,name=PS Eden Space", "java.lang:type=MemoryPool,name=PS Old Gen", "java.lang:type=MemoryPool,name=PS Perm Gen", "java.lang:type=MemoryPool,name=PS Survivor Space", "java.lang:type=OperatingSystem", "java.lang:type=Runtime", "java.lang:type=Threading", 'Catalina:name="http-bio-8080",type=ThreadPool', 'Catalina:type=GlobalRequestProcessor,name="http-bio-8080"', 'Catalina:type=Manager,context=/jmx-dashboard,host=localhost', 'org.hibernate:type=Statistics,application=jmx-dashboard', "net.sf.ehcache:type=CacheStatistics,CacheManager=jmx-dashboard,name=org.hibernate.cache.StandardQueryCache", "net.sf.ehcache:type=CacheStatistics,CacheManager=jmx-dashboard,name=org.hibernate.cache.UpdateTimestampsCache", "quartz:type=QuartzScheduler,name=schedulerFactory,instance=NON_CLUSTERED", 'org.apache.activemq:BrokerName=localhost,Type=Queue,Destination=requests', "com.blogspot.nurkiewicz.spring:name=dataSource,type=ManagedBasicDataSource" ]; return _.map(mbeans, function(mbean) { return { type:'read', mbean: mbean } }); } $.ajax({ url: 'jmx?ignoreErrors=true', type: "POST", dataType: "json", data: JSON.stringify(request()), contentType: "application/json", success: function(response) { displayRawData(response); } }); Just to give you an overview what kind of information is accessible on the client side, we will first dump everything and display it on jQuery UI accordion: function displayRawData(fullResponse) { _(fullResponse).each(function (response) { var content = $('').append(JSON.stringify(response.value, null, '\t')); var header = $('').append($("", {href:'#'}).append(response.request.mbean)); $('#rawDataPanel'). append(header). append($('').append(content)); }); $('#rawDataPanel').accordion({autoHeight: false, collapsible: true}); } Remember that this is just for reference and debug purposes, we are not aiming to display endless list of JMX attributes. As you can see it is actually possible to implement complete jconsole port inside a browser with Jolokia and JavaScript... maybe next time (anyone care to help?). Back to our project, let's pick few essential metrics and display them in a list: The list itself looks very promising. Instead of displaying charts or values I have assigned an icon to each metric (more on that later). But I don't want to go through the whole list all the time. Why can't I just have a single indicator that aggregates several metrics? Since we are already using jsTree, the transition is relatively simple: On the first screenshot you see a healthy system. There is really no need to drill down since Overall metric is green. However the situation is worse on the second screenshot. System load is alarmingly high, also the Swap space needs attention, but is less important. As you can see the former metrics bubbles up all the way to the overall, top metric. This way we can easily discover what is working incorrectly in our system. You might be wondering how did we achieved this pretty tree while at the beginning we only had raw JMX data? No magic here, see how am I constructing the tree: function buildTreeModel(jmx) { return new CompositeNode('Overall', [ new CompositeNode('Servlet container', [ new Node( 'Active HTTP sessions', jmx['Catalina:context=/jmx-dashboard,host=localhost,type=Manager'].activeSessions, Node.threshold(200, 300, 500) ), new Node( 'HTTP sessions create rate', jmx['Catalina:context=/jmx-dashboard,host=localhost,type=Manager'].sessionCreateRate, Node.threshold(5, 10, 50) ), new Node( 'Rejected HTTP sessions', jmx['Catalina:context=/jmx-dashboard,host=localhost,type=Manager'].rejectedSessions, Node.threshold(1, 5, 10) ), new Node( 'Busy worker threads count', jmx['Catalina:name="http-bio-8080",type=ThreadPool'].currentThreadsBusy, Node.relativeThreshold(0.85, 0.9, 0.95, jmx['Catalina:name="http-bio-8080",type=ThreadPool'].maxThreads) ) ]), //... new CompositeNode('External systems', [ new CompositeNode('Persistence', [ new Node( 'Active database connections', jmx['com.blogspot.nurkiewicz.spring:name=dataSource,type=ManagedBasicDataSource'].NumActive, Node.relativeThreshold(0.75, 0.85, 0.95, jmx['com.blogspot.nurkiewicz.spring:name=dataSource,type=ManagedBasicDataSource'].MaxActive) ) ]), new CompositeNode('JMS messaging broker', [ new Node( 'Waiting in "requests" queue', jmx['org.apache.activemq:BrokerName=localhost,Destination=requests,Type=Queue'].QueueSize, Node.threshold(2, 5, 10) ), new Node( 'Number of consumers', jmx['org.apache.activemq:BrokerName=localhost,Destination=requests,Type=Queue'].ConsumerCount, Node.threshold(0.2, 0.1, 0) ) ]) ]) ]); } The tree model is quite simple. Root node can have a list of child nodes. Every child node can be either a leaf representing a single evaluated JMX metric or a composite node representing set of grandchildren. Each grandchild can in turns be a leaf or yet another composite node. Yes, it is a simple example of Composite design pattern! However it is not obvious where Strategy pattern was used. Look closer, each leaf node object has three properties: label (what you see on the screen), value (single JMX metric) and an odd function Node.threshold(200, 300, 500)... What is it? It is actually a higher order function (function returning a function) used later to interpret JMX metric. Remember, the raw value is meaningless, it has to be interpreted and translated into good-looking icon indicator. Here is how this implementation works: Node.threshold = function(attention, warning, fatal) { if(attention > warning && warning > fatal) { return function(value) { if(value > attention) { return 1.0; } if(value > warning) { return 0.5; } if(value > fatal) { return 0.0; } else { return -1.0; } } } if(attention < warning && warning < fatal) { return function(value) { if(value < attention) { return 1.0; } if(value < warning) { return 0.5; } if(value < fatal) { return 0.0; } else { return -1.0; } } } throw new Error("All thresholds should either be increasing or decreasing: " + attention + ", " + warning + ", " + fatal); } Now it becomes clear. The function receives level thresholds and returns a function that translates them to number in -1:1 range. I could have returned icons directly but I wanted to abstract tree model from GUI representation. If you now go back to Node.threshold(200, 300, 500) example of Active HTTP sessions metric it is finally obvious: if the number of active HTTP sessions exceed 200, show attention icon instead of OK. If it exceeds 300, warning appears. Above 500 fatal icon will appear. This function is a strategy that understands the input and handles it somehow. Of course these values/functions are only examples, but this is where real hard work manifests – for each JMX metric you have to define a set of sane thresholds. Is 500 HTTP sessions a disaster or only a high load we can deal with? Is 90% CPU load problematic or maybe if it is really low we should start worrying? Once you fine-tune these levels it should no longer be required to monitor everything at the same time. Just look at the top level single metric. If it is green, have a break. If it is not, drill-down in few seconds to find what the real problem is. Simple and effective. And did I mention it does not require any changes on the server side (except adding Jolokia and mapping it to some URL)? Obviously this is just a small proof-of-concept, not a complete monitoring solution. However if you are interested in trying it out and improving, the whole source code is available - as always on my GitHub account. From http://nurkiewicz.blogspot.com/2012/02/client-side-server-monitoring-with.html
March 1, 2012
by Tomasz Nurkiewicz
· 30,756 Views · 1 Like
article thumbnail
Streaming Radio Player Tutorial with Live Demo and Source Code
today i have prepared another really great tutorial for you. recently i started development of my own radio software (as a module for dolphin cms) and got some interesting results i would like to share with you. it will be nice looking (css3) radio script that consists of three main elements: the header (with animated search bar and integrated radio player), the left side (with a list of categories and subcategories) and the right side (which will contain a list of recent or filtered stations). here's the final result of our player: here's our live demo and downloadable package: ok, download our source files and lets start coding! step 1. html markup this is the markup of one of the template files. this is a template of our main (index) page: templates/main_page.html stream radio script back to original tutorial on script tutorials alternative classic alternativeindustrialnew wavepunk classical modernoperapianoromanticsymphony electronic breakbeatdanceelectrohousetechnotrance metal classic metalheavy metalmetalcorepower metal pop dance popoldiestop 40world pop __stations__ powered by script tutorials first, pay attention to how the script loads the jquery library from google. this can be pretty useful if you don’t like to keep this file directly on your host. our header element contains a nice search bar with an embedded jasl player ( i used a great ffmp3 live stream player ), which allows us to play audio streams without any problems. next, on the left-hand side (beneath the header) we have a ul-li based list of categories and subcategories. the right-hand side will contain a list of the most recent stations and, when we search or select a category, the right-hand side will be filtered by ajaxy. for now – it contains __stations__ key (template key) and we will replace the actual value with php. on to our next template file, the radio player: templates/radio.html of course, it contains its own template keys (__title__ and __stream__) which we will use after. step 2. css here are our stylesheets files: css/main.css the first one contains the styles of our test page (this file is always available in our package) css/radio.css /* header area */ .header { height:62px; } .header input { background:#aaa url(../images/search.png) no-repeat 5px center; border:1px solid #888; border-radius:10px; float:right; margin:14px 10px 0 0; outline:none; padding-left:20px; width:200px; -webkit-transition: 0.5s; -moz-transition: 0.5s; -o-transition: 0.5s; transition: 0.5s; } .header input:focus { background-color:#eee; width:300px; } .header > span { display:block; float:left; line-height:40px; padding:7px; -webkit-transition: 0.5s; -moz-transition: 0.5s; -o-transition: 0.5s; transition: 0.5s; } /* stations list */ .stlist { float:right; margin-right:1%; width:71%; } .stlist ul { list-style:none outside none; margin:0; padding:0; } .stlist ul li { border-bottom:1px dotted #444; overflow:hidden; padding:10px; } .stlist ul li > a > img { border:1px solid #ccc; float:left; height:85px; margin-right:15px; padding:1px; width:85px; } .stlist ul li > div { float:right; margin-left:15px; margin-top:-5px; } .stlist ul li > p.label,.stlist ul li > p.track { font-size:11px; font-weight:700; } .stlist ul li > p.label { color:#888; } .stlist ul li > p.channel { font-size:14px; font-weight:700; margin-bottom:17px; } /* genres list */ .genres_par { border-right:1px solid #ccc; float:left; width:26%; } ul.genres,ul.genres ul { list-style-type:none; margin:0; padding:0; } ul.genres ul { display:none; overflow:hidden; padding:0 15px; } ul.genres ul li { margin:3px; } ul.genres a { color:#333; display:block; font-size:18px; padding:4px 0; text-align:center; text-decoration:none; } ul.genres ul a { font-size:12px; text-align:left; } ul.genres li { border-bottom:1px solid #ccc; margin:0; } ul.genres li ul li a { background:none repeat scroll 0 0 #5bb951; border-radius:2px; color:#fff; font-size:12px; padding:6px; } ul.genres li ul li a:hover { background-color:#53854e; } step 3. js js/script.js $(document).ready(function(){ $('#search').blur(function() { if ('' == $('#search').val()) $('#search').val('search'); }); $('#search').focus(function() { if ('search' == $('#search').val()) $('#search').val(''); }); $('ul.genres li a').click( // category slider function() { var checkelement = $(this).next(); if((checkelement.is('ul')) && (!checkelement.is(':visible'))) { $('.genres li ul').slideup(150); $(this).next().slidetoggle(150); } } ); $('ul.genres ul li a').click( // get stations by category function() { $.ajax({ type: 'get', url: 'index.php', data: 'action=get_genre_stations&id=' + $(this).parent().attr('id') + '&name=' + $(this).parent().attr('val'), success: function(data){ $('.stlist').fadeout(400, function () { $('.stlist').html(data); $('.stlist').fadein(400); }); } }); } ); }); function play(id) { // play function $('#rplayer').load('index.php?action=play&id=' + id, function() {}); return false; } function get_stations_by_keyword() { // get stations by keyword var keyword = $('#search').val().replace(/ /g,"+"); $.ajax({ type: 'get', url: 'index.php', data: 'action=get_keyword_stations&key=' + keyword, success: function(data){ $('.stlist').fadeout(400, function () { $('.stlist').html(data); $('.stlist').fadein(400); }); } }); } as you see – there's nothing difficult there. just several event handlers, and two new functions (to play radio station and to search for stations by keyword). step 4. php index.php =') == 1) error_reporting(e_all & ~e_notice & ~e_deprecated); else error_reporting(e_all & ~e_notice); $astations = array( 0 => array( 'category' => 31, 'name' => 'eurodance', 'desc' => 'the newest and best of eurodance hits', 'url' => 'http://www.di.fm/eurodance', 'br' => 96, 'stream' => 'http://scfire-mtc-aa06.stream.aol.com:80/stream/1024' ), 1 => array ( 'category' => 34, 'name' => 'house', 'desc' => 'silky sexy deep house music direct from new york city!', 'url' => 'http://www.di.fm/house', 'br' => 96, 'stream' => 'http://scfire-ntc-aa04.stream.aol.com:80/stream/1007' ), 2 => array ( 'category' => 13, 'name' => 'trance', 'desc' => 'the hottest, freshest trance music from around the globe!', 'url' => 'http://www.di.fm/trance', 'br' => 96, 'stream' => 'http://scfire-ntc-aa04.stream.aol.com:80/stream/1003' ), 3 => array ( 'category' => 51, 'name' => 'electro house', 'desc' => 'an eclectic mix of electro and dirty house', 'url' => 'http://www.di.fm/electro', 'br' => 96, 'stream' => 'http://scfire-ntc-aa04.stream.aol.com:80/stream/1025' ) ); function searchbycat($icat, $astations) { $ares = array(); foreach ($astations as $i => $ainfo) { if ($ainfo['category'] == $icat) { $ares[$i] = $ainfo; } } return $ares; } function searchbykeyword($skey, $astations) { $ares = array(); foreach ($astations as $i => $ainfo) { if (false !== strpos($ainfo['name'], $skey) || false !== strpos($ainfo['desc'], $skey)) { $ares[$i] = $ainfo; } } return $ares; } function parsestationlist($adata) { $sstations = ''; if (is_array($adata) && count($adata) > 0) { foreach ($adata as $i => $a) { $sstationid = $i; $sstationbr = (int)$a['br']; $sstationname = $a['name']; $sstationdesc = $a['desc']; $sstationurl = $a['url']; $sthumb = 'media/'.($sstationid+1).'.png'; $sstations .= << bitrate: {$sstationbr} {$sstationname} {$sstationdesc} {$sstationurl} eof; } } $sstations = ($sstations == '') ? 'nothing found' : $sstations; return '' . $sstations . ''; } switch ($_get['action']) { case 'play': $i = (int)$_get['id']; $ainfo = $astations[$i]; $avars = array ( '__stream__' => $ainfo['stream'], '__title__' => $ainfo['name'] ); echo strtr(file_get_contents('templates/radio.html'), $avars); exit; break; case 'get_genre_stations': $i = (int)$_get['id']; $asearch = searchbycat($i, $astations); $sstations = parsestationlist($asearch); header('content-type: text/html; charset=utf-8'); echo $sstations; exit; break; case 'get_keyword_stations': $skey = $_get['key']; $asearch = searchbykeyword($skey, $astations); $sstations = parsestationlist($asearch); header('content-type: text/html; charset=utf-8'); echo $sstations; exit; break; } $slaststations = parsestationlist($astations); echo strtr(file_get_contents('templates/main_page.html'), array('__stations__' => $slaststations)); at the beginning, i have prepared a list of our radio stations (4 stations total). then, two search functions: ‘searchbycat’ and ‘searchbykeyword’. next, the special function ‘parsestationlist’ which will transform array with filtered stations into its html representation. finally, a little switch case to manage with our inner ajax commands. conclusion you are always welcome to enhance our script and share your ideas. i will be glad to see your thanks and comments. good luck!
February 29, 2012
by Andrei Prikaznov
· 51,553 Views · 1 Like
article thumbnail
Creating a build pipeline using Maven, Jenkins, Subversion and Nexus.
for a while now, we had been operating in the wild west when it comes to building our applications and deploying to production. builds were typically done straight from the developer’s ide and manually deployed to one of our app servers. we had a manual process in place, where the developer would do the following steps. check all project code into subversion and tag build the application. archive the application binary to a network drive deploy to production update our deployment wiki with the date and version number of the app that was just deployed. the problem is that there were occasionally times where one of these steps were missed, and it always seemed to be at a time when we needed to either rollback to the previous version, or branch from the tag to do a bugfix. sometimes the previous version had not been archived to the network, or the developer forgot to tag svn. we were already using jenkins to perform automated builds, so we wanted to look at extending it further to perform release builds. the maven release plug-in provides a good starting point for creating an automated release process. we have also just started using the nexus maven repository and wanted to incorporate that as well to archive our binaries to, rather than archiving them to a network drive. the first step is to set up the project’s pom file with the deploy plugin as well as include configuration information about our nexus and subversion repositories. org.apache.maven.plugins maven-release-plugin 2.2.2 http://mks:8080/svn/jrepo/tags/frameworks/siestaframework the release plugin configuration is pretty straightforward. the configuration takes the subversion url of the location where the tags will reside for this project. the next step is to configure the svn location where the code will be checked out from. scm:svn:http://mks:8080/svn/jrepo/trunk/frameworks/siestaframework http://mks:8080/svn the last step in configuring the project is to set up the location where the binaries will be archived to. in our case, the nexus repository. lynden-java-release lynden release repository http://cisunwk:8081/nexus/content/repositories/lynden-java-release the project is now ready to use the maven release plug-in. the release plugin provides a number of useful goals. release:clean – cleans the workspace in the event the last release process was not successful. release: prepare – performs a number of operations checks to make sure that there are no uncommitted changes. ensures that there are no snapshot dependencies in the pom file, changes the version of the application and removes snapshot from the version. ie 1.0.3-snapshot becomes 1.0.3 run project tests against modified poms commit the modified pom tag the code in subersion increment the version number and append snapshot. ie 1.0.3 becomes 1.0.4-snapshot commit modified pom release: perform – performs the release process checks out the code using the previously defined tag runs the deploy maven goal to move the resulting binary to the repository. putting it all together the last step in this process is to configure jenkins to allow release builds on-demand, meaning we want the user to have to explicitly kick off a release build for this process to take place. we have download and installed the release jenkins plug-in in order to allow developers to kick off release builds from jenkins. the release plug-in will execute tasks after the normal build has finished. below is a screenshot of the configuration of one of our projects. the release build option for the project is enabled by selecting the “configure release build” option in the “build environment” section. the maven release plug-in is activated by adding the goals to the “after successful release build” section. (the –b option enables batch mode so that the release plug-in will not ask the user for input, but use defaults instead.) once the release option has been configured for a project there will be a “release” icon on the left navigation menu for the project. selecting this will kick off a build and then the maven release process, assuming the build succeeds. finally a look at svn and nexus verifies that the build for version 1.0.4 of the siesta-framework project has been tagged in svn and uploaded to nexus. the next steps for this project will be to generate release notes for release builds, and also to automate a deployment pipeline, so that developers can deploy to our test, staging and production servers via jenkins rather than manually from their development workstations. twitter: @robterp blog: http://rterp.wordpress.com
February 29, 2012
by Rob Terpilowski
· 86,986 Views
article thumbnail
Multiple File Upload is Easy in HTML5
this won't be a terribly long post, nor one that is probably informative to a lot of people, but i finally got around to looking at the html5 specification for multiple file uploads (by that i mean allowing a user to pick multiple files from one file form field). i knew it existed i just never got around to actually looking at it. turns out it is incredibly simple. you take a file form field: and you add multiple to it (or multiple="multiple"). and... yeah, that's it. even better, it degrades perfectly. so in chrome it works, and your label switches from... to... i kept waiting for the "but, wait" moment and it never came. in ie where it fails to work, it simply remains a file upload control that works with one file, not many. because it's so simple and fallback is so good, i can't see really bothering to use another solution, like a flash uploader, but you could do a bit of massaging for it. so for example, consider if my form had the following label: multiple file: in ie, the user won't be able to select multiple files. while not the end of the world, it kind of bugs me that the label may mislead the user into trying something they can't do. (and as we know, the user will blame us, not ie.) so what to do? i did some basic research into how to use javascript to detect features. i found a few good examples that basically suggested creating a temporary dom item like so: var el = document.createelement("input"); but here's where i had issues. most of the links i found discussed how to detect new html form types , like range for example. these techniques worked by setting the type on the new element to the type you want to test and then immediately checking to see if the type still has the same value. but what about attributes? turns out dive into html5 has a great article on this. when you have your dom item, you can simply ask if the item exists. here is an example: function supportmultiple() { //do i support input type=file/multiple var el = document.createelement("input"); return ("multiple" in el); } so given that, i modified my mark up a bit. i changed the label in front of my form and hid the word "multiple": multiple file: i then added an init method to my body tag and used the following code: function supportmultiple() { //do i support input type=file/multiple var el = document.createelement("input"); return ("multiple" in el); } function init() { if(supportmultiple()) { document.queryselector("#multiplefilelabel").setattribute("style",""); } } and that worked like a charm. ie say just "file" whereas chrome and firefox had the new hotness. so yeah - that's a lot of writing about a simple little thing, but... dare i say it... i'm really getting jazzed up about html again! here's my entire test template if you want to cut and paste: normal text: multiple file: p.s. so how you actually process the upload depends on your server. my coldfusion readers are probably wondering how it handles this. good news, bad news. the bad news is that coldfusion can't (as far as i and other smarter peoiple know) handle this at all. if you want to do this in coldfusion 9, use the flash based multifile uploader instead. the good news is that coldfusion 10 handles it just file. be sure to use action value of "uploadall" of your cffile tag.
February 29, 2012
by Raymond Camden
· 101,612 Views
article thumbnail
Running Multiple Tomcat Instances on One Server
Here’s a brief step by step guide to running more than one instance of Tomcat on a single machine. Step 1: Install the Tomcat files Download Tomcat 5.5, 6.x, or 7.x and unzip it into an appropriate directory. I usually put it in /usr/local, so it ends up in a directory called /usr/local/apache-tomcat-5.5.17, and make a symlink named /usr/local/tomcat to that directory. When later versions come out, I can unzip them and relink, leaving the older version in case things don’t work out (which rarely if ever happens, but I’m paranoid). Step 2: Make directories for each instance For each instance of Tomcat you’re going to run, you’ll need a directory that will be CATALINA_BASE. For example, you might make them /var/tomcat/serverA and /var/tomcat/serverB. In each of these directories you need the following subdirectories: conf, logs, temp, webapps, and work. Put a server.xml and web.xml file in the conf directory. You can get these from the conf directory of the directory where you put the tomcat installation files, although of course you should tighten up your server.xml a bit. The webapps directory is where you’ll put the web applications you want to run on the particular instance of Tomcat. I like to have the Tomcat manager webapp installed on each instance, so I can play with the webapps, and see how many active sessions there are. See my instructions for configuring the Tomcat manager webapp. Step 3: Configure the ports and/or addresses for each instance Tomcat listens to at least two network ports, one for the shutdown command, and one or more for accepting requests. Two instances of Tomcat can’t listen to the same port number on the same IP address, so you will need to edit your server.xml files to change the ports they listen to. The first port to look at is the shutdown port. This is used by the command line shutdown script (actually, but the Java code it runs) to tell the Tomcat instance to shut itself down. This port is defined at the top of the server.xml file for the instance. Make sure each instance uses a different port value. The port value will normally need to be higher than 1024, and shouldn’t conflict with any other network service running on the same system. The shutdown string is the value that is sent to shut the server down. Note that Tomcat won’t accept shutdown commands that come from other machines. Unlike the other ports Tomcat listens to, the shutdown port can’t be configured to listen to its port on a different IP address. It always listens on 127.0.0.1. The other ports Tomcat listens to are configured with the elements, for instance the HTTP or JK listeners. The port attribute configures which port to listen to. Setting this to a different value on the different Tomcat instances on a machine will avoid conflict. Of course, you’ll need to configure whatever connects to that Connector to use the different port. If a web server is used as the front end using mod_jk, mod_proxy, or the like, then this is simple enough - change your web server’s configuration. In some cases you may not want to do this, for instance you may not want to use a port other than 8080 for HTTP connectors. If you want all of your Tomcat intances to use the same port number, you’ll need to use different IP addresses. The server system must be configured with multiple IP addresses, and the address attribute of the element for each Tomcat instance will be set to the appropriate IP address. Step 4: Startup Startup scripts are a whole other topic, but here’s the brief rundown. The main different from running a single Tomcat instance is you need to set CATALINA_BASE to the directory you set up for the particular instance you want to start (or stop). Here’s a typical startup routine: JAVA_HOME=/usr/java JAVA_OPTS="-Xmx800m -Xms800m" CATALINA_HOME=/usr/local/tomcat CATALINA_BASE=/var/tomcat/serverA export JAVA_HOME JAVA_OPTS CATALINA_HOME CATALINA_BASE $CATALINA_HOME/bin/catalina.sh start Source: http://kief.com/running-multiple-tomcat-instances-on-one-server.html
February 29, 2012
by Kief Morris
· 96,787 Views · 4 Likes
article thumbnail
Running JavaScript inside PHP code
v8js is a new PHP extension able to run JavaScript code inside V8, Google's JavaScript interpreter that powers for example Chrome and NodeJS. This extension is highly alpha - and its API would probably change in the months ahead. Since documentation is lacking, I invite you to repeat the discovering process I follow in this post in case you find some differences in a new version of v8js. Installation V8 must be present on the machine in order to install the extension. On a Debian/Ubuntu system, run the following: sudo apt-get install libv8-dev libv8-dbg libv8-dev will also install libv8 in its latest version. Afterwards, download and compile the extension with: sudo pecl install v8js There are no more requirements for compilation apart from the usual dependencies for PECL packages, like build-essential. After that, add: extension=v8js.so to php.ini or to a section in conf.d. $ php -m | grep v8 v8js will confirm you the extension is loaded. Some introspection PHP's reflection let us take a look at the classes and methods provided by this extension, even without documentation available. It probably hasn't been written yet, due to the unstable API. $ php -r 'var_dump(get_declared_classes());' | grep V8 string(8) "V8Object" string(10) "V8Function" string(4) "V8Js" string(13) "V8JsException" $ php -r '$class = new ReflectionClass("V8Js"); var_dump($class->getMethods());' array(5) { [0]=> &object(ReflectionMethod)#2 (2) { ["name"]=> string(11) "__construct" ["class"]=> string(4) "V8Js" } [1]=> &object(ReflectionMethod)#3 (2) { ["name"]=> string(13) "executeString" ["class"]=> string(4) "V8Js" } [2]=> &object(ReflectionMethod)#4 (2) { ["name"]=> string(19) "getPendingException" ["class"]=> string(4) "V8Js" } [3]=> &object(ReflectionMethod)#5 (2) { ["name"]=> string(17) "registerExtension" ["class"]=> string(4) "V8Js" } [4]=> &object(ReflectionMethod)#6 (2) { ["name"]=> string(13) "getExtensions" ["class"]=> string(4) "V8Js" } } $ php -r '$v8 = new V8Js(); var_dump($v8->executeString("1+2+3"));' int(6) Interesting! We have just executed our first JavaScript expression inside a PHP process. Apparently the last statement's value is returned by the executeString() method, with a rough conversion preserving the type: $ php -r '$v8 = new V8Js(); var_dump($v8->executeString("var obj = {}; obj.field = 1; obj.field++; obj.field;"));' int(2) Syntax or runtime errors are signaled with a V8JsException: $ php -r '$v8 = new V8Js(); var_dump($v8->executeString("var obj = {"));' PHP Fatal error: Uncaught exception 'V8JsException' with message 'V8Js::executeString():1: SyntaxError: Unexpected end of input' in Command line code:1 Stack trace: #0 Command line code(1): V8Js->executeString('var obj = {') #1 {main} thrown in Command line code on line 1 Let's add more difficulty The FizzBuzz kata OO solution is an example of JavaScript code creating an object and executing anonymous functions: it's a good test bench for our integration.Since evaluating a variable as the last line returns it, that is our channel of communication, supporting integers, strings, floats, booleans, arrays (not objects at this time). Meanwhile, input for JavaScript code can be embedded into the executed string. This code will output string(8) "FizzBuzz": executeString($javaScriptCode)); By changing it a bit, we can build a JSON string by backslashing the double quotes ("), and returns it in lieu of an object to communicate to the PHP process a complex result: ... var myFizzBuzz = new FizzBuzz({3 : "Fizz", 5 : "Buzz"}); "{\"15\" : \"" + myFizzBuzz.accept(15) + "\", \"5\" : \"" + myFizzBuzz.accept(5) + "\"}"; '; $v8 = new V8Js(); $result = $v8->executeString($javaScriptCode); var_dump($result); var_dump(json_decode($result)); The output is: string(33) "{"15" : "FizzBuzz", "5" : "Buzz"}" object(stdClass)#2 (2) { ["15"]=> string(8) "FizzBuzz" ["5"]=> string(4) "Buzz" } Wiring Executing an external script would be nice: it would provide better stack traces, with traceable line numbers at the JavaScript level. It would also mean we won't need backslashing for single quotes, simplifying the syntax. We cannot load scripts on the JavaScript side out of the box, due to V8 missing this functionality (Node JS adds this feature) but we can load the code on the PHP Side: // test.js $ php loadingfiles.php string(24) "test.js file was loaded." // loadingfiles.php executeString($javascriptCode); var_dump($result); Execution results in: $ php loadingfiles.php string(24) "test.js file was loaded." However, we still miss the capability of including JavaScript libraries. Conclusion There are many possible use cases for v8js, like sandboxed scripting or the integration of some code which was written for the client side. That would not be the most clean solution, but it's a Turing complete approach, so why not? After all, it's already possible to run PHP on Java or Python and Ruby on .NET. JavaScript is becoming ubiquitous, so why not providing support for it, even in a caged box?
February 29, 2012
by Giorgio Sironi
· 52,703 Views
article thumbnail
Audio in HTML 5: state of the art
HTML 5 capable browsers support multimedia files as first class citizens - HTML is not a language for describing documents anymore, but more a medium for building applications, which can leverage every bit of built-in functionality to run fast and to not weigh heavily on the shoulders of developers for maintenance. In this article, we'll see all the ways to play audio inside a modern browser via HTML 5. The element is a new tag not only able to load a sound file and play it, but also to feature a series of control buttons for playing, pausing and pausing the reproduction. Of course there are many use cases where you won't need controls, like for the background music of a game. is not more complex than : you specify a mandatory src attribute, and other options to configure the sound player where needed. The attributes shown in this example (and a few others) are: controls: when present, displays a browser-specific player to control the playback. The HTML 5 specification says that with these controls the user should be able to "begin playback, pause playback, seek to an arbitrary position in the content (if the content supports arbitrary seeking), change the volume" and a bunch of other features that I have not seen supported yet. autoplay: when present, tells the browser to begin playing the sound file as soon as it can. loop: when present, specifies the sound file should start again as soon as it finishes. muted: when present, sets the volume at 0 as a default. preload: specifies a policy for loading the sound file. "none" corresponds to no prefetching, which minimizes traffic; "metadata" prefetches only the start of the file, in order to read metadata like a song's duration. "auto" authorizes the browser to prefetch the whole file. Audio object Apparently the combination of HTML 5 and CSS 3 is a Turing complete language: however, it is more practical to code behavior of a web application in JavaScript. That's why eveyrthing you can do with an element can also be accomplished programmatically with JavaScript Audio objects: Thus via JavaScript you can control an audio element by calling a series of methods such as play() and pause(), and adjust properties like *volume*. Audio objects implement an interface named HtmlMediaElement, where you can find the list of all methods, plus modifiable and readonly properties available. For example, doorBell.seekable.length is a range, while doorBell.currentTime is an assignable property to make reproduction jump to a certain point of the file. Formats and support The real problem with HTML 5 Audio right now is its support in different browsers; not the support for and Audio - which is pretty consistent - but for the codecs to play all the different formats an audio file can come in. There are mainly two sides in the issue: Firefox, Chrome and Opera being as usual friendly to open source and open formats, and being the first to support Ogg Vorbis. Ogg is an open container for audio and video files, and Vorbis is a free lossy codec like MP3, but without any patent on it. Internet Explorer and Safari supporting MP3 instead. Let's not even talk about support on mobile browsers, which is close to non-existent with respect to codecs. By the way, for experimenting with stick to Chrome, Firefox and Opera. Fortunately, a series of elements can be embedded in an (or , equivalently) element to provide alternative formats, listed by MIME type: Encoding lots of files in different formats just to please browsers can be a pain, but it's viable in the case of small clips and sound effects.
February 27, 2012
by Giorgio Sironi
· 7,711 Views
article thumbnail
Configuration Drift
In my previous article on the server lifecycle I mentioned ConfigurationDrift, a term that I’ve either coined, or I’ve forgotten where I originally heard, although most likely I got it from the Puppet Labs folks. Configuration Drift is the phenomenon where running servers in an infrastructure become more and more different as time goes on, due to manual ad-hoc changes and updates, and general entropy. A nice automated server provisioning process as I’ve advocated helps ensure machines are consistent when they are created, but during a given machine’s lifetime it will drift from the baseline, and from the other machines. There are two main methods to combat configuration drift. One is to use automated configuration tools such as Puppet or Chef, and run them frequently and repeatedly to keep machines in line. The other is to rebuild machine instances frequently, so that they don’t have much time to drift from the baseline. The challenge with automated configuration tools is that they only manage a subset of a machine’s state. Writing and maintaining manifests/recipes/scripts is time consuming, so most teams tend to focus their efforts on automating the most important areas of the system, leaving fairly large gaps. There are diminishing returns for trying to close these gaps, where you end up spending inordinate amounts of effort to nail down parts of the system that don’t change very often, and don’t matter very much day to day. On the other hand, if you rebuild machines frequently enough, you don’t need to worry about running configuration updates after provisioning happens. However, this may increase the burden of fairly trivial changes, such as tweaking a web server configuration. In practice, most infrastructures are probably best off using a combination of these methods. Use automated configuration, continuously updated, for the areas of machine configuration where it gives the most benefit, and also ensure that machines are rebuilt frequently. The frequency of rebuilds will vary depending on the nature of the services provided and the infrastructure implementation, and may even vary for different types of machines. For example, machines that provide network services such as DNS may be rebuilt weekly, while those which handle batch processing tasks may be rebuilt on demand. Source: http://kief.com/configuration-drift.html
February 27, 2012
by Kief Morris
· 26,759 Views · 3 Likes
  • Previous
  • ...
  • 1570
  • 1571
  • 1572
  • 1573
  • 1574
  • 1575
  • 1576
  • 1577
  • 1578
  • 1579
  • ...
  • 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
×