Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-how-configure-msdtc-and-firewall-distributed-wcf-service
Packt
21 Jun 2010
4 min read
Save for later

How to configure MSDTC and the firewall for the distributed WCF service

Packt
21 Jun 2010
4 min read
Understanding the distributed transaction support of a WCF service As we have seen, distributed transaction support of a WCF service depends on the binding of the service, the operation contract attribute, the operation implementation behavior, and the client applications. The following table shows some possible combinations of the WCF-distributed transaction support: Binding permits transaction flow Client flows transaction Service contract opts in transaction Service operation requires transaction scope Possible result True Yes Allowed or Mandatory True Service executes under the flowed in transaction True or False No Allowed True Service creates and executes within a new transaction True Yes or No Allowed False Service executes without a transaction True or False No Mandatory True or False SOAP exception True Yes NotAllowed True or False SOAP exception Testing the distributed transaction support of the WCF service Now that we have changed the service to support distributed transaction and let the client propagate the transaction to the service, we will test this. We will propagate a transaction from the client to the service, test the multiple database support of the WCF service, and discuss the Distributed Transaction Coordinator and Firewall settings for the distributed transaction support of the WCF service. Configuring the Distributed Transaction Coordinator In a subsequent section, we will call two services to update two databases on two different computers. As these two updates are wrapped within one distributed transaction, Microsoft Distributed Transaction Coordinator (MSDTC) will be activated to manage this distributed transaction. If MSDTC is not started or configured properly the distributed transaction will not be successful. In this section, we will explain how to configure MSDTC on both machines. You can follow these steps to configure MSDTC on your local and remote machines: Open Component Services from Control Panel | Administrative Tools. In the Component Services window, expand Component Services, then Computers, and then right-click on My Computer. Select Properties from the context menu. On the My Computer Properties window, click on the MSDTC tab. If this machine is running Windows XP, click on the Security Configuration button. If this machine is running Windows 7, verify that Use local coordinator is checked and then close the My Computer Properties window. Expand Distributed Transaction Coordinator under My Computer node, right-click on Local DTC, select Properties from the context menu, and then from the Local DTC Properties window, click on the Security tab. You should now see the Security Configuration for DTC on this machine.Set it as in the following screenshot. Remember you have to make these changes for both your local and remote machines. You have to restart the MSDTC service after you have changed your MSDTC settings, for the changes to take effect.Also, to simplify our example, we have chosen the No Authentication Required option. You should be aware that not needing authentication is a serious security issue in production. For more information about WCF security, you can go to the MSDN WCF security website at this address:MSDN Library. Configuring the firewall Even though Distributed Transaction Coordinator has been enabled the distributed transaction may still fail if the firewall is turned on and hasn't been set up properly for MSDTC. To set up the firewall for MSTC, follow these steps: Open the Windows Firewall window from the Control Panel. If the firewall is not turned on you can skip this section. Go to the Allow a program or feature through Windows Firewall window(for Windows XP, you need to allow exceptions and go to the Exceptions tab on the Windows Firewall window). Add Distributed Transaction Coordinator to the program list (windowssystem32msdtc.exe) if it is not already on the list. Make sure the checkbox before this item is checked. Again you need to change your firewall setting for both your local and remote machines. Now the firewall will allow msdtc.exe to go through so our next test won't fail due to the firewall restrictions. You may have to restart IIS after you have changed your firewall settings. In some cases you may also have to stop and then restart your fi rewall for the changes to take effect.
Read more
  • 0
  • 0
  • 19402

Packt
19 Jun 2010
10 min read
Save for later

Getting Started with Blender’s Particle System

Packt
19 Jun 2010
10 min read
We’ll cover a general introduction about Blender’s particle system; how to use it, when to use it, how useful it is on both small scale and large scale projects, and an overview of its implications. In this article, I’ll also discuss how to use the particle system to instance objects These are just but very few examples of what can really be achieved with the particle system, there’s a vast array of possibilities out there that can be discovered. But I’m hoping with these examples and definitions, you’ll find your way through the wonderful world of visual effects with the particle system. If you remember watching Blender Foundation’s Big Buck Bunny, it might not seem as a surprise to you that almost the entire film is filled up with so much particle goodness. Thanks to that, great improvements have been made to Blender’s particle system. As compared to my previous articles, this one uses Blender 2.5, the latest version of Blender which is currently in Alpha stage right now but is fully workable. However, in this article I wouldn’t be telling you what each of the button would do since that would take another article in itself and might deviate from an introductory approach. If you wanted to know more in-depth information about the whole particle system, you can check out the official Blender documentation or the Blender wiki. There had been great improvements on the particle system and now is the right time to start trying it out. So what are you waiting for? Hop on and ride with me in this journey! You can watch the video here. Prerequisites Before we begin with this article, it’s vital to first determine our requirements before proceeding on the actual application. Before going on, we need to have the following: Latest Blender 2.5 (you can grab a copy at http://www.blender.org or http://www.graphicall.org) Adequate hard disk space Decent processor and graphics card What is a Particle System and where can we find it in Blender? A particle system is a technique in Computer Graphics that is used to simulate a visual effect that would otherwise be very difficult and cumbersome if not impossible to do in traditional 3D techniques. These effects include crowd simulation, hair, fur, grass, fire, smoke, fluids, dust, snowflakes, and more. Particle Systems are calculated inside of your simulation program in several ways and one of the most common ones is the Newtonian Physics calculation which regards forces like wind, magnetism, friction, gravity, etc. to generate the particle’s motion along a controllable environment. Properties or parameters of particle systems include: mass, speed, velocity, size, life, color, transparency, softness, damping, and many more. Particle’s behavior along a certain span of time are then saved and written on to your disk. This process is called caching, which enables you to view and edit the particle’s behavior within the timeframe set. And when you’re satisfied with the way your particles act on your simulation space, you can now permanently write these settings to the disk, called baking. Be aware that the longer your particle system’s life is and the greater the number, the more hard disk space it uses, so for testing purposes, it is best to keep the particles number low, then progressively increase them as needed. Particle mass refers the natural weight (in a gravitational field) of a single particle object/point, where higher mass means a heavier particle and a lower mass implies a lighter particle. A heavy particle is more resistant to external forces such as wind but more reactive to gravitational force as compared to a lighter particle system which is a direct opposite. Particle speed/velocity refers to how fast or slow the particle points are being thrown or emitted from their source within a given time. They can be displaced and controlled in the x, y, or z directions accordingly. A higher velocity will create a faster shooting particle (as seen in muzzle flares/flash) and a lower one will create slower particle shots. Size of the particles is one of the most important setting when using a particle system as object instances, since this will better control the size of the objects on the emitting plane as compared to manually resizing the original object. With this option, you can have random sizes which will give the scene a more believable and natural look and offcourse, an easier setup as compared to creating numerous objects for this matter. Particle life refers to the lifespan of the particles, for how long they will be existent until they disappear and die from the system. In some cases, having a large particle life is useful but it can have some speed drawbacks on your machine. Imagine emitting one million particles within 5 seconds where only half of it is relevant within the first few seconds. That could mean 500,000 particles cached is a sheer waste and rendering your machine slower. Having smaller particle lives sometimes is also useful especially when you’re creating small scale smoke and fire. But all these really depend on the way you setup your scenes. Play around and you’ll find the best settings that suit your needs. Note though that in Blender, only Mesh objects can be particle emitters (which is simply rational for this purpose). You can modify the size and shape of the mesh object and the particle system reacts accordingly. The direction from which particles are emitted is dictated by the mesh normals, which I will discuss along the way. In Blender 2.5, we can find the Particle System by selecting any mesh object and clicking the Particles Button in the Properties Editor, as seen in the screenshot. Later, we’ll add and name particle systems and go over their settings more closely. Blender 2.5’s Particle System   What are the types of Blender particle system? Currently, there are only two types of particle systems in Blender 2.5, namely Emmiter and Hair.  With few on the list, these two have already proved to be very handy tools in creating robust simulations. Particle System Types   Let’s begin by learning what an Emitter Type is. Aside from the fact that the term emitter is used to define the source of the particles, the emitter type is one different thing on its own. The Emitter, being the default particle type, is one of the most commonly used particle system type. With it you can create dust, smoke, fire, fluids, snowflakes, and the like. Inside Blender, make the default cube a particle emitter with the type set as Emitter. Leave the default settings as they are and press ALT+A in the 3D Viewport to playback the animation and observe the way the particles act in your observable space, that is, the 3D space that your object is in. During the playback process, the particle system is already caching the position of the particle points in your space and writing these on to the disk. Naturally, this is how the emitter type will act on our space, with a slight pulse from emitter then it drops down as an effect of the gravity. That pulse is coming from the Normal value which tells how strong the points are spurted out until they get affected by external forces. There’s more to the emitter type than there seems to be, so don’t hold back and keep changing the settings and see where they lead you to. And if you can, please send me what you got, I’d be very pleased to see what fun things you came up with. Emitter Type   Leaving from the default settings we had awhile back, change your current frame to 1 (if it is not yet set as such) then let’s change the type from Emitter to Hair. Instantly, you’ll notice that strands come bursting out of our default mesh. This is the particle hair’s nature, whichever frame you are in now, it will stay in the same frame, regardless of any explicit animation you add in. As compared to the Emitter type, Hair doesn’t need to be cached to see the results, it’s an on-the-fly process of editing particle settings. Another great advantage of the hair type over the emitter type is that it has a dedicated Particle Mode which enables you to edit the strands as though you were actually touching real hair. With the hair type, you can create systems like fur, grass, static particle instances/grouping, and more. Hair Type   Basic and Practical Uses of the Particle System Now let’s on the real business. From here on, I’ll approach the proceeding steps in a practical application manner. First, let’s check some of the default settings and see where they lead us. Fire up a fresh Blender session by opening up Blender or by pressing CTRL+N (when you already have it open from our steps awhile ago). Fresh Blender 2.5 Session   Delete the default cube and add in a Plane object. Adding a Plane Primitive   Position the camera’s view such that the plane is just on top of the viewing range, this will give us more space to see the particles falling. Adjusting the View   Select the Plane Mesh and in the Particle Buttons window, add a new Particle System and leave the default values as they are. In the 3D Viewport, press ALT+A to play and pause the animation or use the play buttons in the Timeline Window. Pick a frame you’re satisfied with, any will do right now. New Particle System   Next, add a new material to the Plane Mesh and the Particle System. Activate the Material Buttons and add a new material, then change the material type from Surface to Halo. Halos is a special material type for particles; they give each point a unique shading system compared to the Surface shaders. With halos, you can control the size of the particles, their transparency, color, brightness, hardness, textures, flares, and other interesting effects. With just the default values, let’s render out our scene and see what we get. Halo Material   Halo Rendered   Right now, this doesn’t look too pleasing, but it will be once we get the combinations right. Next, let’s try activating Rings under the halo menu, then Lines, Star, and finally a combination of the three. Below are rendered versions of each and their combination. Additional Options for Halo   Halo with Rings   Halo with Lines   Halo with Star   Halo with Rings, Lines, and Star   Just by altering the halo settings alone, we can achieve particle effects like pollen dust as seen in the image below where the particle effect was composited over a photo. Particle Pollen Dust  
Read more
  • 0
  • 0
  • 8290

article-image-getting-started-facebook-application-development-using-coldfusionrailo
Packt
19 Jun 2010
5 min read
Save for later

Getting Started with Facebook Application Development using ColdFusion/Railo

Packt
19 Jun 2010
5 min read
There are other CFML Facebook articles on the internet such as Ray Camden’s tutorial with ColdFusion 8; however Facebook continues to innovate and change, and a majority of those resources are out of date for Facebook’s 2010 updates. Things such as “profile boxes” are passé, and now you have to work with “Application Tabs.” In addition, I have found that there are some general concepts of how Facebook applications work. These have not been covered well in other resources. Why Facebook? According to statistics, Facebook is the 3rd highest traffic site in the US right now (statistics for the rest of the world weren’t readily available). The nature of Facebook is that people socialize, and look at what other people are doing, which means that if your friends post that they are using certain applications or visiting certain sites, you know about it, and for most of us, that’s a good enough reason to check it out.  Thats what's called Grass roots marketing, and it works. “The average U.S. Internet user spends more time on Facebook than on Google, Yahoo, YouTube, Microsoft, Wikipedia and Amazon combined.” That should tell you something. There is a big market to tap into, and should answer the question—why Facebook. Even if you think Facebook isn't a useful tool for you, you can’t argue with the numbers when it comes to reaching potential customers. Why CFML with Facebook? Hopefully your interest in ColdFusion and/or Railo answers this. Since CFML is such an easy to learn and powerful extensible programming language, it only makes sense that we should be able to build Facebook applications with it. There are always some cautions with making websites talk to each other. Using CFML with Facebook is no different; however most of these have been overcome by people already, and you can easily zip through this by copy/pasting the work of others. The basic framework for my applications is the same, and you can use this as your jumping-off point to work on your own applications. Understanding Data Flow Facebook is rather unique in how it is structured, and understanding this structure is critical to being able to build applications properly. You will save yourself a lot of frustration by reviewing this section before you begin writing code. In most websites or web applications, people type in a web address, and they connect directly to your web server, where your application handles the business logic, database interaction and any other work, and then gives web content back to the requesting user. This is not the case with Facebook. With Facebook applications, users open up their web browsers to a Facebook web address (the “Canvas URL”), Facebook’s servers make a “behind the scenes” request to your web server (the “Callback URL”), your application then responds to Facebook’s request, and then, Facebook does the final markup and sends the web page content back to the user’s browser. If you followed that, you see that users always interact with Facebook, while Facebook’s server is the one that talks to your application. You can also connect back to Facebook via their RESTful API to get information about users, friends, photos, posts and more. So here are two important concepts to understand: Your Facebook application code lives on your web server, separate from Facebook. You will get web requests from Facebook on behalf of Facebook users. Users should always be interacting with Facebook’s web site; They should never go directly to your web server The Canvas URL is a Facebook address, which you will setup in the next section. The Callback URL is the root where you put your application files (*.cfc and *.cfm). It is also where you will put your CSS files, images, and anything else your application needs. The Callback URL can be a directory on any web hosting account, so there is no need to setup a separate web host for your Facebook application. Setting up a new Facebook application Generally speaking, setting up a new Facebook application is pretty easy. There are a few things that can trip you up, and I will highlight them. The first thing to do is log into your Facebook account, and authorize the Facebook Developer application by going to this URL:http://apps.facebook.com/developer/ Once you have authorized this application, you will see a link to create a new application. Create a new application, and give it a name: Fill in the description if you want, give it an icon and logo if you wish. Click on the Canvas menu option. Enter the canvas page url (this becomes the URL on facebook’s site that you and your users will go to – apps.facebook.com/yourapp). Enter the callback URL (the full URL to YOUR web server directory where your CFML code will reside. Very important: Select Render method to be “FBML” (which stands for Facebook Markup Language). The other options you can leave as their default values. When you are done, save your changes. The application summary page will show you some important information, specifically the API Key and Application Secret, which you will need in your application later. Consider using Facebook’s “sandbox” mode which makes your application invisible to the world while you are developing it. Likewise, when you are done with your application, consider using Facebook’s application directory to promote your application.
Read more
  • 0
  • 0
  • 2277

Packt
19 Jun 2010
5 min read
Save for later

Getting Started with Blender’s Particle System- A Sequel

Packt
19 Jun 2010
5 min read
Creating Fire Taking from the same setup we had for the creating the smoke, making a fire is almost a similar process except for a few changes: the halo shader settings and force field strengths. Let’s go ahead and start changing the halo shader such that we change the color, hardness, add, and to disable the texture option. Then, we change the Force Field from Texture to Force with Strength of -6.7. Halo Settings for Fire   Force Field Settings   Fire Test Render   Furthermore, we can achieve even more believable results when we plug these image renders over to our compositor for some contrast boosting and other cool 2d effects. Creating Bubbles Let’s start a new Blender file, delete the default Cube, and replace it with a Plane primitive. Then let’s position the camera such that our plane is just below our view. Preparing the View   Next, let’s add a new particle system to the Plane and name it “Bubble”. Check the screenshots below for the settings. Bubble Cache Settings   Bubble Emission Settings   Bubble Velocity Settings   Bubble Physics Settings   Bubble Display Settings Bubble Field Weights Settings Now that we’ve got those settings in (remember though to play around because your settings might be way better than mine), let’s add a UV Sphere with the default divisions to our scene and name it “Bubble”. Then place it somewhere that the camera view won’t see. Adding, Moving, and Renaming the UV Sphere   What we’ll be doing next is to “instance” the UV Sphere (“Bubble”) we just added into the emitter plane, thus obeying the Particle Settings that we’ve set awhile back. To do this, select the Emitter plane and edit the Render and Display settings under Particle Settings (as seen below). Emitter Render and Display Settings Now if we play the animation in our 3D Viewport, you’ll now notice that the UV Sphere is now instanced to where the particle points are before, replacing them with a mesh object. Often, the instanced Bubble object would look small in our view, if this happens, simply scale the Bubble object and it will propagate accordingly in our Particle System. Instanced Bubble Objects   And that’s about it! Coupled with some nice shaders and compositing effects, you can definitely achieve impressive and seamless results. Bubbles with Sample Shaders and Image Background   Bubble Particles Composited Over a Photograph Bubbles and Butterflies   Creating Rockslides Similar to the concept of creating bubbles via Particle Systems, let’s derive the steps and create something different. This time, we’ll take advantage of Blender’s physics systems to automate natural motion and collision interaction. We won’t be using the Blender Game Engine for this matter (which should do almost the same thing), but instead we’re still going to use the particle system that is present in Blender. Like how we started the other topics, this time again, we’ll start by refreshing Blender’s view and starting a new session. Delete the default cube and add a plane mesh or a grid and start modeling a mountain-like terrain. This will be our slope from which our rock particles will fall and slide later on. You can use whichever technique you have on your disposal. Fast forward into time, here’s closely what we should have: Terrain Model for Rock Sliding   Next step is to create the actual rocks that are going to be falling and sliding on our terrain mesh. It’s optimal to start with an Icosphere and model from there. Be sure to move the models out of the camera’s view since we don’t want to see the original meshes, only the instances that are going to be generated. Model five (5) variations of the rocks and create a group for them named “RockGroup”. Rock Group Add an emitter plane across the top of the mountain terrain, this will be our particle rock emitter. Rock Particle Emitter   Next, create a Particle System on the emitter mesh and call it “RockSystem”. And this time, we’ll use the default gravity settings to simulate falling rock. Check the screenshots below for the particle setup.           Additionally, we must set the terrain mesh as a collision object such that the particles react to it whenever they collide. Play around with the settings until you’re satisfied with the behavior of your particles. Press ALT+A or click the play button in the Timeline Window to preview the animation. Setting Terrain as Collision   Single Frame from the Animation   Single Frame Rendered  
Read more
  • 0
  • 0
  • 3324

article-image-creating-composition-components-jsf-20
Packt
18 Jun 2010
7 min read
Save for later

Creating Composition Components in JSF 2.0

Packt
18 Jun 2010
7 min read
(For more resources on JSF, see here.) A great feature of Facelets consists in composition components (available starting with JSF 2.0). For a better understanding, we will start with a traditional application, and we will compare it with an application that uses composition components. At the end, you will love composition components. Getting ready We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library. How to do it... Let's suppose that we have a list of books, characterized by title, author, and price, and we need to display this list in a table and provide the sorting (ascending/descending) action for each category (see next screenshot): Focusing on this view (not on functionality or backing beans), we will probably write a JSF page like the following (this is the traditional approach): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <h:head> <title> Composition components in JSF 2.0</title> <style type="text/css"> .header { text-align: left; letter-spacing:5px; color:#000099 } .odd { background-color: yellow } .even { background-color: orange } </style> </h:head> <f:view> <h:form> <h:dataTable id="booksId" value="#{booksStore.books}" var="bk" rowClasses="odd, even" headerClass="header"> <!-- book title --> <h:column> <f:facet name="header"> <h:panelGroup> <h:outputText value="Book Title" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="booktitleascid" value="ascending" /> <f:param name="by" value="title"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="booktitledescid" value="descending" /> <f:param name="by" value="title"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup> </f:facet> <h:outputText value="#{bk.title}" /> </h:column> <!-- book author --> <h:column> <f:facet name="header"> <h:panelGroup> <h:outputText value="Book Author" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookauthorascid" value="ascending" /> <f:param name="by" value="author"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookauthordescid" value="descending" /> <f:param name="by" value="author"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup></f:facet><h:outputText value="#{bk.author}" /></h:column> <!-- book price --> <h:column> <f:facet name="header"> <h:panelGroup> <h:outputText value="Book Price" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookpriceascid" value="ascending" /> <f:param name="by" value="price"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookpricedescid" value="descending" /> <f:param name="by" value="price"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup> </f:facet> <h:outputText value="#{bk.price}" /> </h:column> </h:dataTable> </h:form> </f:view></html> In addition, we have two backing beans as follows: A Book.java backing bean that maps the book characteristics: package bean;import javax.faces.bean.ManagedBean;import javax.faces.bean.SessionScoped;@ManagedBean@SessionScopedpublic class Book { private String title; private String author; private String price; public Book(String title, String author, String price) { this.title = title; this.author = author; this.price = price; } public Book() { } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }} A BooksStore.java backing bean that defines a list of Book instances and defines a method for sorting the books by title, author, or price is shown next: package bean;import java.util.ArrayList;import java.util.List;import javax.faces.bean.ManagedBean;import javax.faces.bean.SessionScoped;import javax.faces.context.FacesContext;import javax.servlet.http.HttpServletRequest;@ManagedBean@SessionScopedpublic class BooksStore {private List books = new ArrayList();public BooksStore() { books.add(new Book("Learning Website Development with Django", "Ayman Hourieh", "€26.34")); books.add(new Book("Building Websites with Joomla! 1.5", "Hagen Graf", "€29.74")); books.add(new Book("ASP.NET 3.5 Application Architecture and Design", "Vivek Thakur", "€30.99")); books.add(new Book("Drupal 6 Themes", "Ric Shreves", "€26.34")); books.add(new Book("WordPress Theme Design", "Tessa Blakeley Silver", "€26.34")); } public List getBooks() { return books; } public void setBooks(List books) { this.books = books; } public void sortBooks() { FacesContext facesContext = FacesContext.getCurrentInstance(); HttpServletRequest httpServletRequest = (HttpServletRequest) facesContext.getExternalContext().getRequest(); String by = httpServletRequest.getParameter("by"); String order = httpServletRequest.getParameter("order"); System.out.println("The books should be order " + order + " by " + by + "!"); //ordering books }} Obviously, the redundancy of the JSF view is annoying and very primitive. We can fix this by defining a composition component that can be invoked instead of repeating code (the backing beans remain unchanged). The composition component can be created by following a few steps. To start with, we define the composition component page and place it under the /WEB-INF folder: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <ui:composition> <h:column> <f:facet name="header"> <h:panelGroup> <f:verbatim>Book-</f:verbatim> <h:outputText value="${attr}" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{compbean.sortBooks}"> <h:outputText value="ascending" /> <f:param name="by" value="${attr}"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{compbean.sortBooks}"> <h:outputText value="descending" /> <f:param name="by" value="${attr}"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup> </f:facet> <h:outputText value="${book[attr]}" /> </h:column> </ui:composition></html> Next, we define a tag library file to map the tag name to the tag source or, in other words, to map the name of the composition component with the composition component source page. In addition, it defines the namespace used to access the tag. This is an XML file that looks like this: <?xml version="1.0"?><!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd"><facelet-taglib> <namespace>http://www.my.facelets.component.com/jsf</namespace> <tag> <tag-name>tableColumn</tag-name> <source>mycomp.xhtml</source> </tag></facelet-taglib>
Read more
  • 0
  • 0
  • 3459

article-image-getting-started-jquery
Packt
18 Jun 2010
3 min read
Save for later

Getting Started with jQuery

Packt
18 Jun 2010
3 min read
(For more resources on jQuery, see here.) jQuery - How it works To understand how jQuery can ease web client (JavaScript based) development, one has to understand two aspects of jQuery. They are: Functionalities Modules Understanding the functionalities/services provided by jQuery will tell you what jQuery provides and understanding the modules that constitute jQuery will tell you how to access the services provided by jQuery. Here are the details. Functionalities The functionalities provided by jQuery can be classified into following: Selection Attributes handling Element manipulation Ajax Callbacks Event Handling Among the above listed functionalities, selection, element manipulation and event handling makes common tasks very easily implementable or trivial. Selection Using this functionality one can select one or multiple HTML elements. The raw JavaScript equivalent of the selection functionality is: document.getElementByID(‘<element id>’) or document.getElementByTagName(‘<tag name>’) Attributes handling One of most required task in JavaScript is to change the value of an attribute of a tag. The conventional way is to use getElementByID to get the element and then use index to get to the required attribute. jQuery eases it by using selection and attributes handling functionality in conjunction. Element handling There are scenarios where the values of tags need to be modified. One of such scenarios is rewriting text of a <p> tag based on selection from combo box. That is where element handling functionality of jQuery comes handy. Using the element handling or DOM scripting, as it is popularly known, one can not only access a tag but also perform manipulation such as appending child tags to multiple occurrences of a specific tag without using for loop. Ajax Ajax is of the concept and implementation that brought the usefulness of JavaScript to the fore. However, it also brought the complexities and the boilerplate code required for using Ajax to its full potential. The Ajax related functionalities of jQuery encapsulates away the boilerplate code and lets one concentrate on the result of the Ajax call. The main point to keep in mind is that encapsulation of the setup code does not mean that one cannot access the Ajax related events. jQuery takes care of that too and one can register to the Ajax events and handle them. Callbacks There are many scenarios in web development, where you want to initiate another task on the basis of completion of one task. An example of such a scenario involves animation. If you want to execute a task after completion of an animation, you will need callback function. The core of jQuery is implemented in such a way that most of the API supports callbacks. Event handling One of the main aspects of JavaScript and its relationship with HTML is the events triggered by the form elements can be handled using JavaScript. However, when multiple elements and multiple events come into picture, the code complexity becomes very hard to handle. The core of jQuery is geared towards handling the events in such a way that complexity can be maintained at manageable levels. Now that we have discussed the main functionalities of jQuery, let us move onto the main modules of jQuery and how the functionalities map onto the functionalities.
Read more
  • 0
  • 0
  • 2141
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-build-iphone-android-and-ipad-applications-using-jqtouch
Packt
18 Jun 2010
12 min read
Save for later

Build iPhone, Android and iPad Applications using jQTouch

Packt
18 Jun 2010
12 min read
  jQuery Plugin Development Beginner's Guide Build powerful, interactive plugins to implement jQuery in the best way possible Utilize jQuery's plugin framework to create a wide range of useful jQuery plugins from scratch Understand development patterns and best practices and move up the ladder to master plugin development Discover the ins and outs of some of the most popular jQuery plugins in action A Beginner's Guide packed with examples and step-by-step instructions to quickly get your hands dirty in developing high quality jQuery plugins       jQuery is a javascript framework that simplifies javascript development life cycle for web applications. Its greatest force comes from the ease of use and the huge number of plugins available. As a result of which javascript developers are exposed to a large number of enterprise components like Sort Tables, Editable Tables with Ajax and also web application components for animation, data manipulation. One such plugin with very powerful effects is the jQTouch; this plugin can be used by any web application developer with small experience in jquery to build applications for iPhone, iPad and Android devices. For now, just to get a feel, you can point your internet enabled iPad, iPhone or Android device to http://www.afrovisiongroup.com/twigle and test the application. Other examples of applications that can be developed using jQtouch include Gmail for the iPad or facebook touch. Getting Started Before we start using jQTouch, I would love to put across a few facts about jQTouch. jQTouch is a plugin for jQuery which means it only enhances jQuery to build smartphone applications that support swiping, and all the other touch gestures. Before you begin development with jQTouch, I would suggest you get comfortable with jQuery. jQTouch applications are not developed like regular web applications, where in an index page will be loaded with links that lead to other pages, and each page is loaded from the server every time a visitor clicks on a link. With jQTouch, all the pages are loaded once inside the index.html and each page is represented as a seperate div element in the index page. For example, the following html code snippet (<div id='page_name'>content</div>) represents a page in your jQTouch application and a link to that page is as follows (<a href='#page_name'>link to page name</a>). You can have as many pages as you want with all the pages having links to other pages inside the index.html file, but remember all this is stored in one single file index.html. The link clicks and navigation actions are implemented using javascript inbuilt into jQTouch. You will get to understand this as we implement twigle. Let's first get to know more about twigle. It is a twitter search application for smartphones loaded from the web. We will use jQTouch for client side development, jQuery ajax plugin for the server side communication and PHP in the backend to get the search results from the twitter Search API. jQTouch comes with javascript files and css files with themes. This defines the look and feel of the application. You won't have to bother about the design as the plugin already comes with predefined styles and graphics from which you can use as the base and extend it further to create your own unique looks. There are two themes that come with the plugin: apple theme and jqt theme.  Just like the name implies, the apple theme looks and feels like native iPhone OS apps. The plugin styles are predefined for the toolbar, rounded button, etc. You will discover this as we move on. jQTouch applications are basically developed in a single file, usually index.html. It contains the html code, javascript code and the styling. Everything in your application happens inside this file which gets loaded into your smartphone once like gmail and the other google applications. For example [code]  &lt;html&gt; &lt;head&gt; &lt;/head&gt; &lt;body&gt; &lt;div id='home'&gt; &lt;div class='toolbar'&gt;  Home Page &lt;/div&gt; &lt;div&gt;  this is the home page &lt;/div&gt; &lt;/div&gt; &lt;/body&gt; &lt;/html&gt; [/code] The above html code should produce the following: After installing and initializing the jQtouch plugin with the apple theme, you should have the following: Notice how the <div class='toolbar'><h1>Home Page</h1></div> gets styled into the iPhone or iPad toolbar's look and feel. Now, on the whole, the page looks more or less like a native iPhone application. Developing with jQTouch To develop your iPhone OS or Android OS applications with jQtouch you need to have jQuery and jQTouch libraries which you can download from http://www.jqtouch.com/. Next, get your favorite code editor (dreamweaver, notepad ++, etc) and we can get started. Remember, we are going to look at how to develop an application like twigle here. You can check out the demo of the application at http://www.afrovisiongroup.com/twigle. This is a twitter search application for smartphones loaded from the web. We will use jQTouch for client side development, jQuery ajax plugin for the server side communication and PHP in the backend to get the search results from the twitter Search API. Lets Get to work: Create a folder on your local web server directory called twigle Download the jQTouch package and unzip it into the folder twigle, this will give you the following structure: twigle/demos(this folder contains the sample applications. You can look at the source to learn more about these) /extensions(this folder contains jQTouch extensions that are like its own plugins) /jqtouch(this folder contains the javascript and css files needed for jQTouch to work) /themes (this folder contains the theme files and you can create your own themes too) /license.txt /readme.txt /sample.htaccess Now we create two files in the twigle folder: index.html and twigle.php The index.html will hold our application views(pages represented as html DIV Tags) and the twigle.php will be our business logic backend that connects the twitter API to our index.html front end. Javascript and AJAX communications comes between the index.html and the twigle.php to load twitter search results for any given search request. Paste the following code into the index.html file: [code] &lt;!doctype html&gt;  &lt;html&gt;      &lt;head&gt;          &lt;meta charset="UTF-8" /&gt;          &lt;/head&gt; &lt;body&gt; &lt;div id="home"&gt;          &lt;div class="toolbar"&gt;             &lt;h1&gt;TWIGLE&lt;/h1&gt;             &lt;a href="#info" class="button leftButton flip"&gt;Info&lt;/a&gt;             &lt;!-- &lt;a href="#search_results" class="button add slideup"&gt;+&lt;/a&gt;   --&gt;        &lt;/div&gt;             &lt;form id="search"&gt;  &lt;ul class="rounded"&gt; &lt;li id="notice"&gt; Type your search term below and hit search twitter&lt;/li&gt; &lt;li&gt; &lt;input type="text" id="keyword" name="keyword" placeholder="type your search term here"&gt; &lt;/li&gt; &lt;/ul&gt; &lt;a href="#" class="whiteButton submit"&gt;SEARCH TWITTER&lt;/a&gt;  &lt;/form&gt;        &lt;/div&gt;         &lt;/div&gt;  &lt;div id="info"&gt; &lt;div class="toolbar"&gt; &lt;a href="#home" class="button leftButton flip"&gt;back&lt;/a&gt; &lt;h1&gt;TWIGLE BY mambenanje&lt;/h1&gt; &lt;/div&gt; &lt;div&gt; &lt;ul class='rounded'&gt; &lt;li&gt;mambenanje is CEO of AfroVisioN Group - www.afrovisiongroup.com&lt;br /&gt; And TWIGLE is a tutorial he did for packtpub.com&lt;/li&gt; &lt;li&gt;TWIGLE runs on iPhone and Android because its powered by jqtouch and it helps users search twitter from their internet connected handhelds&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;/div&gt; &lt;div id="search_results"&gt; &lt;div class="toolbar"&gt; &lt;a href="#home" class="button leftButton flip"&gt;back&lt;/a&gt; &lt;h1 id="search_title"&gt;Search results&lt;/h1&gt; &lt;/div&gt; &lt;div&gt; &lt;ul class="rounded" id="results"&gt; &lt;/ul&gt; &lt;/div&gt; &lt;/div&gt; &lt;/body&gt; &lt;/html&gt; [/code] Thats the DOM structure for our application. Taking a close look at it,  you will see three main div siblings of the <body> tag. These divs represent the pages our application will have and only one of these divs appears at a time in a jQTouch application. Note the toolbar class that is called inside each of those divs to represent the app view's toolbar(title bar + menu) on every given page. The <ul classs='rounded'> is also needed to represent rounded listed items typical for iPhone applications. So in summary our application has three pages which would be home, info and search_results. Lets explain the DOM for every page: Home: [code] &lt;div id="home"&gt;              &lt;div class="toolbar"&gt;                  &lt;h1&gt;TWIGLE&lt;/h1&gt;                  &lt;a href="#info" class="button leftButton flip"&gt;Info&lt;/a&gt;                   &lt;!-- &lt;a href="#search_results" class="button add slideup"&gt;+&lt;/a&gt;   --&gt;             &lt;/div&gt;              &lt;form id="search"&gt;  &lt;ul class="rounded"&gt; &lt;li id="notice"&gt; Type your search term below and hit search twitter&lt;/li&gt; &lt;li&gt; &lt;input type="text" id="keyword" name="keyword" placeholder="type your search term here"&gt; &lt;/li&gt; &lt;/ul&gt; &lt;a href="#" class="whiteButton submit"&gt;SEARCH TWITTER&lt;/a&gt;  &lt;/form&gt;             &lt;/div&gt;          &lt;/div&gt;  [/code] The home page has a toolbar that contains the TWIGLE heading, along with a jQTouch button that is left aligned and when clicked, flips to the next page which is Info. The other button which leads to the search_results page is commented out using html comments. Its there to show that you can add more buttons to the toolbar. Next is the form which has the id:search. This is how jQTouch works with forms with no action or method. The form submission is done via javascript which will be explained later. The rest is instruction and the keyword input field. Look closely at the search twitter button. Its not a typical input button, but an anchor tag styled with jQTouch theme classes that tells jQTouch this is a white button. It is responsible for initiating the form submission. The home page is the most important page in this application as it contains the form and like every home page it is also the welcome page of the application. The Info Page: [code]   &lt;div id="info"&gt; &lt;div class="toolbar"&gt; &lt;a href="#home" class="button leftButton flip"&gt;back&lt;/a&gt; &lt;h1&gt;TWIGLE BY mambenanje&lt;/h1&gt; &lt;/div&gt; &lt;div&gt; &lt;ul class='rounded'&gt; &lt;li&gt;mambenanje is CEO of AfroVisioN Group - www.afrovisiongroup.com&lt;br /&gt; And TWIGLE is a tutorial he did for packtpub.com&lt;/li&gt; &lt;li&gt;TWIGLE runs on iPhone and Android because its powered by jqtouch and it helps users search twitter from their internet connected handhelds&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;/div&gt; [/code] Its a tradition in software development to always have an about page for the software and iPhone/Android apps are no exception. The info page was created to give users of the twigle application an idea how this application came about. Closely look at the toolbar. It contains a button that leads to the home page and is styled to appear like a button. It flips to the home page when clicked. The rest is just literature that is presented in rounded lists.  
Read more
  • 0
  • 0
  • 6300

article-image-security-and-disaster-recovery-prestashop-13
Packt
18 Jun 2010
6 min read
Save for later

Security and Disaster Recovery in PrestaShop 1.3

Packt
18 Jun 2010
6 min read
We will do everything possible to make sure our store is not the victim of a successful attack. Fortunately, the PrestaShop team takes security very seriously and issues updates and fixes as soon as possible after any problems are discovered. We just have to make sure we do everything we can and also implement the PrestaShop upgrades as soon as they are available. It is also vital that we always have a recent copy of our store because one day, it is probably inevitable that our shop will die on us. It might be a hacker or maybe we will accidentally muck it up ourselves. A recent backup to handle this type of event is a minor inconvenience, because without one, it is an expensive catastrophe. So let's get on with it... Types of security attacks There are different types of security attacks. Here is a very brief explanation of some of the most common ones. Hopefully, this will make it clear why security is an ongoing and evolving issue and not something that can ever be 100 percent solved out of the box. Common sense issues These are often overlooked—make sure your passwords are impossible to guess. Use number sequences that are memorable to you but unguessable and meaningless to everyone else. Combine number sequences with regular letters in a variety of upper and lower case. Don't share your passwords with anyone. This applies to anyone who has access to your shop or hosting account. Brute force This is when an attacker uses software to repeatedly attempt to gain access or discover a password by guessing. Clearly, the simplest defence against this is a secure password. A good password is one with upper and lower case characters, apparently random numbers and words that are not names or are in the dictionary. Does your administrator password stand up to these criteria? SQL injection attack A malicious person amends, deletes, or retrieves information from your database by cleverly manipulating the forms or database requests contained in the code of PrestaShop. By appending to legitimate PrestaShop database code, harm can be done or breaches of security can be achieved. Cross-site scripting Attackers add instructions to access code on another site. They do this by appending a URL pointing to malicious code to a PHP URL of a legitimate page on your site. User error This is straight forward. It is likely that while developing or amending your website, you will mess up some or perhaps all of your PrestaShop. I did it once while writing this article. I will give you the full details of my slightly embarrassing confession later. So with so many ways that things can go wrong, we better start looking at some solutions. Employees and user security If you plan to employ someone or if you have a partner who is going to help in your new shop, it makes good sense to create a new user account so that they have their own login details. Even if it will be only you who needs to use the PrestaShop control panel, there is still a good argument for creating two or more accounts. Here is why. First we will consider a scenario, though a slightly exaggerated one: Guns4u.com: Guns4u wants to offer articles about how to use its products. The management, probably correctly, believe that in-depth how-tos about all its products will boost sales and increase customer retention. The diverse nature of their products makes employing a single writer impossible. For example, an expert on small arms is rarely an expert on ground-to-air ordinance. And a user of laser targeting equipment probably doesn't know the first thing about ship-based artillery. This is quite a problem. The management decides they need a way to allow a whole team of freelance writers who can login directly to the PrestaShop CMS. But bearing in mind the highly dubious backgrounds some of these writers will have, how can they be trusted in the PrestaShop control panel? Users of Guns4u.com: Suppose you employ somebody to write articles for you. You don't really want them being able to play with product prices or payment modules. You would want to restrict them to the CMS area of the control panel. Similarly, your partner might be helping you wrap and pack your products. To avoid accidents you might like to restrict them to the Customers and Orders tab. Now consider this scenario. Even you, after reading this article, can make a mistake. It is a really good idea to create at least one extra user account for you. I always make myself a wrapping and packing account. I use it all the time and it is reassuring to know that I can't accidentally click anything that can cause a problem. This type of user security is common in large organisations. On a company intranet, employees will almost always be restricted to areas of the company system to which they need and nothing more. Below is how to create a new user account and then after that we will look at profiles and permissions to enforce the restrictions and permissions suitable to us. Okay, let's create a new user. Time for action – creating users As you have come to expect, this is really easy. Click on the Employees tab and then click on the Add new link. Enter the Last name, First name, and E-mail address of your new employee or user. The status box enables you to allow or disallow access to the new employee. Unless you have a reason for creating an account and not letting them use it, select the check mark (Allow). If you have reason to want to stop your new employee or user accessing your control panel, simply come back here and click on the cross. In the Profile drop-down box, choose Administrator. This will give the new user full access. We will investigate when this is a good idea and when you might like to change this, if you would like to add our freelance writer next. Click the Save button to create the new user account.
Read more
  • 0
  • 0
  • 3981

article-image-checkbox-persistence-tabular-forms-reports
Packt
17 Jun 2010
7 min read
Save for later

Checkbox Persistence in Tabular Forms (Reports)

Packt
17 Jun 2010
7 min read
(For more resources on Oracle, see here.) One of the problems we are facing with Tabular Forms is that pagination doesn't submit the current view of the Tabular Form (Report) page, and if we are using Partial Page Refresh (PPR), it doesn't even reload the entire page. As such, Session State is not saved prior to us moving to the next/previous view. Without saving Session State, all the changes that we might have made to the current form view will be lost upon using pagination. This problematic behavior is most notable when we are using a checkboxes column in our Tabular Form (Report). We can mark specific checkboxes in the current Tabular Form (Report) view, but if we paginate to another view, and then return, the marked checkboxes will be cleared (no Session State, no history to rely on). In some cases, it can be very useful to save the marked checkboxes while paginating through the Tabular Form (Report). Joel Kallman, from the APEX development team, blogged about this issue (http://joelkallman.blogspot.com/2008/03/ preserving-checked-checkboxes-in-report.html) and offered a simple solution, which uses AJAX and APEX collections. Using APEX collections means that the marked checkboxes will be preserved for the duration of a specific user's current APEX session. If that's what you need, Joel's solution is very good as it utilizes built-in APEX resources in an optimal way. However, sometimes the current APEX session is not persistent enough. In one of my applications I needed more lasting persistence, which can be used crossed APEX users and sessions. So, I took Joel's idea and modified it a bit. Instead of using APEX collections, I've decided to save the checked checkboxes into a database table. The database table, of course, can support unlimited persistence across users. Report on CUSTOMERS We are going to use a simple report on the CUSTOMERS table, where the first column is a checkboxes column. The following is a screenshot of the report region: W e are going to use AJAX to preserve the status of the checkboxes in the following scenarios: Using the checkbox in the header of the first column to check or clear all the checkboxes in the first column of the current report view Individual row check or clearing of a checkbox The first column—the checkboxes column—represents the CUST_ID column of the CUSTOMERS table, and we are going to implement persistence by saving the values of this column, for all the checked rows, in a table called CUSTOMERS_VIP. This table includes only one column: CREATE TABLE "CUSTOMERS_VIP" ( "CUST_ID" NUMBER(7,0) NOT NULL ENABLE, CONSTRAINT "CUSTOMERS_VIP_PK" PRIMARY KEY ("CUST_ID") ENABLE) Bear in mind: In this particular example we are talking about crossed APEX users and sessions persistence. If, however, you need to maintain a specific user-level persistence, as it happens natively when using APEX collections, you can add a second column to the table that can hold the APP_USER of the user. In this case, you'll need to amend the appropriate WHERE clauses and the INSERT statements, to include and reflect the second column. The report SQL query The following is the SQL code used for the report: SELECT apex_item.checkbox(10,l.cust_id,'onclick=updateCB(this);', r.cust_id) as cust_id, l.cust_name, l.cust_address1, l.cust_address2, l.cust_city, l.cust_zip_code, (select r1.sname from states r1 where l.cust_state = r1.code) state, (select r2.cname from countries r2 where l.cust_country = r2.code) countryFROM customers l, customers_vip rWHERE r.cust_id (+) = l.cust_idORDER BY cust_name The Bold segments of the SELECT statement are the ones we are most interested in. The APEX_ITEM.CHECKBOX function creates a checkboxes column in the report. Its third parameter—p_attributes—allows us to define HTML attributes within the checkbox <input> tag. We are using this parameter to attach an onclick event to every checkbox in the column. The event fires a JavaScript function— updateCB(this)—which takes the current checkbox object as a parameter and initiates an AJAX process. The fourth parameter of the APEX_ITEM.CHECKBOX function—p_checked_ values—allows us to determine the initial status of the checkbox. If the value of this parameter is equal to the value of the checkbox (determined by the second parameter—p_value) the checkbox will be checked. This parameter is the heart of the solution. Its value is taken from the CUSTOMERS_VIP table using outer join with the value of the checkbox. The outcome is that every time the CUSTOMERS_VIP table contains a CUST_ID value equal to the current checkbox value, this checkbox will be checked. The report headers In the Report Attributes tab we can set the report headers using the Custom option. We are going to use this option to set friendlier report headers, but mostly to define the first column header—a checkbox that allows us to toggle the status of all the column checkboxes. The full HTML code we are using for the header of the first column is: <input type="checkbox" id = "CB" onclick="toggleAll(this,10);"title="Mark/Clear All"> We are actually creating a checkbox, with an ID of CB and an onclick event that fires the JavaScript function toggleAll(this,10). The first parameter of this function is a reference to the checkbox object, and the second one is the first parameter—p_idx—of the APEX_ITEM.CHECKBOX function we are using to create the checkbox column. The AJAX client-side JavaScript functions So far, we have mentioned two JavaScript functions that initiate an AJAX call. The first—updateCB()—initiates an AJAX call that updates the CUSTOMERS_VIP file according to the status of a single (row) checkbox. The second one—toggleAll()— initiates an AJAX call that updates the CUSTOMERS_VIP file according to the status of the entire checkboxes column. Let's review these functions. The updateCB() JavaScript function The following is the code of this function: function updateCB(pItem){ var get = new htmldb_Get(null, $v('pFlowId'), 'APPLICATION_PROCESS=update_CB',$v('pFlowStepId')); get.addParam('x01',pItem.value); get.addParam('x02',pItem.checked); get.GetAsync(function(){return;}); get = null;} The function accepts, as a parameter, a reference to an object—this—that points to the checkbox we just clicked. We are using this reference to set the temporary item x01 to the value of the checkbox and x02 to its status (checked/unchecked). As we are using the AJ AX related temporary items, we are using the addParam() method to do so. These items will be available to us in the on-demand PL/SQL process update_CD, which implements the server-side logic of this AJAX call. We stated this process in the third parameter of the htmldb_Get constructor function— 'APPLICATION_PROCESS=update_CB'. In this example, we are using the name 'get' for the variable referencing the new instance of htmldb_Get object. The use of this name is very common in many AJAX examples, especially on the OTN APEX forum, and its related examples. As we'll see when we review the server-side logic of this AJAX call, all it does is update—insert or delete—the content of the CUSTOMERS_VIP table. As such, it doesn't have an immediate effect on the client side, and we don't need to wait for its result. This is a classic case for us to use an asynchronous AJAX call. We do so by using the GetAsync() method. In this specific case, as the client side doesn't need to process any server response, we can use an empty function as the GetAsync() parameter.
Read more
  • 0
  • 0
  • 3664

article-image-distributed-transaction-using-wcf
Packt
17 Jun 2010
12 min read
Save for later

Distributed transaction using WCF

Packt
17 Jun 2010
12 min read
(Read more interesting articles on WCF 4.0 here.) Creating the DistNorthwind solution In this article, we will create a new solution based on the LINQNorthwind solution.We will copy all of the source code from the LINQNorthwind directory to a new directory and then customize it to suit our needs. The steps here are very similar to the steps in the previous chapter when we created the LINQNorthwind solution.Please refer to the previous chapter for diagrams. Follow these steps to create the new solution: Create a new directory named DistNorthwind under the existing C:SOAwithWCFandLINQProjects directory. Copy all of the files under the C:SOAwithWCFandLINQProjectsLINQNorthwind directory to the C:SOAwithWCFandLINQProjectsDistNorthwind directory. Remove the folder, LINQNorthwindClient. We will create a new client for this solution. Change all the folder names under the new folder, DistNorthwind, from LINQNorthwindxxx to DistNorthwindxxx. Change the solution files' names from LINQNorthwind.sln to DistNorthwind.sln, and also from LINQNorthwind.suo to DistNorthwind.suo. Now we have the file structures ready for the new solution but all the file contents and the solution structure are still for the old solution. Next we need to change them to work for the new solution. We will first change all the related WCF service files. Once we have the service up and running we will create a new client to test this new service. Start Visual Studio 2010 and open this solution: C:SOAWithWCFandLINQProjectsDistNorthwindDistNorthwind.sln. Click on the OK button to close the projects were not loaded correctly warning dialog. From Solution Explorer, remove all five projects (they should all be unavailable). Right-click on the solution item and select Add | Existing Projects… to add these four projects to the solution. Note that these are the projects under the DistNorthwind folder, not under the LINQNorthwind folder: LINQNorthwindEntities.csproj, LINQNorthwindDAL.csproj, LINQNorthwindLogic.csproj, and LINQNorthwindService.csproj. In Solution Explorer, change all four projects' names from LINQNorthwindxxx to DistNorthwindxxx. In Solution Explorer, right-click on each project, select Properties (or select menu Project | DistNorthwindxxx Properties), then change the Assembly name from LINQNorthwindxxx to DistNorthwindxxx, and change the Default namespace from MyWCFServices.LINQNorthwindxxx to MyWCFServices.DistNorthwindxxx. Open the following files and change the word LINQNorthwind to DistNorthwind wherever it occurs: ProductEntity.cs, ProductDAO.cs, ProductLogic.cs, IProductService.cs, and ProductService.cs. Open the file, app.config, in the DistNorthwindService project and change the word LINQNorthwind to DistNorthwind in this file. The screenshot below shows the final structure of the new solution, DistNorthwind: Now we have finished modifying the service projects. If you build the solution now you should see no errors. You can set the service project as the startup project, run the program. Hosting the WCF service in IIS The WCF service is now hosted within WCF Service Host.We had to start the WCF Service Host before we ran our test client.Not only do you have to start the WCF Service Host, you also have to start the WCF Test client and leave it open. This is not that nice. In addition, we will add another service later in this articleto test distributed transaction support with two databases and it is not that easy to host two services with one WCF Service Host.So, in this article, we will first decouple our WCF service from Visual Studio to host it in IIS. You can follow these steps to host this WCF service in IIS: In Windows Explorer, go to the directory C:SOAWithWCFandLINQProjectsDistNorthwindDistNorthwindService. Within this folder create a new text file, ProductService.svc, to contain the following one line of code: <%@ServiceHost Service="MyWCFServices.DistNorthwindService. ProductService"%> Again within this folder copy the file, App.config, to Web.config and remove the following lines from the new Web.config file: <host> <baseAddresses> <add baseAddress="http://localhost:8080/ Design_Time_Addresses/MyWCFServices/ DistNorthwindService/ProductService/" /> </baseAddresses> </host> Now open IIS Manager, add a new application, DistNorthwindService, and set its physical path to C:SOAWithWCFandLINQProjectsDistNorthwindDistNorthwindService. If you choose to use the default application pool, DefaultAppPool, make sure it is a .NET 4.0 application pool.If you are using Windows XP you can create a new virtual directory, DistNorthwindService, set its local path to the above directory, and make sure its ASP.NET version is 4.0. From Visual Studio, in Solution Explorer, right-click on the project item,DistNorthwindService, select Properties, then click on the Build Events tab, and enter the following code to the Post-build event command line box: copy .*.* ..With this Post-build event command line, whenever DistNorthwindService is rebuilt the service binary files will be copied to the C:SOAWithWCFandLINQProjectsDistNorthwindDistNorthwindServicebin directory so that the service hosted in IIS will always be up-to-date. From Visual Studio, in Solution Explorer, right-click on the project item, DistNorthwindService, and select Rebuild. Now you have finished setting up the service to be hosted in IIS. Open Internet Explorer, go to the following address, and you should see the ProductService description in the browser: http://localhost/DistNorthwindService/ProductService.svc Testing the transaction behavior of the WCF service Before explaining how to enhance this WCF service to support distributed transactions, we will first confirm that the existing WCF service doesn't support distributed transactions. In this article, we will test the following scenarios: Create a WPF client to call the service twice in one method. The first service call should succeed and the second service call should fail. Verify that the update in the first service call has been committed to the database, which means that the WCF service does not support distributed transactions. Wrap the two service calls in one TransactionScope and redo the test. Verify that the update in the first service call has still been committed to the database which means the WCF service does not support distributed transactions even if both service calls are within one transaction scope. Add a second database support to the WCF service. Modify the client to update both databases in one method. The first update should succeed and the second update should fail. Verify that the first update has been committed to the database, which means the WCF service does not support distributed transactions with multiple databases. Creating a client to call the WCF service sequentially The first scenario to test is that within one method of the client application two service calls will be made and one of them will fail. We then verify whether the update in the successful service call has been committed to the database. If it has been, it will mean that the two service calls are not within a single atomic transaction and will indicate that the WCF service doesn't support distributed transactions. You can follow these steps to create a WPF client for this test case: In Solution Explorer, right-click on the solution item and select Add | New Project… from the context menu. Select Visual C# | WPF Application as the template. Enter DistributedWPF as the Name. Click on the OK button to create the new client project. Now the new test client should have been created and added to the solution. Let's follow these steps to customize this client so that we can call ProductService twice within one method and test the distributed transaction support of this WCF service: On the WPF MainWindow designer surface, add the following controls (you can double-click on the MainWindow.xaml item to open this window and make sure you are on the design mode, not the XAML mode): A label with Content Product ID Two textboxes named txtProductID1 and txtProductID2 A button named btnGetProduct with Content Get Product Details A separator to separate above controls from below controls Two labels with content Product1 Details and Product2 Details Two textboxes named txtProduct1Details and txtProduct2Details, with the following properties: AcceptsReturn: checked Background: Beige HorizontalScrollbarVisibility: Auto VerticalScrollbarVisibility: Auto IsReadOnly: checked A separator to separate above controls from below controls A label with content New Price Two textboxes named txtNewPrice1 and txtNewPrice2 A button named btnUpdatePrice with Content Update Price A separator to separate above controls from below controls Two labels with content Update1 Results and Update2 Results Two textboxes named txtUpdate1Results and txtUpdate2Results with the following properties: AcceptsReturn: checked Background: Beige HorizontalScrollbarVisibility: Auto VerticalScrollbarVisibility: Auto IsReadOnly: checked Your MainWindow design surface should look like the following screenshot: In Solution Explorer, right-click on the DistNorthwindWPF project item, select Add Service Reference… and add a service reference of the product service to the project. The namespace of this service reference should be ProductServiceProxy and the URL of the product service should be like this:http://localhost/DistNorthwindService/ProductService.svc On the MainWindow.xaml designer surface, double-click on the Get Product Details button to create an event handler for this button. In the MainWindow.xaml.cs file, add the following using statement: using DistNorthwindWPF.ProductServiceProxy; Again in the MainWindow.xaml.cs file, add the following two class members: Product product1, product2; Now add the following method to the MainWindow.xaml.cs file: private string GetProduct(TextBox txtProductID, ref Product product) { string result = ""; try { int productID = Int32.Parse(txtProductID.Text.ToString()); ProductServiceClient client = new ProductServiceClient(); product = client.GetProduct(productID); StringBuilder sb = new StringBuilder(); sb.Append("ProductID:" + product.ProductID.ToString() + "n"); sb.Append("ProductName:" + product.ProductName + "n"); sb.Append("UnitPrice:" + product.UnitPrice.ToString() + "n"); sb.Append("RowVersion:"); foreach (var x in product.RowVersion.AsEnumerable()) { sb.Append(x.ToString()); sb.Append(" "); } result = sb.ToString(); } catch (Exception ex) { result = "Exception: " + ex.Message.ToString(); } return result; } This method will call the product service to retrieve a product from the database, format the product details to a string, and return the string. This string will be displayed on the screen. The product object will also be returned so that later on we can reuse this object to update the price of the product. Inside the event handler of the Get Product Details button, add the following two lines of code to get and display the product details: txtProduct1Details.Text = GetProduct(txtProductID1, ref product1); txtProduct2Details.Text = GetProduct(txtProductID2, ref product2); Now we have finished adding code to retrieve products from the database through the Product WCF service. Set DistNorthwindWPF as the startup project, press Ctrl + F5 to start the WPF test client, enter 30 and 31 as the product IDs, and then click on the Get Product Details button. You should get a window like this image: To update the prices of these two products follow these steps to add the code to the project: On the MainWindow.xaml design surface and double-click on the Update Price button to add an event handler for this button. Add the following method to the MainWindow.xaml.cs file: private string UpdatePrice( TextBox txtNewPrice, ref Product product, ref bool updateResult) { string result = ""; try { product.UnitPrice = Decimal.Parse(txtNewPrice.Text.ToString()); ProductServiceClient client = new ProductServiceClient(); updateResult = client.UpdateProduct(ref product); StringBuilder sb = new StringBuilder(); if (updateResult == true) { sb.Append("Price updated to "); sb.Append(txtNewPrice.Text.ToString()); sb.Append("n"); sb.Append("Update result:"); sb.Append(updateResult.ToString()); sb.Append("n"); sb.Append("New RowVersion:"); } else { sb.Append("Price not updated to "); sb.Append(txtNewPrice.Text.ToString()); sb.Append("n"); sb.Append("Update result:"); sb.Append(updateResult.ToString()); sb.Append("n"); sb.Append("Old RowVersion:"); } foreach (var x in product.RowVersion.AsEnumerable()) { sb.Append(x.ToString()); sb.Append(" "); } result = sb.ToString(); } catch (Exception ex) { result = "Exception: " + ex.Message; } return result; } This method will call the product service to update the price of a product in the database. The update result will be formatted and returned so that later on we can display it. The updated product object with the new RowVersion will also be returned so that later on we can update the price of the same product again and again. Inside the event handler of the Update Price button, add the following code to update the product prices: if (product1 == null) { txtUpdate1Results.Text = "Get product details first"; } else if (product2 == null) { txtUpdate2Results.Text = "Get product details first"; } else { bool update1Result = false, update2Result = false; txtUpdate1Results.Text = UpdatePrice( txtNewPrice1, ref product1, ref update1Result); txtUpdate2Results.Text = UpdatePrice( txtNewPrice2, ref product2, ref update2Result); } Testing the sequential calls to the WCF service Let's run the program now to test the distributed transaction support of the WCF service. We will first update two products with two valid prices to make sure our code works with normal use cases. Then we will update one product with a valid price and another with an invalid price. We will verify that the update with the valid price has been committed to the database, regardless of the failure of the other update. Let's follow these steps for this test: Press Ctrl + F5 to start the program. Enter 30 and 31 as product IDs in the top two textboxes and click on the Get Product Details button to retrieve the two products. Note that the prices for these two products are 25.89 and 12.5 respectively. Enter 26.89 and 13.5 as new prices in the middle two textboxes and click on the Update Price button to update these two products. The update results are true for both updates, as shown in following screenshot: Now enter 27.89 and -14.5 as new prices in the middle two textboxes and click on the Update Price button to update these two products. This time the update result for product 30 is still True but for the second update the result is False. Click on the Get Product Details button again to refresh the product prices so that we can verify the update results. We know that the second service call should fail so the second update should not be committed to the database. From the test result we know this is true (the second product price didn't change). However from the test result we also know that the first update in the first service call has been committed to the database (the first product price has been changed). This means that the first call to the service is not rolled back even when a subsequent service call has failed. Therefore each service call is in a separate standalone transaction. In other words, the two sequential service calls are not within one distributed transaction.
Read more
  • 0
  • 0
  • 2138
article-image-how-microsoft-dynamics-nav-fits-consultancy-company
Packt
16 Jun 2010
15 min read
Save for later

How Microsoft Dynamics NAV fits a consultancy company

Packt
16 Jun 2010
15 min read
(Further on Microsoft Dynamics NAV:here.) The process The two main processes for Microsoft Dynamics NAV partners are implementing new projects and providing services such as support and upgrades to existing customers. A third process is selling infrastructure and assembling computer systems but this is an extra service, not the core business. To support the projects (jobs) the company needs people, software licenses and hardware. The people (resources) need to be carefully planned on the projects as they are the least flexible part of the company. Hardware (items) and software licenses (G/L accounts) will be purchased from vendors such as Microsoft. The projects can be divided into large and small projects. The larger projects are new implementations and upgrades. Smaller projects include implementing small features and helping users with regular support issues. Invoicing can be done in various ways. New implementations and small projects can be invoiced per billable hour while upgrades are sold fixed price. For hardware we will use items. Licenses are invoiced directly to the General Ledger. Large projects also have budgets and a plan that need to be maintained. If the budget is fully used and the planning milestones have not been reached there should be a new budget created in order to complete the project. To support this process we will use the Jobs functionality with some customizations. Projects are called Jobs in Microsoft Dynamics NAV so we will use that term from now on. The Jobs module has been completely redesigned by Microsoft for version 5. In this article we will use a lot of the new functionality where we would have done customizations in the older versions of Microsoft Dynamics NAV. Fits The registration of the Jobs can be done using the standard functionality of Microsoft Dynamics NAV as well as the budgeting and planning. The standard software also allows us to invoice Jobs both fixed price and on time and materials. We can also purchase items for our Jobs. Gaps The Jobs module in Microsoft Dynamics NAV is often referenced as a framework that almost always needs some changes. Fortunately, it is designed to be easily changed and we will do so to support our processes. Resource groups Although many companies work this way; budgeting on Resource Groups is not possible. We will create a solution for that. We will also make it possible to see the total number of planned, used and invoiced hours. Time registration The standard software allows us to register hours but it does not have a real-time sheet application. We will create one. Item calculation We will create a solution calculating the system assembling. As hardware specifications are changing rapidly we do not want to create a new item for each system when we may only sell that particular configuration once or twice. Issue registration Our support team needs a single point for registration of all support issues for all customers and follow up their workflow. For this we will also create the functionality to register and follow up issues. Getting started Before we start creating any new jobs, we should have a look at the data and posting model of the Microsoft Dynamics NAV Jobs module. The starting point is the Job table, which has Job Tasks and Job Planning Lines we can use for budgeting and planning. Each job can have its own prices. The Job Planning Lines get invoiced through the standard Microsoft Dynamics NAV Sales functionality which then creates Job Ledger Entries. How many jobs The first step is setting up a new job. There can be different angles on setting up jobs.This depends on how we want to work with the system. The minimum requirement is to have at least one job per Bill-to Customer. This enables us to do the invoicing.Some companies use jobs this way to use it as a pre-invoice engine. Another angle can be to set up new jobs nicely for each project we do for the customer. In our case this starts with the basic Dynamics NAV implementation.When this is finished we close the job. If the customer has any new requirements we will need to start a new job. This way we can keep better track of what issues we have outstanding with each customer. The downside of this methodology is that it requires some work to set up a new job every time. Most companies end up with a solution in the middle. It is common to set up a new job for larger jobs and to have a job for support issues. This also allows us to set up different invoicing strategies for each job. We will use this strategy. Job card Let's have a look at the Job Card and the important fields there. Let's see these fields in more detail: No.: This is the unique number of a job. We can use different number series strategies for this, from simple sequential numbering to linked number series for different job types or manual numbering. Description: This should be a logical description of the job for internal use. Most people will search on this field so make sure to have certain rules for naming. This will make searching for old jobs easier in the future. Bill-to Customer No.: Each job has one Bill-to Customer. If we want to invoice multiple customers for one job we will need to customize the application. Search Description: By default this will be populated with the value of the description field but can be changed to another value if required. Person Responsible: This is an informative field indicating who is responsible for this job. Blocked: If this field is checked, it is not possible to make new entries for this job. Use this for closed jobs. Job Posting Group: This refers to the G/L Accounts that are used for the Work In Progress postings (WIP). There can be different G/L Accounts for different types of jobs or WIP methods. WIP Method: Each job can have one Work in Progress method. We wild discuss this briefly later in this article. Status: The jobs have a limited set of status fields. The only available status values are Planning, Quote, Order, and Completed. Most companies want to have more sub statuses for the order phase.The best approach for this is to add a new status field that maps with the standard status field. This requires minimum changes to the application while creating new workflow possibilities. Allow Schedule/Contract Lines: If this field is not checked it is not possible to create planning lines, which have both schedule and contract options. When planning lines are created they will be split into a schedule and a contract line. Starting and Ending Date: These are informative fields that are only used to calculate the currency exchange rates for the job. Foreign Trade: In the jobs module it is possible to send calculate and create invoices in a currency other than the local currency. This will increase the complexity of the implementation and should be used carefully. Job task and planning lines When the Job is created, the next step is to create Job Tasks and Planning Lines.These can be used in different ways. Using job task lines we can cut the job into smaller pieces, which we can then schedule and invoice. The more detailed the job tasks are, the better we can measure the progress of the job, but the more work they require to maintain. Balance is the key to success here. The Job Tasks can be created with the same structure as the Chart of Accounts, meaning the actual Task Lines can be grouped using Begin and End Total lines. Each level can be indented for better readability. The Job Planning Lines are the detail lines of each job task. This defines what we will do and how this will be invoiced. A job planning line can be linked to the master data types Resource, Item, G/L Account, or Text. Job Tasks and Job Planning Lines can be copied very easily from other jobs. This allows us to reuse them and even create template jobs for frequently used combinations. The line type in the job planning line defines how it will be invoiced. There are three types: Schedule: The amounts on this line will only be used in for budgeting purposes. When invoicing we need to post one or more job journal lines that will be invoiced or we can create another job planning line with the invoice amount. Schedule lines should be used when billing on time and materials. Contract: This line will be invoiced with the exact amounts. However the amounts do not show up in the budget. This can be used when invoicing fixed price jobs in a schedule, for example: 50% when signing the contract and 50% on job completion. Both Schedule and Contract: This line will be invoiced exactly the same way as the contract lines but the amount will also show up in the budget. Job journal When the job tasks and job planning lines are set up we can start the job. During the job we will consume resources and items from our company. This should be registered using the Job Journal. When creating a job journal line a few fields are particularly important for the process: Line Type: This has the same options as the job planning line, Schedule,Contract, and Both Schedule and Contract. When the job journal line should be invoiced, the type should be Contract. When the job journal line is part of a fixed price the line type should be left blank. When the line type is Schedule, the system will create additional Job Planning Lines of this type which may corrupt our budget for the customer asthey are already created. Unit Cost and Unit Price: These fields will determine the cost of the job and the price that will be invoiced to the customer if the line type is Contract.This information is also used in the calculation of the Work in Progress.   Job examples Let's go through some different job scenarios to see how we can use this functionality. Chapter objects The chapter objects contain both the changes we discuss in this article and as the example jobs we will use. After importing chapter 8.job, run page 123.456.700 Jobs Add-on Setup and then run Initialise Application. When this completes, restart the Role Tailored Client. You should now see the Project Manager Role Center. 1 | The new implementation Implementing Microsoft Dynamics NAV 2009 is not an easy task and many things need to be taken care of before we can use the product. We will implement Microsoft Dynamics NAV for Packt Publishing. The job for this example is EXAMPLE1. For the implementation we will create various job task groups. Each part of the implementation gets a code. Because the sorting is done on this field we will create codes using numbers and a logical name. For example, 0200. SETUP and 0210. FIN. Leave enough space in the numbers to add additional lines if required. This will avoid renaming which is an expensive task for the database engine and users will have to wait until it is completed.. Our consultants will help the customer to install the system, help with the setup and convert the data from the old system. When this is done we will help them with testing and train them for using Microsoft Dynamics NAV. The consultants will be set up in the system as Resources, which are in turn entered into the job planning lines. When everything is working as expected we can schedule a go-live weekend and help them in the first period using the system. Invoicing a job like this is done using a budget. We will make a pre calculation of the number of hours we think are necessary and start with that. During the job we need to measure the used budget and compare it with the progress. Budgeting The budget is created using the Job Planning Lines. During this phase of the job we do not yet know which resource will be used for the job tasks and it might even be done by more than one resource. This is why we want to use Resource Groups in our budget. This is not possible in the standard application so we have created a modification which we will discuss at the end of this article. The Line Type of these job planning lines is Schedule. This means that these lines are just for budgeting and schedule purposes. The system will invoice the actual consumption posted in the Job Journal. 2 | The infrastructure To use Microsoft Dynamics NAV 2009 Packt Publishing needs new infrastructure.Their current systems do not meet the requirements for Microsoft Dynamics NAV 2009. For this job we could create new Job Task Lines in the implementation job, but for a clearer overview we will create a new job, EXAMPLE2. Our company builds and sells its own computer systems. We can build both servers and desktop systems. Because none of the systems are exactly the same and available components switch regularly we do not want to create an item and a bill of materials for each system. Instead we use a Calculation system that allows us to determine a price for a system. For other products like switches, routers, printers, and laptops we use items which we purchase from vendors. The Job Tasks and Job Planning Lines for this job look like this: The installation costs in this job are Resource Groups with line type Schedule,just as in the previous job, so we invoice actual hours spent on the job. The other lines are of type Both Schedule and Contract. This means we will invoice exactly what is in the budget. The job journal lines for these tasks should be posted with a blank line type. 3 | The upgrade Our customer requests an upgrade from Navision version 3.70 to Microsoft Dynamics NAV 2009. We can do this for a fixed price but we require a fee for analyzing the system. For this job, EXAMPLE3, we can start with a limited number of Job Task Lines, just for the quote. When the customer agrees to do the upgrade we can add new job task lines. Both the Quote and the Upgrade are fixed price and posted directly to the general ledger. This does not mean we cannot have our resources to register the actual hours using the job journal but the line type should be blank. Another part of the upgrade is not done fixed price. The systems needs some redesign, a conversion to SQL Server 2008, and the customer wants additional training and support. The fixed price part of the upgrade is invoiced in three phases. When the job starts we invoice 50%, when we deliver the test system we invoice 40% and 10% is invoiced three months after go-live. This is done using lines of Both Schedule and Contract line type. 4 | The support team For the support team, our policy is to create one job per fiscal year per Customer.We will use this job, EXAMPLE4, for invoicing the maintenance of the license and all support issues. The support issues can be both little questions customers call us for, such as changing a report or a page, or implementing new features that requires only a few days work. Each issue and new feature will be created as a job task line. The new features will be created by the account manager who sells the feature. We can then decide if the invoicing is done fixed price, using contract lines, or on time and materials using schedule lines. Our support team also needs to use the job system, but we do not want them to manually create a new job task line for each support call, and we also want them to view all outstanding issues for all customers easily. For this we have created a new issue registration system which we discuss at the end of this article. Each issue in the system is linked to a job task. When Support Engineers create a new issue, the job task line is automatically generated for them and they can use it in our time and billing system.   Time sheets For all the jobs in our examples it is critical to have a solid registration of resource hours. In the standard Microsoft Dynamics NAV job application resources need to post a job journal for each combination of Job, Job Task, and Posting Date. This is not the way most people want to register their hours; therefore we have created a Time Sheet application. Data and transaction model The Time Sheet application is layered above the job journal line and is created using resources and job tasks. There is an approval process for the person responsible for the job allowing them to make corrections. The time sheet is designed to be created for each week. The system automatically generates the week starting date and creates the description. After that the resource can create time sheet lines for each job task line, and populate the number of hours each day of the week. If we look at this time sheet we can see, after it is updated, that Wednesday is missing two hours.
Read more
  • 0
  • 0
  • 3499

article-image-integrating-application-relationship-management-and-sales-microsoft-dynamics-nav-2009
Packt
11 Jun 2010
5 min read
Save for later

Integrating the application with Relationship Management and Sales in Microsoft Dynamics NAV 2009

Packt
11 Jun 2010
5 min read
(Further on Microsoft Dynamics NAV:here.) Invoicing The last issue on our to-do list is the invoicing process. For this we use a part of the standard application. invoicing is done using a document structure with a header and a line table. This has a posting routine that will start the journal transactions. For our application we need to create the invoice document and make sure that when posted, it updates our sub administration. Invoice document The sales invoice documents in Microsoft Dynamics NAV are stored in the sales header (36) and sales line (37) tables. We will create a report that will combine the outstanding reservation entries into invoices allowing the user to filter on a specific entry or any other field value in the squash ledger entry table. Reports in Microsoft Dynamics NAV are not just for printing documents, we can also use its dataset capabilities to start batch jobs. To enable this, our batch job needs to have a special property, ProcessingOnly (as shown in the following screenshot), so let's start a blank report and do this. The report will browse through the squash ledger entries filtered on entry type reservation and open (yes). The sorting is Open, Entry Type, Bill-to Customer No. and Reservation Date (as shown in the following screenshot): Because bill-to customer no. is the first non filtered value in the sorting we can assume that if this value changes we need a new sales header. For every Squash Ledger Entry we will generate a sales line. Squash Ledger Entry - OnAfterGetRecord()IF "Bill-to Customer No." <> SalesHdr."Bill-to Customer No."THEN CreateSalesHdr;CreateLn; Sales header The code to create a sales header looks like this: CreateSalesHdr()CLEAR(SalesHdr);SalesHdr.SetHideValidationDialog(TRUE);SalesHdr."Document Type" := SalesHdr."Document Type"::Invoice;SalesHdr."Document Date" := WORKDATE;SalesHdr."Posting Date" := WORKDATE;SalesHdr.VALIDATE("Sell-to Customer No.", "Squash Ledger Entry"."Bill-to Customer No.");SalesHdr.INSERT(TRUE);NextLineNo := 10000;CounterOK := CounterOK + 1; The function SetHideValidationDialog makes sure that we don't get pop-up messages while validating values. This is a standard function in Microsoft Dynamics NAV which is designed for this purpose. Sales line To create a sales line we need a minimum of this code. Please note that we added the field Applies-to Squash Entry No. to the sales line table. CreateLn()WITH "Squash Ledger Entry" DO BEGIN GenPstSetup.GET("Gen. Bus. Posting Group", "Gen. Prod. Posting Group"); GenPstSetup.TESTFIELD("Sales Account"); SalesLn.INIT; SalesLn."Document Type" := SalesHdr."Document Type"; SalesLn."Document No." := SalesHdr."No."; SalesLn."Line No." := NextLineNo; SalesLn."System-Created Entry" := TRUE; SalesLn.Type := SalesLn.Type::"G/L Account"; SalesLn.VALIDATE("No.", GenPstSetup."Sales Account"); SalesLn.Description := Description; SalesLn.VALIDATE(Quantity, Quantity); SalesLn.VALIDATE("Unit Price", "Unit Price"); SalesLn.VALIDATE("Unit Cost (LCY)", "Unit Cost"); SalesLn."Applies-to Squash Entry No." := "Entry No."; SalesLn.INSERT(TRUE);END;NextLineNo := NextLineNo + 10000; When you add fields to the sales and purchase document tables, make sure to also add these to the posted equivalents of these tables with the same number. This way you make sure that the information is copied to the historic data. This is done using the TRANSFERFIELDS command. Dialog If the combined invoicing takes some time it might be good to show the user a process bar. For this Microsoft Dynamics NAV has a standard structure. The window shows the bill-to customer no. it is currently processing and a bar going from 1 percent to 100 percent. This is calculated by keeping a counter. At the end of the process we show a message telling the user how many invoices were created out of the number of squash ledger entries. Squash Ledger Entry - OnPreDataItem()CounterTotal := COUNT;Window.OPEN(Text000);Squash Ledger Entry - OnAfterGetRecord()Counter := Counter + 1;Window.UPDATE(1,"Bill-to Customer No.");Window.UPDATE(2,ROUND(Counter / CounterTotal * 10000,1));...Squash Ledger Entry - OnPostDataItem()Window.CLOSE;MESSAGE(Text001,CounterOK,CounterTotal); To do this we need some variables. The Window variable is of type Dialog whilst Counter, CounterTotal and CounterOK are integers (as shown in the following screenshot): The constant Text000 has a special values #1########## and @2@@@@@@@@@@@@@ (as shown in the following screenshot). The first allows us to show and update the text; the latter is to create the process bar: The result is this: We see the following window when invoice creation process completes: bars in combination with the impact on performance at http://www.mibuso.com/howtoinfo.asp?FileID=17 Posting process Now, our sales invoice is ready so we can start making the necessary changes to the posting process. Posting a sales document is done using a single posting codeunit and some helper objects: Report 297: This report can be used to post more than one document at the same time with a filter. Codeunit 80: This is the actual posting routine we are going to change. Codeunit 81: This codeunit is called from the user interface and has a dialog whether the user wants to ship, invoice or both if the document is an order, and a yes/no if the document is an invoice or credit memo. Codeunit 82: When the user chooses post and print this codeunit is executed which does the same as codeunit 81 plus printing a report. So we will make a change to codeunit 80. This codeunit has a specific structure that we need to understand before we go in and make the change.
Read more
  • 0
  • 0
  • 1816

article-image-integrating-images-jsf-css-jsf-and-js-jsf
Packt
11 Jun 2010
7 min read
Save for later

Integrating Images with JSF, CSS with JSF and, JS with JSF

Packt
11 Jun 2010
7 min read
(For more resources on JSF, see here.) Injecting CSS in JSF In this recipe, you will see how to add CSS styles to JSF tags. It is a simple solution, but it has the advantage that it can be applied to almost all JSF tags that render text, images, and so on. Getting ready We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library. How to do it... When you need a simple and classic solution to integrate CSS in JSF it is important to know that JSF components support the styleClass and style attributes. The styleClass attribute is used when you are working with CSS classes, while the style attribute allows you to place CSS code directly in place between quotes. You can see in the following code snippet how this works with the h:outputText component: <?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <h:head> <title>JSF and CSS example</title> <style type="text/css"> .message { text-align: left; letter-spacing:5px; color:#000099 } .message-overline { text-decoration:overline; } .message-font { font-family:georgia,garamond,serif; font-size:20px; font-style:italic; } </style> </h:head> <h:body> <h:outputText styleClass="message" value="This text is CSS formated by 'message' class!"/> <br /><br /> <h:outputText styleClass="message message-overline" value="This text is CSS formated by 'message' and 'message-overline' classes!"/> <br /><br /> <h:outputText styleClass="message message-overline message-font" value="This text is CSS formated by 'message', 'message-overline' and 'message-font' classes!"/> <br /><br /> <h:outputText style="text-align: left;letter-spacing:5px; color:#000099" value="This text is CSS formated using the 'style' attribute instead of 'message' class!"/> <br /><br /> <h:outputText style="text-align: left;letter-spacing:5px; color:#000099;text-decoration:overline;" value="This text is CSS formated using the 'style' attribute instead of 'message' and 'message-overline' classes!"/> <br /><br /> <h:outputText style="text-align: left;letter-spacing:5px; color:#000099;text-decoration:overline; font-family:georgia,garamond,serif; font-size:20px;font-style:italic; " value="This text is CSS formated using the 'style' attribute instead of 'message', 'message-overline' and 'message-font' classes!"/> <br /><br /> </h:body></html> Notice that when you need to specify more CSS classes under the same styleClass you need to separate their names by space. How it works... As you can see the JSF – CSS construction looks similar to HTML – CSS usage. The interaction between JSF – CSS imitates HTML – CSS interaction, but, as you will see in the next recipes, JSF is more flexible and supports more kinds of attributes for injecting CSS code in JSF pages. JSF, CSS, and tables There are two kinds of grids (tables) that are very often used in JSF, h:panelGrid and h:dataTable. Both of them can be styled with CSS in detail using a set of dedicated attributes. In this recipe you will see these attributes at work for h:panelGrid, but it is very simple to extrapolate this to h:dataTable. Getting ready We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library. How to do it... Suppose that we have an h:panelGrid. We can "populate" it with CSS styles, using the following set of attributes: Name Description columnClasses This is used to specify the comma-separated list of CSS style classes to be applied on the columns of the table. headerClass This is used to specify the spaces-separated list of CSS style classes to be applied on the header of the table. footerClass This is used to specify the spaces-separated list of CSS style classes to be applied on the footer of the table. rowClasses This is used to specify the comma-separated list of CSS style classes to be applied on the rows of the table. styleClass This is used to set the CSS class for the component. style This is used to set the CSS style definition for the component. Knowing these attributes, we build a JSF page to show you how to use them in practice (notice where we have placed the attributes): <?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <h:head> <title>JSF and CSS example</title> <style type="text/css"> .message { text-align: left; letter-spacing:5px; color:#000099 } .message-font { font-family:georgia,garamond,serif; font-size:20px; font-style:italic; } .odd { background-color: blue } .even { background-color: red } </style> </h:head> <h:body> <h:form> <h:panelGrid columns="3" border="1" footerClass="message" headerClass="message-font" rowClasses="odd, even" title="PanelGrid and CSS"> <f:facet name="header"> <h:outputText value="Fill Names Below"/> </f:facet> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <h:inputText/> <f:facet name="footer"> <h:outputText value="The End"/> </f:facet> </h:panelGrid> </h:form> </h:body></html> How it works... Since we have an attribute for each part of a grid, we can easily specify CSS styles to customize the design of each of these parts. JSF will combine the specified CSS styles to render a cool grid to the user. There's more... The h:dataTable allows you to use the same CSS attributes for table header, footer, and so on. Integrating JavaScript and JSF JSF and JavaScript can combine their forces to develop powerful applications. For example, let's see how we can use JavaScript code with h:commandLink and h:commandButton to obtain a confirmation before getting into action. Getting ready We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library. How to do it... As you know the h:commandLink takes an action after a link is clicked (on the mouse click event), while h:commandButton does the same thing, but renders a button, instead of a text link. In this case, we place a JavaScript confirmation box before the action starts its effect. This is useful in user tasks that can't be reversed, such as deleting accounts, database records, and so on. Therefore, the onclick event was implemented as shown next: <?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <h:head> <title>JSF and JavaScript example</title> </h:head> <h:body> <!-- using h:commandLink and JavaScript --> <h:form id="myCLForm"> <h:commandLink id="cmdlinkID" value="Delete record" onclick="if (!confirm('Are you sure you want to delete the current record?')) return false" action="#{bean.deleteRecord}"/> </h:form> <!-- using h:commandButton and JavaScript --> <h:form id="myCBForm"> <h:commandButton id="cmdbtnID" value="Delete record" onclick="if (!confirm('Are you sure you want to delete the current record?')) return false" action="#{bean.deleteRecord}"/> </h:form> </h:body></html> How it works... Notice that we embed the JavaScript code inside the onclick event (you also may put it separately in a JS function, per example). When the user clicks the link or the button, a JS confirmation box appear with two buttons. If you confirm the choice the JSF action takes place, while if you deny it then nothing happens. There's more... You can use this recipe to display another JS box, such as prompt box or alert box.
Read more
  • 0
  • 0
  • 15172
article-image-improving-plone-3-product-performance
Packt
11 Jun 2010
7 min read
Save for later

Improving Plone 3 Product Performance

Packt
11 Jun 2010
7 min read
(For more resources on Plone, see here.) Introduction CMS Plone provides: A Means of adding, editing, and managing content A database to store content A mechanism to serve content in HTML or other formats Fortunately, it also supplies the tools to do all these things in an incredibly easy and powerful way. For example, content producers can create a new article without worrying how it will look or what other information will be surrounding the main information. To do this Plone must compose a single HTML output file (if we are talking from a web browser viewpoint) by joining and rendering several sources of data according to the place, importance, and target they are meant for. As it is built upon the Zope application server, all these jobs are easy for Plone. However, they have a tremendous impact as far as work and performance goes. If enough care is not taken, then a whole website could be stuck due to a couple of user requests. In this article, we'll look at the various performance improvements and how to measure these enhancements. We are not going to make a comprehensive review of all the options to tweak or set up a Zope-based web application, like configuring a like configuring a proxy cache or a load balancer. There are lots of places, maybe too many, where you can find information about these topics. We invite you to read these articles and tutorials and subscribe or visit Zope and Plone mailing lists: http://projects.zestsoftware.nl/guidelines/guidelines/caching/ caching1_background.html http://plone.org/documentation/tutorial/buildout/a-deployment-configuration/ http://plone.org/documentation/tutorial/optimizing-plone Installing CacheFu with a policy product When a user requests HTML pages from a website, many things can be expressed about the downloading files by setting special headers in the HTTP response. If managed cautiously, the server can save lots of time and, consequently, work by telling the browser how to store and reuse many of the resources it has got. CacheFu is the Plone add-on product that streamlines HTTP header handling in order to obtain the required performance. We could add a couple of lines to the buildout.cfg file to download and install CacheFu. Then we could add some code in our end user content type products (pox.video and Products.poxContentTypes) to configure CacheFu properly to deliver them in an efficient way. However, if we do so, we would be forcing these products to automatically install CacheFu, even if we were testing them in a development environment. To prevent this, we are going to create a policy product and add some code to install and configure CacheFu. A policy product is a regular package that will take care of general customizations to meet customer requirements. For information on how to create a policy product see Creating a policy product. Getting ready To achieve this we'll use pox.policy, the policy product created in Creating a policy product. How to do it... Automatically fetch dependencies of the policy product: Open setup.py in the root pox.policy folder and modify the install_requires variable of the setup call: setup(name='pox.policy', ... install_requires=['setuptools', # -*- Extra requirements: -*- 'Products.CacheSetup', ], Install dependencies during policy product installation. In the profiles/default folder, modify the metadata.xml file: <?xml version="1.0"?><metadata> <version>1</version> <dependencies> <dependency>profile-Products.CacheSetup:default</dependency> </dependencies></metadata You could also add here all the other products you plan to install as dependencies, instead of adding them individually in the buildout.cfg file. Configure products during the policy product installation. Our policy product already has a <genericsetup:importStep /> directive in its main component configuration file (configure.zcml). This import step tells GenericSetup to process a method in the setuphandlers module (we could have several steps, each of them with a matching method). Then modify the setupVarious method to do what we want, that is, to apply some settings to CacheFu. from zope.app.component.hooks import getSitefrom Products.CMFCore.utils import getToolByNamefrom config import * def setupVarious(context): if context.readDataFile('pox.policy_various.txt') is None: return portal = getSite() # perform custom operations # Get portal_cache_settings (from CacheFu) and # update plone-content-types rule pcs = getToolByName(portal, 'portal_cache_settings') rules = pcs.getRules() rule = getattr(rules, 'plone-content-types') rule.setContentTypes(list(rule.getContentTypes()) + CACHED_CONTENT) The above code has been shortened for clarity's sake. Check the accompanying code bundle for the full version. Add or update a config.py file in your package with all configuration options: # Content types that should be cached in plone-content-types# rule of CacheFuCACHED_CONTENT = ['XNewsItem', 'Video',] Build your instance up again and launch it: ./bin/buildout./bin/instance fg After installing the pox.policy product (it's automatically installed during buildout as explained in Creating a policy product) we should see our content types—Video and XNewsItem—listed within the cached content types. The next screenshot corresponds to the following URL: http://localhost:8080/plone/portal_cache_settings/with-caching-proxy/rules/plone-content-types. The with-caching-proxy part of the URL matches the Cache Policy field; and the plone-content-types part matches the Short Name field. As we added Python code, we must test it. Create this doctest in the README.txt file in the pox.policy package folder: Check that our content types are properly configured >>> pcs = getToolByName(self.portal, 'portal_cache_settings')>>> rules = pcs.getRules()>>> rule = getattr(rules, 'plone-content-types')>>> 'Video' in rule.getContentTypes()True>>> 'XNewsItem' in rule.getContentTypes()True Modify the tests module by replacing the ptc.setupPloneSite() line with these ones: # We first tell Zope there's a CacheSetup product availableztc.installProduct('CacheSetup') # And then we install pox.policy product in Plone.# This should take care of installing CacheSetup in Plone alsoptc.setupPloneSite(products=['pox.policy']) And then uncomment the ZopeDocFileSuite: # Integration tests that use PloneTestCaseztc.ZopeDocFileSuite( 'README.txt', package='pox.policy', test_class=TestCase), Run this test suite with the following command: ./bin/instance test -s pox.policy How it works... In the preceding steps, we have created a specific procedure to install and configure other products (CacheFu in our case). This will help us in the final production environment startup as well as on installation of other development environments we could need (when a new member joins the development team, for instance). In Step 1 of the How to do it... section, we modified setup.py to download and install a dependency package during the installation process, which is done on instance buildout. Getting dependencies in this way is possible when products are delivered in egg format thanks to Python eggs repositories and distribution services. If you need to get an old-style product, you'll have to add it to the [productdistros] part in buildout.cfg. Products.CacheSetup is the package name for CacheFu and contains these dependencies: CMFSquidTool, PageCacheManager, and PolicyHTTPCacheManager. There's more... For more information about CacheFu visit the project home page at http://plone.org/products/cachefu. You can also check for its latest version and release notes at Python Package Index (PyPI, a.k.a. The Cheese Shop): http://pypi.python.org/pypi/Products.CacheSetup. The first link that we recommended in the Introduction is a great help in understanding how CacheFu works: http://projects.zestsoftware.nl/guidelines/guidelines/caching/caching1_background.html. See also Creating a policy product Installing and configuring an egg repository
Read more
  • 0
  • 0
  • 5043

article-image-find-and-install-add-ons-expand-plone-functionality
Packt
10 Jun 2010
11 min read
Save for later

Find and Install Add-Ons that Expand Plone Functionality

Packt
10 Jun 2010
11 min read
(For more resources on Plone, see here.) Background It seems like every application platform uses a different name for its add-ons: modules, components, libraries, packages, extensions, plug-ins, and more. Add-on packages for the Zope web application server are generally called Products. A Zope product is a bundle of Zope or Plone functionality contained in a Python module or modules. Like Plone, add-on products are distributed in source code, so that you may always read and examine them. Plone itself is actually a set of tightly connected Zope products and Python modules. Plone add-on products may be divided into three major categories: Skins or themes that change Plone’s look and feel or add visual elements like portlets. These are typically the simplest of Plone products. Products that add new content types with specialized functionality. Some are simple extensions of built-in types, others have custom workflows and behaviours. Products that add to or change the behaviour of Plone itself. Where to Find Products Plone.org’s Products section at http://plone.org/products is the place to look for Plone products. At the time of this writing, the Plone.org contains listings for 765 products and 1,901 product releases. The Plone Products section is itself built with a Plone product, the Plone Software Center – often called the PSC – that adds content types for projects, software releases, project roadmaps, issue trackers, and project documentation. Using the Plone Product Pages Visiting the Plone product pages for the first time may be a bewildering experience due to the number of available products. However, by specifying a product category and target Plone version, you will quickly narrow the product selection to the point where it’s worth reading descriptions and following the links to product pages. Product pages typically contain product descriptions, software releases, and a list of available documentation, issue tracker, version control repository, and contact resources. Each release will have release notes, a change log, and a list of Plone versions with which the release has been tested. If the release has a product package available, it will be available here for download. Some releases do not have associated software packages. This may be because the release is still in a planning stage, and the listing is mainly meant to document the product’s development roadmap; or because the development is still in an early stage, and the software is only available from a version-control repository. The release notes commonly include a list of dependencies, and you should make special note of that along with compatible Plone versions. Many products require the installation of other, supporting products. Some require that your server or test workstation have particular system libraries or utilities. Product pages may also have links to a variety of additional resources: product-specific documentation, other release pages, an issue tracker, a roadmap for future development, contact form for the project, and a version-control repository. Playing it Safe with Add-On Products Plone 3 is probably one of the most rigorously tested open-source software packages in existence. While no software is defect free, Plone’s core development team is on the leading edge of software development methodologies and work under a strong testing culture that requires that they prove their components work correctly before they ever become part of Plone. Plone’s library of add-on products is a very different story. Add-on products are contributed by a diverse community of developers. Some add-on products follow the same development and maintenance methodologies as Plone itself; others are haphazard experiments. To complicate matters, today’s haphazard experiment may be – if it succeeds – next year’s rigorously developed and reliable product. (Much of the Plone core codebase began as add-on products.) And, this year’s reliable standby may lose the devotion of its developers and not be upgraded to work with the next version of Plone. If you’re new to the world of open source software, this may seem dismaying. Don’t be discouraged. It is not hard to evaluate the status of a product, and the Plone community is happy to help. Be encouraged by evidence of continual, exciting innovation. Most importantly, stop thinking of yourself as a consumer. Take an interest in the community process that produces good products. Test some early releases and file bug reports and feature requests. Participate in, or help document, test, and fund the development of the products that are most important to you. Product Choice Strategy Trying out new Plone add-on products is great fun, but incorporating them into production websites requires planning and judgement if you’re going to have good long-run results. New versions of Plone pose a particular challenge. Major new releases of Plone don’t just add features: with every major version of Plone the application programming interface (API) and presentation templates change. This is not done arbitrarily, and there is usually a good deal of warning before a major change, but it means that add-on products often need to be updated before they will work with a major new version of Plone. Probably worthwhile to point out that major versions are released very ~18 months, and that minor version upgrades generally do not pose compatibility problems for the vast majority of add-on products. This means that when a new version of Plone appears on the scene, you won’t be able to migrate your Plone site to use it until compatible product versions are available for all the add-on products in use on the site. If you’re using mainstream, well-supported products, this may happen very quickly. Many products are upgraded to work with new Plone versions during the beta and release-candidate stages of Plone development. Some products take longer, and some may not make the jump at all. The products least likely to be updated are often ones made obsolete by new functionality. This creates a somewhat ironic situation when a new version of Plone arrives: the quickest adopters are often those with the least history with the platform. The slowest adopters are sometimes the sites that are most heavily invested in the new features. Consider, as a prime example, Plone.org, a very active, very large, community site which must be conservatively managed and stick with proven versions of add-on products. Plone.org often does not migrate to a new Plone version until many months after release. Is this a problem? Not really – unless you need both the newest features of the newest Plone version and the functionality of a more slowly developed add-on product. If that’s the case, prepare to make an investment of time or money in supporting product development and possibly writing some custom migration scripts. If you want to be more conservative, try the following strategy: Enjoy testing many products and keeping up with new developments by trying them out on a test server. Learn the built-in Plone functionality well, and use it in preference to add-on products whenever possible. Make sure you have a good understanding of the maturity level and degree of developer support for add-on products. Incorporate the smallest number of add-on products reasonably possible into your production sites. Don’t be just a consumer: when you commit to a product, help support it by filing bug reports and feature requests, contributing translations, documentation or code, and answering questions about it on the Plone mailing lists or #plone IRC channel. Evaluating a Product Judging the maturity of a Plone product is generally easy. Start with a product’s project page on Plone.org. The product page may offer you a "Current release" and one or more "Experimental releases". Anything marked as a current release should be stable on its tested Plone versions. If you need a release to work with an earlier version of Plone than the ones supported by the current release, follow the "List all releases..." link. Releases in the "Experimental" list will be marked as "alpha", "beta", or "Release Candidate." These terms are well-defined in practice: Alpha releases are truly experimental, and are usually posted in order to get early feedback. Interfaces and implementations are likely still in flux. Download an alpha release only for testing in an experimental environment, and only for purposes of previewing new features and giving feedback to developers. Do not plan on keeping any content you develop using an alpha release, as there may be no upgrade path to later releases. With a beta release, feature sets and programming interfaces should be stable or changing only incrementally. It’s reasonable to start testing the integration of the product with the platform and with other products. There will typically be an upgrade path to future releases. Bug reports will be welcome and will help develop the product. Release candidates have a fixed feature set and no known major issues. Templates and messages should be complete, so that translators may work on language files with some confidence that their work won’t be lost. If you encounter a bug in release-candidate products, please immediately file an issue report. Products may be re-released repeatedly at any release state. For alpha, beta and RC releases, each additional release changes the release count, but not the version number. So, "PloneFormGen 1.2" (Beta release 6) is the sixth beta release of version 1.2 of PloneFormGen. Once a product release reaches current release status, new releases for maintenance will increment the version number by 0.0.1. "PloneFormGen 1.1.3" is thus the third maintenance release of version 1.1 of that product. Don’t make too much of version numbers or release counts. Release status is a better indicator of maturity. If your site is mission-critical, don’t use beta releases on it. However, if you test carefully before deploying, you may find that some products are ready for live use when late in their beta development on sites where an error or glitch wouldn’t be intolerable. Testing a Product Conscientious Plone site administrators maintain an off-line mirror of their production sites on a secondary server – or even a desktop computer – that they may use for testing purposes. Always test a new product on a test server. Before deploying, test it on a server that has precisely the combination of products in use on your production server. Ideally, test with a copy of the database of your live server. Check the functionality of not only the new product, but also the products you’re already using. The latter is particularly important if you’re using products that alter the base functionality of Plone or Zope. Looking to the Future Evaluating product maturity and testing the product will help you judge its current status, but what about the future? What are the signs of a product that’s likely to be well-maintained and available for future versions of Plone? There are no guarantees, but here are some signs that experienced Plone integrators look for: Developing in public. This is open-source software. Look to see if the product is being developed with a public roadmap for the future, and with a public version-control repository. Plone.org provides product authors with great tools for indicating release plans, and makes a Subversion (SVN) version-control repository available to all product authors. Look to see if they’re using these facilities. Issue tracker status. Every released product should have a public issue (bug) tracker. Look for it. Look to see if it’s being maintained, and if issues are actively responded to. No issue tracker, or lots of old, uncategorized issues are bad signs. Support for multiple Plone versions. If a product has been around a while look to see if versions are available for at least a couple of Plone releases. This might be the previous and current releases, or the current and next releases. Internationalization. Excellent products attract translations. Good development methodologies. This is the hardest criterion for a non-developer to judge, but a forthcoming version of the Plone Software Center will ask developers to rate themselves on compliance with a set of community standards. My guess is that product developers will be pretty honest about these ratings. Several of these criteria have something in common: they allow the Plone community to participate in product maintenance and development. The best projects belong to the community, and not any single author. One of the best ways to get a quick read on the quality of an add-on product is to hop on the #plone IRC channel and ask. Chances are you’ll run into someone who can share their experiences and offer insight. You may even run into the product author him/herself!
Read more
  • 0
  • 0
  • 3367
Modal Close icon
Modal Close icon