Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
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

7019 Articles
article-image-working-report-builder-microsoft-sql-server-2008-part-2
Packt
22 Oct 2009
3 min read
Save for later

Working with the Report Builder in Microsoft SQL Server 2008: Part 2

Packt
22 Oct 2009
3 min read
Enabling and reviewing My Reports As described in Part 1 the My Reports folder needs to be enabled in order to use the folder or display it in the Open Report dialogue. The RC0 version had a documentation bug which has been rectified (https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=366413) Getting ready In order to enable the My Reports folder you need to carry out a few tasks. This will require authentication and working with the SQL Server Management Studio. These tasks are listed here: Make sure the Report Server has started. Make sure you have adequate permissions to access the Servers. Open the Microsoft SQL Server Management Studio as described previously. Connect to the Reporting Services after making sure you have started the Reporting Services. Right-click the Report Server node. General Execution History Logging Security Advanced The Server Properties window is displayed with a navigation list on the left consisting of the following: In the General page the name, version, edition, authentication mode, and URL of Reporting Service is displayed. Download of an ActiveX Client Print control is enabled by default. In order to work with Report Builder effectively and provide a My Reports folder for each user, you need to place a check mark for the check box Enable a My Reports folder for each user. The My Reports feature has been turned on as shown in the next screenshot. In the Execution page there is choice for report timeout execution, with the default set such that the report execution expires after 1800 seconds. In the History page there is choice between keeping an unlimited number of snapshots in the report history (default) or to limit the copies allowing you to specify how many to be kept. In the Logging page, report execution logging is enabled and the log entries older than 60 days are removed by default. This can be changed if desired. In the Security page, both Windows integrated security for report data sources and ad hoc report executions are enabled by default. The Advanced page shows several more items including the ones described thus far as shown in the next figure. In the General page enable the My Reports feature by placing a check mark. Click on the Advanced list item in the left. The Advanced page is displayed as shown: Now expand the Security node of Reporting Services and you will see that the My Reports role is present in the list of roles as shown. This is also added to the ReportServer database. The description of everything that a user with the assignment My Reports role can do is as follows: May publish reports and linked reports, manage folders, reports, and resources in a users My Reports folder. Now bring up Report Builder 2.0 by clicking Start | All Programs | Microsoft SQL Server 2008 Report Builder | Report Builder 2.0. Report Builder 2.0 is displayed. Click on Office Button | Open. The Open Report dialogue appears as shown. When the report Server is offline, the default location is My Documents, like Microsoft products Excel and MS Access. Choose the Recent sites and Servers. The Report server that is active should get displayed here as shown: Highlight the Server URL and click Open. All the folders and files on the server become accessible as shown: Open the Report Manager by providing its URL address. Verify that a My Reports folder is created for the user (current user). There could be slight differences in the look of the interface depending on whether you are using the RTM or the final version of SQL Server 2008 Enterprise edition.
Read more
  • 0
  • 0
  • 2596

article-image-customer-management-joomla-and-virtuemart
Packt
22 Oct 2009
7 min read
Save for later

Customer Management in Joomla! and VirtueMart

Packt
22 Oct 2009
7 min read
Note that all VirtueMart customers must be registered with Joomla!. However, not all Joomla! users need to be the VirtueMart customers. Within the first few sections of this article, you will have a clear concept about user management in Joomla! and VirtueMart. Customer management Customer management in VirtueMart includes registering customers to the VirtueMart shop, assigning them to user groups for appropriate permission levels, managing fields in the registration form, viewing and editing customer information, and managing the user groups. Let's dive in to these activities in the following sections. Registration/Authentication of customers Joomla! has a very strong user registration and authentication system. One core component in Joomla! is com_users, which manages user registration and authentication in Joomla!. However, VirtueMart needs some extra information for customers. VirtueMart collects this information through its own customer registration process, and stores the information in separate tables in the database. The extra information required by VirtueMart is stored in a table named jos_vm_user_info, which is related to the jos_users table by the user id field. Usually, when a user registers to the Joomla! site, they also register with VirtueMart. This depends on some global settings. In the following sections, we are going to learn how to enable the user registration and authentication for VirtueMart. Revisiting registration settings We configure the registration settings from VirtueMart's administration panel Admin | Configuration | Global screen. There is a section titled User Registration Settings, which defines how the user registration will be handled: Ensure that your VirtueMart shop has been configured as shown in the screenshot above. The first field to configure is the User Registration Type. Selecting Normal Account Creation in this field creates both a Joomla! and VirtueMart account during user registration. For our example shop, we will be using this setting. Joomla!'s new user activation should be disabled when we are using VirtueMart. That means the Joomla! New account activation necessary? field should read No. Enabling VirtueMart login module There is a default module in Joomla! which is used for user registrations and login. When we are using this default Login Form (mod_login module), it does not collect information required by VirtueMart, and does not create customers in VirtueMart. By default, when published, the mod_login module looks like the following screenshot: As you see, registered users can log in to Joomla! through this form, recover their forgotten password by clicking on the Forgot your password? link, and create a new user account by clicking on the Create an account link. When a user clicks on the Create an account link, they get the form as shown in the following screenshot: We see that normal registration in Joomla! only requires four pieces of information: Name, Username, Email, and Password. It does not collect information needed in VirtueMart, such as billing and shipping address, to be a customer. Therefore, we need to disable the mod_login module and enable the mod_virtuemart_login module. We have already learned how to enable and disable a module in Joomla!. We have also learned how to install modules. By default, the mod_virtuemart_login module's title is VirtueMart Login. You may prefer to show this title as Login only. In that case, click on the VirtueMart Login link in the Module Name column. This brings the Module:[Edit] screen: In the Title field, type Login (or any other text you want to show as the title of this module). Make sure the module is enabled and position is set to left or right. Click  on the Save icon to save your settings. Now, browse to your site's front-page  (for example, http://localhost/bdosn/), and you will see the login form as shown in the following screenshot: As you can see, this module has the same functionalities as we saw in the mod_login module of Joomla!. Let us test the account creation in this module. Click on the Register link. It brings the following screen: The registration form has three main sections: Customer Information, Bill To Information, and Send Registration. At the end, there is the Send Registration button for submitting the form data. In the Customer Information section, type your email address, the desired username, and password. Confirm the password by typing it again in the Confirm password field. In the Bill To Information section, type the address details where bills are to be sent. In the entire form, required fields are marked with an asterisk (*). You must provide information for these required fields. In the Send Registration section, you need to agree to the Terms of Service. Click on the Terms of Service link to read it. Then, check the I agree to the Terms of Service checkbox and click on the Send Registration button to submit the form data: If you have provided all of the required information and submitted a unique  email address, the registration will be successful. On successful completion of registration, you get the following screen notification, and will be logged in to  the shop automatically: If you scroll down to the Login module, you will see that you are logged in and greeted by the store. You also see the User Menu in this screen: Both the User Menu and the Login modules contain a Logout button. Click on either of these buttons to log out from the Joomla! site. In fact, links in the User Menu module are for Joomla! only. Let us try the link Your Details. Click on the Your Details link, and you will see the information shown in the following screenshot: As you see in the screenshot above, you can change your full name, email, password, frontend language, and time zone. You cannot view any information regarding billing address, or other information of the customer. In fact, this information is for regular Joomla! users. We can only get full customer information by clicking on the Account Maintenance link in the Login module. Let us try it. Click on the Account Maintenance link, and it shows the following screenshot: The Account Maintenance screen has three sections: Account Information, Shipping Information, and Order Information. Click on the Account Information link to see what happens. It shows the following screen: This shows Customer Information and Bill To Information, which have been entered during user registration. The last section on this screen is the Bank Information, from where the customer can add bank account information. This section looks like the following screenshot: As you can see, from the Bank Account Info section, the customers can enter their bank account information including the account holder's name, account number, bank's sorting code number, bank's name, account type, and IBAN (International Bank Account Number). Entering this information is important when you are using  a Bank Account Debit payment method. Now, let us go back to the Account Maintenance screen and see the other sections. Click on the Shipping Information link, and you get the following screen: There is one default shipping address, which is the same as the billing address. The customers can create additional shipping addresses. For creating a new shipping address, click on the Add Address link. It shows the following screen:
Read more
  • 0
  • 0
  • 11449

article-image-adding-newsletters-web-site-using-drupal-6
Packt
22 Oct 2009
4 min read
Save for later

Adding Newsletters to a Web Site Using Drupal 6

Packt
22 Oct 2009
4 min read
Creating newsletters A newsletter is a great way of keeping customers up-to-date without them needing to visit your web site. Customers appreciate well-designed newsletters because they allow the customer to keep tabs on their favorite places without needing to check every web site on a regular basis. Creating a newsletter Good Eatin' Goal: Create a new newsletter on the Good Eatin' site, which will contain relevant news about the restaurant, and will be delivered quarterly to subscribers. Additional modules needed: Simplenews (http://drupal.org/project/simplenews). Basic steps Newsletters are containers for individual issues. For example, you could have a newsletter called Seasonal Dining Guide, which would have four issues per year (Summer, Fall, Winter, and Spring). A customer subscribes to the newsletter and each issue is sent to them as it becomes available. Begin by installing and activating the Simplenews module, as shown below: At this point, we only need to enable the Simplenews module, and the Simplenews action module can be left disabled. Next, select Content management and then Newsletters, from the Administer menu. Drupal will display an administration area divided into the following sections: a) Sent issuesb) Draftsc) Newslettersd) Subscriptions Click on the Newsletters tab and Drupal will display a page similar to the following: As you can see, a default newsletter with the name of our site has been automatically created for us. We can either edit this default newsletter or click on the Add newsletter link to create a new newsletter. Let's click the Add newsletter option to create our seasonal newsletter. Drupal will display a standard form where we can enter the name, description, and relative importance (relative importance weight) of the newsletter. Click Save to save the newsletter. It will now appear in the list of available newsletters. If you want to modify the Sender information for the newsletter to use an alternate name or email address to your site's default ones, you can either expand the Sender information section when adding the newsletter, or you click Edit newsletter and modify the Sender information, as shown in the following screenshot: Allowing users to sign-up for the newsletter Good Eatin' Goal: Demonstrate how registered and unregistered users can sign-up for a newsletter, and configure the registration process. Additional modules needed: Simplenews (http://drupal.org/project/simplenews). Basic steps To allow customers to sign-up for the newsletter, we will begin by adding a block to the page. Open the Block Manager by selecting Site building and then Blocks, from the Administer menu. Add the block for the newsletter that you want to allow customers to subscribe to, as shown in the following screenshot: We will now need to give users permission to subscribe to newsletters by selecting User management and then Permissions, from the Administer menu. We will give all users permissions to subscribe to newsletters and to view newsletter links, as shown below: If the customer does not have permission to subscribe to newsletters then the block will appear as shown in the following screenshot: However, if the customer has permissions to subscribe to newsletters, and is logged in to the site, the block will appear as shown in the following screenshot: If the customer has permission to subscribe, but is not logged in, the block will appear as follows: To subscribe to the newsletter, the customer will simply click on the Subscribe button. Once they he subscribed, the Subscribe button will change to Unsubscribe so that the user can easily opt out of the newsletter. If the user does not have an active account with the site, they will need to confirm that they want to subscribe to the site.
Read more
  • 0
  • 0
  • 2721

article-image-content-modeling
Packt
22 Oct 2009
12 min read
Save for later

Content Modeling

Packt
22 Oct 2009
12 min read
Organizing content in a meaningful way is nothing new. We have been doing it for centuries in our libraries—the Dewey decimal system being a perfect example. So, why can't we take known approaches and apply them to the Web? The main reason is that a web page has more than two dimensions. A page on a book might have footnotes or refer to other pages, but the content only appears in one place. On a web page, content can directly link to other content and even show a summary of it. It goes way beyond just the content that appears on the page—links, related content, reviews, ratings, etc. All of this brings extra dimensions to the core content of the page and how it is displayed. This is why it's so important to ensure your content model is sound. However, there is no such thing as the "right" content model. Each content model can only be judged on how well it achieves the goals of the website now and in the future. The Purpose of a Content Model The idea of a content model is new, but it has similarities to both a database design and an object model. The purpose of both of these is to provide a foundation for the logic of the operation. With a database design, we want to structure the data in a meaningful way to make storage and retrieval effective. With an object model, we define the objects and how they relate to each other so that accessing and managing objects is efficient and effective. The same applies to a content model. It's about structuring the content and the relationships between the classes to allow the content to be accessed and displayed easily. The following diagram is a simple content model that shows the key content classes and how they relate to each other. In this diagram, we see that resources belong to a collection which in turn belongs to a context. Also, a particular resource can belong to more than one collection. As stated before, there is no such thing as the "right" model. What we are trying to achieve is the most "effective" model for the project at hand. This means coming up with a model that will provide the most effective way of organizing content so that it can be easily displayed in the manner defined in the functional specification. The way a content model is defined will have an impact on how easy it is to code templates, how quickly the code will run, how easy it is for the editors to input content, and also how easy it is to change down the track. From experience, rarely is a project completed and then never touched again. Usually, there are changes, modifications, updates, etc. down the track. If the model is well structured, these changes will be easy, if not, they can require a significant amount of work to implement. In some cases, the project has to be rebuilt entirely and content re-entered to achieve the goals of the client. This is why the model is so important. If done well, it means the client pays less and has a better-running solution. A poor model will take longer to implement and changes will be more difficult to implement. What Makes a Good Model? It's not easy to define exactly what makes a good model. Like any form of design, simplicity is the key. The more the elements, the more complex it gets. Ideally, a model should be technology independent, but there are certain ways in which eZ publish operates that can influence how we structure the content model. Do we always need a content model? No, it depends on the scale of the project. Smaller projects don't really need a formal model. It's only when there are specific relationships between content classes that we need to go to the effort of creating a model. For example, a basic website that has a number of sections, e.g., About Us, Services, Articles, Contact, etc., doesn't need a model. There's no need for an underlying structure. It's just content added to sections. The in-built content classes in eZ publish will be enough to cater for that type of site. It's when the content itself has specific relationships e.g., a book belongs to a category or a product belongs to a product group, which belongs to a division of the business—this is when you need to create a model to capture the objects and the relationships between them. T o start with, we need to understand the content we are dealing with. The broad categories are existing/known content and new content. If we know the structure of the content we are dealing with and it already exists, this can help to shape the model. If we are dealing with content that doesn't exist yet (i.e. is to be written or created for this project) it's harder to know if we are on the right track. For example, when dealing with products, generally the product data will already exist in a database or ERP system. This gives us a basis from which to work. We can establish the structure of the content and the relationships from the existing data. That doesn't mean that we simply copy what's there, but it can guide us in the right direction. Sometimes the structure of the data isn't effective for the way it's to be displayed on the Web or it's missing elements. (As a typical example, in a recent project, the product data was stored in three places—the core details were in the Point of Sale system, product details and categorization were in a spreadsheet, and the images were stored on a file system.) So, the first step is to get an understanding of all the content we are dealing with. If the content doesn't exist as yet, at least get some examples of what it is likely to be. Without knowing what you are dealing with, you can't be sure your model will accommodate everything. T his means you'll need to allow for modifications down the track. Of course we want to minimize this but it's not always possible. Clients change their minds so the best we can do is hope that our model will accommodate what we think are the likely changes. This really can only be done through experience. There are patterns in content as well as how it's displayed. Through these patterns e.g., a related-content box on each page, we can try to foresee the way things might alter and build room for this into the model. A good example was that on a recent project, for each object, there was the main content but there were also a number of related objects (widgets) that were to be displayed in the right-hand column of the page. Initially, the content class defined the specific widgets to be associated with the object. The table below contains the details of a particular resource (as shown in the previous content model). It captures the details of the "research report" resource content class. Attribute Type Notes Title Text line Short Title Text Line If present, will be used in menus and URLs Flash Flash Navigator object Hero Image Image (displays if no flash) Caption Rich text   Body* Rich Text   Free Form Widgets Related Objects Select one or more Multimedia Widget Related Object Select one This would mean that when the editor added content, they would pick the free-form widgets and then the multimedia widget to be associated with the research report. Displaying the content would be straightforward as from the parent object we would have the object IDs for each widget. The idea is sound but lacks flexibility. It would mean that the order in which the object was added would dictate the order in which it was displayed. It also means that if the editor wants to choose to add a different type of widget, they couldn't unless the model was changed, i.e., another attribute was added to the content class. We updated the content class as follows: Attribute Type Notes Title* Text line Short Title Text Line If present, will be used in menus and URLs Flash Flash Navigator object Hero Image Image (displays if no flash) Caption Rich text   Body* Rich Text   Widgets Related Objects Select one or more This approach is less strict and provides more flexibility. The editor can choose any widget and also select the order. In terms of programming the template, there's the same amount of work. But, if we decide to add another widget type down the track, there's no need to update the content class to accommodate it. Does this mean that anytime we have a related object we should use the latter approach? No, the reason we did it in this situation is that the content was still being written as we were creating the model, and there was a good chance that once the content was entered and we saw the end result, the client was going to say something like "can we add widget x" to the right-hand column of a context object? In a different project, in which a particular widget should only be related to a particular content class, it's better to enforce the rule by only allowing that widget to be associated with that content class. Defining a Content Model The process of creating a content model requires a number of steps. It's not just a matter of analyzing the content; the modeler also needs to take into consideration the domain, users, groups, and the relationships between different classes within the model. To do this, we start with a walkthrough of the domain. Step 1: Domain Walkthrough The client and domain experts walk us through the entire project. This is a vital part of the process. We need to get an understanding of the entire system, not just the part that is captured in the final solution. The model that we end up creating may need to interact with other systems and knowing what they are and how they work will inform the shape of the model. A good example is with e-commerce systems, any information captured on a sale will eventually need to be entered into the existing financial system (whether is it automated or manual). Without an understanding of the bigger picture, we lack the understanding of how the solution we are creating will fit in with what the business does. That's when there is an existing business process. Sometimes there is no business process and the client is making things up as they go along, e.g. they have decided to do online shopping but they have never dealt with overseas orders so don't know how that will work and have no idea how they would deal with shipping costs. One of the typical problems that will surface during the domain walkthrough is that the client will try to tell you how they want the solution to work. By doing this, they are actually defining the model and interactions. This is something to be wary of. It is unlikely that they would be aware of how best to structure a solution; what you want to be asking is what they currently do, what's their current business process. You want to deal with facts that are in existence so that you can decide how best to model the solution. To get the client back on track ask questions like: How do you currently do "it" (i.e. the business process)? What information to you currently capture? How do you capture that information? What format is that information in? How often is the information updated? Who updates it? This gives you a picture of what is currently happening. Then you can start to shape the model to ensure that you are dealing with the real world, not what the client thinks they want. Sometimes they won't be able to answer the question and you'll have to get the right person from the business involved to get the answers you want. Sometimes you discover that what the client thought was happening is not really what happens. Another benefit of this process is gaining a common understanding. If both you and the client are in the room when the process for calculating shipping costs is being explained by the Shipping Manager, you'll both appreciate how complex the process is. If the client thinks it's easy, they won't expect it to cost much. If they are in the room when the shipping manager explains there are five different shipping methods and each has its own way of calculating the costs for a shipment based on their own set of international zones, you know modeling that part of the system is not going to be straightforward unlike what the client initially thought. What this means is that the domain walkthrough gives you a sense of what's real, not what people think the situation is. It's the most important part of the process. Assumptions that "shipping costs" are straightforward, so you don't need to worry about that, can be a disaster later down the track when you find out it's not the case. Also, don't necessarily rely on requirements documents (unless you have written them yourself). A statement in a requirements document may not reflect what really happens; that's why you want to make sure you go through everything to confirm that you have all the facts. Sometimes, a particular requirement can be stated in the document but when you go through it in more detail, ask a few questions, pose a few scenarios, the client changes their mind on what it is that they really want as they realize what they thought they wanted is going to be difficult or expensive to implement. Or, you put an alternative approach to them and they are happy to achieve the same result in a different manner that is easier to implement. This is a valuable way to work out what's real and what really matters.
Read more
  • 0
  • 0
  • 2522

article-image-module-development-joomla
Packt
22 Oct 2009
4 min read
Save for later

Module Development in Joomla

Packt
22 Oct 2009
4 min read
Introduction Modules in Joomla can be used to fetch and display data almost anywhere on a page in a website.In this article, we will cover the following topics on module development. Registering the module in the database Getting and setting parameters Centralizing data access and output using helper classes Selecting display options using layouts Displaying the latest reviews Displaying a random review We will assume that we have a table in our database called jos_modules with the following fields title, ordering, position, published, module, showtitle, and params. We will also assume that we have a website that reviews different restaurants. However, visitors have to go to the component to see the reviews. We would be developing a module so that we could pull the content directly from the reviews and display them. Registering the Module in the Database As with the component, we will have to register the module in the database so that it can be referenced in the back end and used effectively. Entering a record into the jos_modules table will take care of this. Open your database console and enter the following query: INSERT INTO jos_modules (title, ordering, position, published, module, showtitle, params) VALUES ('Restaurant Reviews', 1, 'left', 1, 'mod_reviews', 1, 'style=simplenitems=3nrandom=1'); If you're using phpMyAdmin, enter the fields as in the following screen: If you refresh the front end right after entering the record in jos_modules, you'll notice that the module doesn't appear, even though the published column is set to 1. To fix this, go to Extensions | Module Manager in the back end and click the Restaurants Reviews link. Under Menu Assignment, select All and click Save. In the front end, the left-hand side of your front page should look similar to the following: Creating and Configuring a Basic Module Modules are both simple and flexible. You can create a module that simply outputs static text or one that queries remote databases for things like weather reports. Although you can create rather complex modules, they're best suited for displaying data and simple forms. You will not typically use a module for complex record or session management; you can do this through a component or plug-in instead. To create the module for our reviews, we will have to create a directory mod_reviews under /modules. We will also need to create the mod_reviews.php file inside mod_reviews. To start, we'll create a basic module that displays links to the most recent reviews. In the mod_reviews.php file, add the following code: <?php defined('_JEXEC') or die('Restricted access'); $items = $params->get('items', 1); $db =& JFactory::getDBO(); $query = "SELECT id, name FROM #__reviews WHERE published = '1' ORDER BY review_date DESC"; $db->setQuery( $query, 0, $items ); $rows = $db->loadObjectList(); foreach($rows as $row) { echo '<a href="' . JRoute::_('index.php?option=com_reviews&id=' . $row->id . '&task=view') . '">' . $row->name . '</a><br />'; } ?> When you save the file and refresh the homepage, your module should look similar to the following: When the module is loaded, the $params object is pulled into scope and can be used to get and set the parameters. When we added the row into jos_modules, the params column contained three values: one for items (set to 3), one for style (set to simple), and another for random (set to 1). We set $items to the parameter items using the get() member function, defaulting to 1 if no value exists. If desired, you can use the member function set($name, $value) to override or add a parameter for your module. After getting a database object reference, we write a query to select the id and name form jos_reviews and order reverse chronologically by the published date. We use the second and third parameters of setQuery() to generate a LIMIT clause that is automatically added to the query. This ensures that the correct syntax is used for the database type. Once the query is built, we load all the relevant database rows, go through them, and provide a link to each review.
Read more
  • 0
  • 0
  • 2996

article-image-linux-thin-client-considering-network
Packt
22 Oct 2009
4 min read
Save for later

Linux Thin Client : Considering the Network

Packt
22 Oct 2009
4 min read
Primary Network Your first thought might be that your current network will work fine with thin clients and that is entirely possible. But your network might be something that has grown through the years and is not that well designed. Your implementation of thin clients then might be a good time to review the design and make upgrades as needed. Personal Computers versus Thin Clients Based on conversations with some hardware vendors, it's clear that most of the testing is done with the expectation that personal computers willbe deployed. The biggest difference is in how the two platforms use the network. When running a personal computer, often software applications are stored on network servers. When you activate an icon, the network pushes the executable down to your PC. Once downloaded into memory, the application runs and then very little interaction takes place until you save a file. Or in other cases, the executables are on the local PC, and network activity is not used until files are saved. If an executable takes a few seconds longer to download, you won't      really notice it when using a personal computer. Some networking devices seem better designed for efficiency of download instead of being designed for the smaller and more plentiful packets of network computing. When you activate a software application on a thin client, the presentation of the user interface is pushed to you from the server, and then all keystrokes and mouse activity are transmitted back and forth to the server in real time. The network needs to be very fast, have low latency, and be configured to pass packets immediately to the servers. Network Design For implementing your network, the network backbone should be Gigabit if possible. Obviously if your solution is for only a small number of users, this might not be required. Ideally fibre optic lines are then run to each of the wiring closets, and each switch should have it's own line. It is advisable to avoid daisy-chaining the switches together in order to avoid any kind of contention between them. The servers are all plugged into the backbone at Gigabit as well. If a server is required away from a centralized computer room, then it is better to run a separate line instead of plugging it into a switch that will be shared with thin clients. It's important to keep the data paths solidly designed so that all of your real-time interaction will not be delayed. X windows, RDP, or Citrix are used to display the user presentation. This means that the software is running on the server, but the image of that software is transmitted over the network. It's important that a strong network exists or repaints of windows will be slower and feel sluggish. This issue will cause people problems, with perceptions that a personal computer can run software faster than a network. A correctly designed network will provide excellent response time and the user community should not even see a difference. Font servers are used to distribute fonts to users. A font server is just a process or application that runs on the server. When a user requests a font, it's sent over the network to the thin client and made available to them immediately. The strength of this design is that all your employees will have the same fonts and while sharing documents, they will render exactly the same way no matter from where you log into the network. Anyone that has shipped documents between personal computers with different fonts, will greatly appreciate this design. When the network is configured correctly, font download and interaction is immediate and undetected by the user community. NFS mounts are used to connect disk drives between Linux servers. This allows applications to share data between the various servers on your network. Response time needs to be excellent to provide very fast file saves and retrievals, at the same time avoiding applications that lock or timeout while trying to interact with files. A review of the possible network problems is provided in the following table: Networking Issue Symptom(s) X windows RDP Citrix Slow repaints of user interfaces Lockups Disconnections Font Servers Slow repaints Wrong fonts in applications Thin Client Slow keyboard response Disconnections Slow repaints NFS Mounts Lockups Slow response in saving files  
Read more
  • 0
  • 0
  • 1539
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-modeling-orchestration-and-choreography-service-oriented-architecture
Packt
22 Oct 2009
30 min read
Save for later

Modeling Orchestration and Choreography in Service Oriented Architecture

Packt
22 Oct 2009
30 min read
  Choreography versus Orchestration Choreography and orchestration, in an SOA context, pertain to the use of processes that span multiple participants, with message traffic moving in all directions according to a complex set of rules. Choreography and orchestration are attempts to coordinate or control all of this activity. They attack the problem by putting rigor on how message exchanges are represented, and by organizing the overall process using the right set of control flow patterns. Use cases in this area can be inter-organizational (for example, B2B commerce involving buyer, seller, and wholesaler), or intra-organizational if the organization is large enough and the participants act as separate organizations (for example, bank account processes spanning the front office, the back office, and the fraud department). By convention, choreography describes the global protocol governing how individual participants interact with one another. Each participant has its own process, but choreography is a master process that acts as a kind of traffic cop. Significantly, the choreography process does not actually run. It is not a central broker in the live message exchange, but merely a message exchange protocol. If the participants follow the protocol, the live exchange will run as smoothly as if there were a central broker. 'Traffic cop' is not exactly right then; choreography is more like a set of traffic rules. To mix metaphors, choreography teaches the participant processes how to dance as a group. The process for each participant is referred to as an orchestration process, whose principal job is to build a flow of control around (that is, to orchestrate) its interactions with partners. Orchestration processes are difficult to model, especially those faced with complex combinations of inbound events. If the process is subject to choreography, its structure can be derived from the choreography; in fact, as we'll see, there are tools that can generate skeletal orchestration processes from choreography definitions. The idea is simple: the choreography tells the complete story, so the participant can determine its role by isolating the parts in which it's involved. Not all orchestrations, alas, have a choreography to guide them (not all inter-organizational domains have a precise protocol defined). If the use case is sufficiently complex, the participant ought to create its own choreography anyway, not to share with its partners but simply to improve its own understanding of its orchestration. An orchestration process has public and private activities. The public activities are those that are required by the choreography. Private activities are there to meet internal requirements, but are not visible to partners. The next figure shows the public activities of the orchestration process for an energy retailer. The steps shown (for example, Send Request to Distributor) are those required by the enrollment choreography, in which the retailer is but one participant. The next figure shows the same process with private steps (for example, Update Account) included. In the figure, steps marked with a P are public steps. We examine the energy example in detail in this article. Web Services Choreography Description Language (WS-CDL) is the leading choreography language; Business Process Execution Language (BPEL) is the dominant process orchestration language. Although these XML-based languages feature a similar flow-oriented design style, only BPEL is meant to have an actual runtime platform: BPEL processes run; WS-CDL choreographies are protocols. BPEL is better known than WS-CDL in part because orchestration is more prevalent than choreography. BPEL's user community is much larger than WS-CDL's. Today, every company is building an SOA platform, and if they don't use BPEL as their SOA orchestration language, they use something similar. The user community for choreography consists of industry committees that publish protocols such as the enrollment and funds transfer choreographies we discuss in this article. Choreography might also work as part of a large organization's enterprise architecture, helping to sort out the communication of the organization's numerous systems. Few of these committees use WS-CDL to document their protocols anyway. Choreography is more often documented less formally using English descriptions, flowchart diagrams, and an XML message schema. Examples-Energy Enrollment and Email Bank Transfer The two examples from industry that showcase our technique for modeling choreography and orchestration are the enrollment of customers with retailers in a deregulated energy market and the procedure for transferring funds by email between two banks. In the energy market for a state or small country there are three parties: customers (who use electricity to power their homes), retailers (who sell electricity to customers), and the distributor (who supplies the electricity). Before deregulation, the distributor sold electricity directly to customers; there were no retailers back then. Deregulation introduced competition and broke up the distributor's monopoly. Customers can now buy electricity from one of many competing retailers. The distributor is now merely a supplier, having moved out of the retail sales business. When a customer enrolls with a retailer, the retailer uses the following protocol to complete the enrollment: The retailer submits the customer's request for enrollment to the distributor. The distributor responds in one of the three ways. If there is a problem with the request (for example, the customer has another enrollment in progress, or the customer has been flagged for fraud), the distributor sends a rejection to the retailer. If the request is valid and the customer is not currently enrolled with a retailer, the distributor sends an acceptance to the retailer. If the customer is currently enrolled with a competing retailer but intends to switch, the distributor sends a notice of pending switch to both the retailers. In the acceptance case, there is a 10-day waiting period during which the customer may cancel the enrollment. To cancel, the customer contacts the retailer, who forwards the cancellation request to the distributor. Assuming the customer does not cancel, at the end of the waiting period, the distributor sends a completion event to the retailer. The customer is now enrolled with the retailer. In the switch case, there is also a 10-day waiting period. To cancel, the customer contacts the initiating retailer (that is, the retailer to whom the customer is switching). The initiating retailer forwards the cancellation to the distributor, who then sends completion events to both retailers indicating that the customer will remain enrolled with the original retailer. Assuming the customer does not cancel, at the end of the waiting period, the distributor sends completion events to both retailers indicating that the customer is now enrolled with the initiating retailer. Email bank transfer is a protocol for wiring money by email. It works as follows: The person sending the money contacts his bank (the Sender bank), specifying from which account to draw the funds, how much money to send, and the name and email address of the recipient. The Sender bank sets aside the amount and sends an email to the recipient with instructions on how to complete the transfer. The Sender bank sets aside the amount and sends an email to the recipient with instructions on how to complete the transfer. The Recipient bank submits the transfer request to the Sender bank. The Sender bank accepts, and the funds are moved into the recipient's account, completing the transfer. At any point, either the sender or recipient may cancel the transfer, and the transaction is automatically canceled if not completed within 30 days. On cancellation, the funds are returned to the sender's account. (We assume both banks are members of the email transfer programme.) The following figure shows the most common scenarios in these examples: Modeling Choreography in BPMN In BPMN, two possible models for choreography are as follows: Invisible hub: Although choreography is fundamentally decentralized, we imagine there is a central hub through which all messages pass, and model the choreography as the process of that hub. Sum of parts: The public process of each participant (that is, the process containing steps required by the choreography, with private steps omitted) is drawn in a swim lane. Message flow (dashed lines) is used to show inter-participant communication. A sum-of-parts model for the enrollment choreography is shown in next figure. There are three swim lanes in the diagram: one for the distributor (referred to as Distributor), one for the initiating retailer (referred to as Retailer), and one for the current retailer (referred to as CurrentRetailer). Each lane contains the public process of the participant. The dashed arrows show the flow of messages between participants. The enrollment choreography is, according to this approach, the combination of the public processes of each participant plus the message flow that connects them. The choreography begins when the customer enrolls with the retailer (Cust Enrolls in the Retailer lane). The retailer then submits the enrollment request to the distributor by calling Dist.enroll. This call sends a message to the distributor, which triggers the event Enroll (the first step in the Distributor lane). The Distributor process is now underway, and it responds to the enrollment request either by rejecting the request, accepting it, or notifying the initiating retailer and the current retailer of a pending switch. The distributor rejects by calling Ret.reject, and, as the dashed line signifies, triggers the event Dist.reject in the retailer. The remaining steps are straightforward. The sum-of-parts method is intuitive, and variations on it can be found in business process literature (in the WSCI and BPMN specifications, for example). Sum-of-parts, however, has two disadvantages. First, the message flow creates an indecipherable clutter, making complex choreographies almost impossible to read; the swim lanes, for their part, use a lot of real estate. Aesthetics aside, sum-of-parts fails to present a global, consolidated view of the choreography. We grow bug-eyed trying to keep track of what each participant is doing. We are forced to watch each dancer rather than the group as a whole. The invisible-hub representation is comparatively compact. The next figure, which shows the enrollment choreography as a hub, has fewer steps than the sum-of-parts equivalent, and it makes do without lanes or dashed lines. The hub works as you would expect a hub to work: it listens for inbound events and routes them to their intended recipients. The act of receiving an event and sending it elsewhere is a single unit of work (shown in the figure as a rounded box with a dashed line), known as an interaction. The hub choreography represents the communication of its participants as a process of interactions. Before walking through this process, consider the following notational conventions: The event with a thin border (Ret.enroll(Dist)) is the process' start event. Events with a double-line border (for example, Dist.reject(Ret)) are intermediate events, which occur over the course of the process. Intermediate events can be used in three ways: for cancellation, for deferred choice, or simply to wait for the next message before continuing. The enrollment hub has examples of the latter two forms. We'll come back to cancellation while discussing the email transfer hub. Deferred choice, also known as an event pick, uses a diamond containing an inscribed star (known as an event-based gateway) with arrows leading to a set of intermediate events. The intent is to wait for one of those events to occur, execute its activities, and discard the remaining events. There are three deferred choices in the enrollment hub. The first occurs in three steps, and selects one of the three events: Dis.reject(Ret), Dist.accept(ret), or Dist.pendingSwitch(Ret, CurrRet). If, say, Dist.reject(Ret) occurs first, the activity Ret1.reject(Dist) is executed. The intermediate event Dist.switchCompleteCurrent(Ret, CurrRet) simply waits for something to happen before continuing. This event is sandwiched between the activities Dist.cancel(Ret) and Ret.switchCompleteCurrent, CurrRet.switchCompleteCurrent(Dist). Thus, when the first activity completes, that branch of the process waits for the event to occur before continuing with the second activity. Events have labels of the form Sender.msg (Recipients), meaning that the event received by the hub is a message from the sender bound for the specified recipients. (There must be at least one.) Thus, Dist.switchCompleteCurrent(Ret, CurrRet) is the message switchCompleteCurrent from the distributor (Dist) to both the initiating retailer (Ret) and the current retailer (CurrRet). Send tasks (rounded boxes with a straight border) are labeled Recipient.msg(Sender), meaning that hub is sending the specified message to the recipient and is indicating that the message originated with the specified sender. In Dist.enroll(Ret), for instance, the hub sends the message enroll to the distributor (Dist), and is indicating to the distributor that this message came from the retailer (Ret). If the event that preceded it specifies multiple recipients, the send task sends the message to each recipient. Each send counts as one interaction.Ret.pendingSwitch, CurrRet.pendingSwitch (Dist), for example, sends the message pendingSwitch to both the retailer (Ret) and the current retailer (CurrRet), and thus spans two interactions. A rounded box with a dashed border, known in BPMN as a group, pairs up an event and a send task. Thus, the grouping of Ret.enroll(Dist) and Dist.enroll(Ret) means that when the hub receives the message enroll from the retailer bound for the distributor, it sends that message to the distributor, indicating to the distributor that the message originated with the retailer. A group that contains multiple interactions has a label in the top-center of the dashed box indicating the number of interactions. The number of interactions is equal to the number of recipients. The enrollment hub diagram reads as follows: The choreography begins with the interaction in which the retailer sends an enrollment request to the distributor. For convenience, this interaction is labeled a in the figure. Exactly one of the three interactions can happen next: the distributor sends a rejection to the retailer (b); the distributor sends an acceptance to the retailer (c); or the distributor sends a notice of pending switch to both the initiating and current retailers (d). Exactly one of the two interactions can follow acceptance: the retailer sends a cancellation to the distributor e, or the distributor sends a completion event to the retailer (f). In the pending switch case, one of the two interactions follows the notice of pending switch: the initiating retailer sends a cancellation to the distributor (g); or the distributor sends a switch completion event to both the initiating and current retailers indicating that the current retailer won (h). If the switch is cancelled, the distributor sends a switch completion event to both retailers indicating that the initiating retailer won (i). The choreography has 12 interactions assembled in a process flow. (There are nine groups, but three of them have two interactions each.) Reading the diagram means spotting the 12 interactions and traversing the control flow that connects them. The email transfer choreography hub, shown in the next figure, is somewhat more complex. The email transfer hub reads as follows: The choreography begins when the sender submits the transfer request to the sender bank (a). The sender bank can reject the request (b), or accept it (c). The acceptance event in c is routed to both the sender and the recipient, and thus results in two interactions. The remainder of the hub process is a loop that continues until the transfer is completed. The loop is modeled as a BPMN embedded sub-process labeled Loop. The arched arrow pointing counter-clockwise in the bottom-center of the sub-process box denotes that this sub-process is iterative. In the first step of the loop, the recipient requests her bank to transfer the funds into his or her account (d). The recipient's bank either rejects (e) or accepts (f) the request. In the rejection case, the recipient's bank sends a rejection notice to the recipient. In the next iteration of the loop, the recipient can try again. In the acceptance case, the recipient's bank sends a transfer request to the sender's bank. The sender's bank can either accept (g) or reject (h) the request. In the acceptance case, the sender's bank sends a transferOK message to both the recipient's bank and the sender. The recipient's bank then notifies the recipient (i), and the choreography completes. (The Set Done task sets the loop's continuation condition to false, which causes the loop to exit and the hub process to complete.) In the rejection case, the sender's bank sends a rejectTransfer message to the recipient's bank, and the recipient's bank notifies the recipient of this (j). In the next iteration of the loop, the recipient can try again. While the loop is executing, any of the parties may cancel the request (k). The label in the event *.cancel (SenderBank) informs the hub to listen for a cancel message from any party—the * works as a wildcard—and to route that message to the sender's bank. The sender's bank, in turn, sends an abort message (l) to the sender, the recipient, and the recipient's bank (the bank into which the recipient is currently requesting the transfer). Interaction (k) is an example of a cancellation intermediate event; it terminates the loop and transition into a series of cancellation activities. Choreographies are not executable, as we discussed previously. A choreography is a protocol, a set of traffic laws. It is, emphatically, not a central hub through which all participant interactions flow. Our hub model is merely a specification of how the individual participants should communicate. There are countless senders, recipients, and banks in the world of email transfer, but there is no hub that helps them talk to each other. The invisible hub for email transfer is merely a model; it is every bit as hypothetical as the invisible hand of Adam Smith's free-market economy. The economy is self-powered, and does not require the intervention of a hand; email transfer goes on without a hub. Still, the BPMN hub model is more than an informative picture. As we'll see, it maps easily to WS-CDL, and it serves as the basis for the generation of participant stubs and a choreography 'protocol' tester. Our BPMN method is practical and built with implementation in mind. Choreography modeling is also a hot topic in the academic world. Useful papers in this arena include Inheritance of Interorganizational Workflows: How to agree to disagree without loosing control? (Wil van der Aalst," BETA Working Paper Series, BP46, Eindhoven University, http://is.tm.tue.nl/staff/wvdaalst/publications/p109.pdf) and 'Let's Dance' (servicechoreographies.com, http://sky.fit.qut.edu.au/~dumas/LetsDance/01-Overview.html). The Invisible Hub in BPEL BPEL is principally an orchestration language, as just discussed, but it can also be used to model invisible hub choreographies. The code shown in the next figure is a simplified version of an actual BPEL implementation of the enrollment hub. The mapping from the BPMN hub to this BPEL implementation is straightforward: The event that starts the choreography in BPMN (Ret.enroll(Dist)) is receive that creates the BPEL process instance, marked as Start Event in the figure. An intermediate event that simply waits for a message between activities (for example, Dist.switchCompleteCurrent (Ret, CurrRet) in the BPMN model) is a BPEL receive, such as the line marked Intermediate Event in the figure. Deferred choice is a BPEL pick. The events in the choice are onMessage handlers. For example, the deferred choice in the BPMN model of Dist.reject(Ret), Dist.accept(Ret) and Dist.pendingSwitch(Ret, CurrRet) is the pick marked as Deferred Choice in the figure. The handlers are the three onMessage blocks that sit underneath the pick. Send tasks are BPEL invoke activities. For example, Dist.enroll(Ret) in the BPMN representation becomes the invoke in the line marked Send Task in the figure. The set of partner links used in the BPEL process is the union of all sender and recipient participants in the hub. Many partner links are bidirectional: they can either call the BPEL process or the BPEL process can call the partner link. The three partner links in this example, which are referred to in each receive, invoke, and onMessage tag are Ret, Dist, and CurrRet. BPEL supports dynamic partner links (where the BPEL process determines the physical address of its partner service at runtime). The series of four steps marked Dynamic partner links in the figure provides an example. The initial receive is a message from the distributor intended for one of the two retailers (either the current or the initiating retailer). The invoke that follows sends the message to that retailer. The endpoint of that retailer is resolved at runtime, based on the contents of the receive message. The next receive is a message from the distributor intended for the second retailer, and the invoke that follows sends the message to that retailer, again resolving the endpoint at runtime. In the majority of BPEL processes, partner links are resolved at deployment time, but that approach does not work in scenarios like ours. An interaction in which the sender sends to N recipients is modeled in BPEL as N separate inbound events and invokes. The series of four steps discussed in the previous bullet (and marked with Send to Multiple in the figure) provides an example. These steps model the activity Dist.switchCompleteCurrent (Ret, CurrRet) from the BPMN hub. In the BPEL code, the effect of the distributor sending the message switchCompleteCurrent to both the initiating and current retailers is achieved by having the hub receive the message from the distributor twice (using a receive), in each case forwarding the message (using an invoke) to one of the retailers. Dynamic partner links are used to resolve the endpoint of the recipient. The figure maps lines of code in the BPEL hub to interaction groups in the BPMN model. The first two lines, for example, represent group A. The reader can easily verify the mapping for groups B to I. There are two advantages to having the hub model in BPEL form: BPEL's XML form is an alternative to the leading XML choreography representation, WS-CDL (discussed in the next section). If we require an XML representation of choreography, BPEL might be a better choice than WS-CDL, because it is more familiar and has broader tool support. The BPEL hub is executable! There are numerous BPEL runtime platforms that can run this process as an actual hub. Granted, choreographies are not meant to run as part of the live exchange of actual participants, but having an executable version enables two important types of testing, shown in the next figure: unit testing of the choreography itself, and protocol testing of a particular participant. In unit testing, we build a Test Harness, driven by scripted scenarios, that sends messages to the hub and compares responses received with those expected. In protocol testing, we build the public process of a participant (say the retailer), but point it to the hub rather than its actual partners. We can embellish the hub to use test scripts to control how it responds. Once we have tested all of the scenarios and verified that the participant behaves as required, we can point the participant process to the real partners and go live Choreography in WS-CDL with Pi4SOA The description of choreography in WS-CDL with P14SOA is as follows: Defining Roles and Relationships Web Services Choreography Description Language (WS-CDL) is a specification from the W3C (Web Services Choreography Description Language Version 1.0, http://www.w3.org/TR/ws-cdl-10) for building choreographies in XML form. Like our invisible hub model, WS-CDL takes the global view: a choreography is not the sum of the public processes of its participants, but a single control flow of interactions. The WS-CDL language is exceedingly rich and best learned by example. In this section, we study how the enrollment choreography is represented in WS-CDL. Rather than building the choreography's XML from scratch, we use a visual modelling tool known as pi4SOA. pi4SOA, an open-source implementation that plugs into Eclipse, is one of the few WS-CDL implementations available today. The first step in building a WS-CDL choreography is to define participants and their structural relationships. The following figure shows the enrollment choreography open in the Participants, Roles, and Relationships tab of the pi4SOA editor.   There are five participants (shown with building icons) in the figure: Distributor, Retailer, CurrentRetailer, Customer (to model a customer's interaction with a retailer), and DistributorBizCal (a subsystem of the distributor to model the management of business calendars for completion and switch periods). Each participant has a role of the same name (designated by a stick-man icon), and each role has a behavior named for its role: Distributor's behavior is DistributorBehavior, Retailer's behaviour is RetailerBehavior, and so on. In WS-CDL, a behavior is a web service interface, and a role is a group of behaviors. A role can have multiple behaviors and a participant can have multiple roles. In our case, each participant has one role and one participant. The lines connecting roles are called relationships. There are four relationships: RD is the relationship between Retailer and Distributor, CRD the relationship between CurrentRetailer and Distributor, RC the relationship between Retailer and Customer, and DInt the relationship between Distributor and DistributorBizCal. When two roles have a relationship, they can interact by calling each other's services. The next figure shows the Base Types tab of the choreography editor. To the participants, roles, and relationships defined above, we add four important elements: information types, tokens, token locators, and channel types. An information type is an XML data type (generally based on an XML schema) exchanged during interactions. A token is a field in an information type. A token locator defines how to extract—generally using an XPath expression—the token from the information type. Our choreography has one information type, called EnergyMsg with five tokens and token locators (custID, retailer, txID, currentRetailer, and reason). A channel type is an inbound communication endpoint for a role behavior. In the enrollment choreography, there are channels for the retailer, current retailer and distributor. Each channel type is configured for one-way asynchronous requests only. Hence, Retailer receives requests on its RetailerChannel; CurrentRetailer receives requests on its CurrentRetailerChannel; and Distributor receives requests on its DistributorChannel. Combining our definitions of relationships and channels, we have the following communication structure: In the relationship RD, Retailer sends to Distributor on DistributorChannel, and Distributor sends to Retailer on RetailerChannel   In the relationship CRD, Distributor sends to CurrentRetailer on CurrentRetailerChannel. (CurrentRetailer could also send to Distributor on DistributorChannel, but the use case does not require it.) In the relationship RC, Customer sends to Retailer on RetailerChannel. (Customer does not have a channel, so the reverse direction is not permitted.) In the relationship DInt, DistributorBizCal sends to Distributor on DistributorChannel. (DistributorBizCal does not have a channel, so the reverse direction is not permitted.) Building a Control Flow of Interactions The next figure shows the overall control flow that defines the behaviour of the choreography. There are three steps. The first, RequestC2R, is an interaction in which the Customer participant sends an enrollment request to the Retailer participant. The request has the information type EnrollmentMsg, and is sent on RetailerChannel as part of the RC relationship. In the interaction that follows, RequestR2D, the retailer forwards that request to the distributor; or, in the language of WS-CDL, Retailer sends the request with information type EnrollmentMsg on the DistributorChannel as part of the RD relationship. The step that follows, enrollmentResult, is a flow construct known as a choice. There are three possible outcomes of an enrollment request—acceptance, rejection, or a pending switch. The choice allows exactly one to occur. The next figure shows the acceptance and rejection paths; the switch path is omitted for brevity. The rejection path (housed in a sequence labelled rejectEnrollment) has one interaction, RejectD2R, in which the distributor sends a rejection message to the retailer. The more complicated acceptance path is housed in the sequence labelled newEnrollment, which begins with the interaction in which the distributor notifies the retailer that the enrollment is accepted (AcceptD2R). Next is a silent action, setCompletionTimer, in which the distributor sets a timer that expires at the end of the ten-day cancellation period. A silent action in WS-CDL is a private operation performed by a role. The acceptance path has a nested choice, labelled completionPeriod, which documents the two possible outcomes for an accepted enrolment: periodExpired is a sequence that specifies what happens when the ten-day timer expires, and cancel handles the case in which the customer cancels the enrollment during the cancellation period. Each path contains two interactions. In the periodExpired sequence, the periodExpired interaction (sent from DistributorBizCal to Distributor by the DInt relationship) notifies the distributor that time is up, whereupon the distributor sends a completion event to the retailer (CompleteD2R). In the cancel sequence, the customer cancels with the retailer (CancelC2R by the RC relationship), and the retailer, in turn, cancels with the distributor (CancelR2D by the RD relationship). The following is a snippet of the WS-CDL XML encoding of the enrollment choreography, covering the acceptance case only. For the sake of simplicity, numerous details are omitted: <package name="EnergyChoreo">   <choreography name="main" root="true">     <sequence>       <!-- Cust sends request to retailer -->       <interaction channelVariable="tns:retailerChannel"                    name="RequestC2R" operation="enroll">         <participate fromRoleTypeRef="tns:Customer"                      relationshipType="tns:RC" toRoleTypeRef="tns:Retailer"/>       </interaction>       <!-- Retailer sends request to distributor -->       <interaction channelVariable="tns:distributorChannel"                    name="RequestR2D" operation="enroll">         <participate fromRoleTypeRef="tns:Retailer"                relationshipType="tns:RD" toRoleTypeRef= "tns:Distributor"/>       </interaction>       <!-- Choose what comes next -->       <choice>         <!-- Path taken if distributor rejects -->         <sequence>           <!-- This is the interaction that heads the reject path -->             <interaction name="RejectD2R" operation="reject">             </interaction>         </sequence>         <!-- Path taken if distributor accepts -->         <sequence>           <!-- This is the interaction that heads the accept path -->             <interaction name="AcceptD2R" operation="accept">             </interaction>             <silentAction name="setCompletionTimer"                           roleType="tns:Distributor">             <choice>               <!-- Accept subpaths omitted -->             </choice>          </sequence>          <!-- Omitted: switch path -->       </choice>     </sequence>   </choreography> </package> The two key elements in this example are choice and interaction. They are mapped to our hub model as follows: A receive-send pair in the hub is a WS-CDL interaction. In WS-CDL, a relationship is defined between sender and recipient, and the recipient has a channel on which the sender sends the message. An example of this is the interaction shown in bold from the customer (fromRoleTypeRef="tns: Customer") to the retailer (toRoleTypeRef="tns:Retailer") on the RC relationship (relationshipType="tns:RC"). The event arrives on the retailer's channel (channelVariable="tns:retailerChannel"). A deferred choice in the hub is a choice structure in WS-CDL. Generally, a path in the choice is a sequence. The set of events from which we are choosing is the set of first interactions on each path. The main choice structure in the choreography, shown in bold, has two interactions from which to choose: acceptance and rejection interactions (also shown in bold). The interaction that actually occurs determines which path is taken.   Generating a BPEL Role Process In addition to producing conformant WS-CDL code, pi4SOA's capabilities include scenario testing and BPEL and Java endpoint generation. The BPEL generation feature is especially useful, as BPEL is a suitable implementation choice to build orchestration process of a given participant. Here, in pseudo-code, is the BPEL process that pi4SOA generates for the distributor: <process>   <sequence>     <receive operation="enroll" partnerLink="RD"              portType="DistributorBehavior"/>       <!-- Dist receives interaction -->     <switch name="enrollmentResult"> <!-- Dist choice is switch -->       <case condition="accepted">         <sequence>           <invoke operation="accept" partnerLink="RD"                   portType="RetailerBehavior"/> <!-- Dist is sender -->           <scope name="setCompletionTimer"/>           <pick name="completionPeriod">             <onMessage operation="periodExpired" partnerLink="DInt"                        portType="DistributorBehavior">               <sequence>                 <invoke operation="complete" partnerLink="RD"                         portType="RetailerBehavior"/>               </sequence>             </onMessage>             <onMessage operation="cancel" partnerLink="RD"                        portType="DistributorBehavior"/>           </pick>         </sequence>       </case>       <case condition="rejected ">         <invoke operation="reject" partnerLink="RD"                 portType="RetailerBehavior"/>       </case>       <case condition="switch">         <!-- omitted -->       </case>   </switch> </sequence> </process> Two salient features of this process are the mapping of interactions and the conversion of the WS-CDL choice to a BPEL switch as follows: An interaction in which the distributor is the sender is a BPEL invoke activity whose partner link is the WS-CDL relationship and whose port type is the recipient's behavior. The operation element in the invoke matches the one specified in the interaction. The invoke shown in bold, for example, which is sent to the retailer, has partner link RD, port type RetailerBehavior, and operation accept. An interaction in which the participant is the recipient is either a receive activity or an onMessage handler in a pick. The partner link is the name of the relationship, and port type is the participant's behavior. The operation element, as before, matches that specified in the interaction. The bolded receive in the BPEL sample is the enroll operation on the partner link RD and port type DistributorBehavior. The WS-CDL choice is a switch for the BPEL distributor process (as the bolded comment in the switch line indicates), because the distributor begins each path of the choice by sending a message. From the distributor's perspective, the choice represents its decision to reject the request, accept it, or initiate a pending switch. Each case in the switch handles one of these possibilities. The retailer, on the other hand, begins each path by waiting for an event from the distributor. From the retailer's point of view, the choice is a pick, as in the following snippet: <pick name="enrollmentResult"> <!-- For Ret, choice is a pick -->   <onMessage operation="accept" partnerLink="RD"              portType="RetailerBehavior">     <!-- code omitted -->   </onMessage>   <onMessage operation="reject" partnerLink="RD"              portType="RetailerBehavior" />   <onMessage operation="pendingSwitch" partnerLink="RD"              portType="RetailerBehavior" >     <!-- code omitted -->   </onMessage> </pick> We have only scratched the surface of WS-CDL. Other notable capabilities are state alignment, coordination, and channel passing. WS-CDL's supporters boast that their language has its foundations in the Pi Calculus, a mathematical scheme for describing concurrent processes and how they pass messages to each other. Robin Milner, the mathematician who devised the Pi Calculus, is an advisor to the WS-CDL working group. Sadly, WS-CDL has not gained much traction in the field. There are scant tools to build WS-CDL choreographies and, frankly, not many use cases that require choreography. Few people who practice SOA technology have even heard of this language. WS-CDL is winning the mathematics battle but losing the marketing war. Summary Choreography is the global protocol governing the interaction of SOA processes partnering to achieve some business ends. An orchestration process is a process whose principal job is to build a flow of control around its interactions with partners. WS-CDL is the dominant choreography standard. BPEL is the dominant orchestration standard. Both standards provide a way to build process flows in an XML form, though only BPEL processes are meant to actually execute. The modeling tool pi4SOA is ideal for building WS-CDL examples. Key WS-CDL elements are interaction (which corresponds to the receive-send pair in the invisible hub) and choice (a kind of deferred choice in the choreography's flow of control. pi4SOA generates skeletal BPEL code for each participant in the choreography.
Read more
  • 0
  • 0
  • 7700

article-image-basic-dijit-knowledge-dojo
Packt
22 Oct 2009
7 min read
Save for later

Basic Dijit Knowledge in Dojo

Packt
22 Oct 2009
7 min read
All Dijits can be subclassed to change parts of their behavior, and then used as the original Dijits, or you can create your own Dijits from scratch and include existing Dijits (Forms, buttons, calendars, and so on) in a hierarchical manner. All Dijits can be created in either of the following two ways: Using the dojoType markup property inside selected tags in the HTML page. Programmatic creation inside any JavaScript. For instance, if you want to have a ColorPalette in your page, you can write the following: <div dojoType="dijit.ColorPalette"></div> But you also need to load the required Dojo packages, which consist of the ColorPalette and any other things it needs. This is generally done in a script statement in the <head> part of the HTML page, along with any CSS resources and the djConfig declaration. So a complete example would look like this: <html> <head> <title>ColorPalette</title> <style> @import "dojo-1.1b1/dojo/resources/dojo.css"; @import "dojo-1.1b1/dijit/themes/tundra/tundra.css"; </style> <script type="text/javascript"> djConfig= { parseOnLoad: true } </script> <script type="text/javascript" src="dojo-1.1b1/dojo/dojo.js"></script> <script type="text/javascript"> dojo.require("dojo.parser"); dojo.require("dijit.ColorPalette"); </script> </head> <body class=”tundra”> <div dojoType="dijit.ColorPalette"></div> </body> </html> Obviously, this shows a simple color palette, which can be told to call a function when a choice has been made. But if we start from the top, I've chosen to include two CSS files in the <style> tag. The first one, dojo.css, is a reset.css, which gives lists, table elements, and various other things their defaults. The file itself is quite small and well commented. The second file is called tundra.css and is a wrapper around lots of other stylesheets; some are generic for the theme it represents, but most are specific for widgets or widget families. The two ways to create Dijits So putting a Dojo widget in your page is very simple. If you would want the ColorPalette dynamically in a script instead, remove the highlighted line just before the closing body tag and instead write the following: <script> new dijit.ColorPalette({}, dojo.byId('myPalette')); </script> This seems fairly easy, but what's up with the empty object literal ( {} ) as the first argument? Well, as some Dijits take few arguments and others more, all arguments to a Dijit get stuffed into the first argument and the others, the last argument is (if needed) the DOM node which the Dijit shall replace with its own content somewhere in the page. The default is, for all Dijits, that if we only give one argument to the constructor, this will be taken as the DOM node where the Dijit is to be created. Let's see how to create a more complex Dijit in our page, a NumberSpinner. This will create a NumberSpinner that is set at the value '200' and which has '500' as a maximum, showing no decimals. To create this NumberSpinner dynamically, we would write the following: <input type="text" name="date1" value="2008-12-30" dojoType="dijit.form.DateTextBox"/> One rather peculiar feature of markup-instantiation of Dijits is that you can use almost any kind of tag for the Dijit. The Dijit will replace the element with its own template when it is initialized. Certain Dijits work in a more complicated fashion and do not replace child nodes of the element where they're defined, but wrap them instead. However, each Dijit has support for template HTML which will be inserted, with variable substitutions whenever that Dijit is put in the page. This is a very powerful feature, since when you start creating your own widgets, you will have an excellent system in place already which constrains where things will be put and how they are called. This means that when you finish your super-complicated graph drawing widget and your client or boss wants three more just like it on the same page, you just slap up three more tags which have the dojoType defining your widget. How do I find my widget? You already know that you can use dojo.byId('foo') as a shorter version of document.getElementById('foo'). If you still think that dojo.byId is too long, you can create a shorthand function like this: var $ = dojo.byId; And then use $('foo') instead of dojo.byId for simple DOM node lookup. But Dijits also seem to have an id. Are those the same as the ids of the DOM node they reside in or what? Well, the answer is both yes and no. All created Dijit widgets have a unique id. That id can be the same string as the id that defines the DOM node where they're created, but it doesn't have to be. Suppose that you create a Dijit like this: <div id='foo' dojoType='dijit._Calendar'></div> The created Dijit will have the same Dijit id as the id of the DOM node it was created in, because no others were given. But can you define another id for the widget than for its DOM node? Sure thing. There's a magic attribute called widgetId. So we could do the following: <div id='foo' dojoType='dijit._Calendar' widgetId='bar'></div> This would give the widget the id of 'bar'. But, really, what is the point? Why would we care the widget / Dijit has some kind of obscure id? All we really need is the DOM node, right? Not at all. Sure, you might want to reach out and do bad things to the DOM node of a widget, but that object will not be the widget and have none of its functions. If you want to grab hold of a widget instance after it is created, you need to know its widget id, so you can call the functions defined in the widget. So it's almost its entire reason to exist! So how do I get hold of a widget obejct now that I have its id? By using dijit.byId(). These two functions look pretty similar, so here is a clear and easy to find (when browsing the book) explanation: dojo.byId(): Returns the DOM node for the given id. dijit.byId(): Returns the widget object for the given widget id. Just one more thing. What happens if we create a widget and don't give either a DOM or widget id? Does the created widget still get an id? How do we get at it? Yes, the widget will get a generated id, if we write the following: <div dojoType='dijit._Calendar'></div> The widget will get a widget id like this: dijit__Calendar_0. The id will be the string of the file or namespace path down to the .js file which declares the widget, with / exchanged to _, and with a static widget counter attached to the end.
Read more
  • 0
  • 0
  • 3249

article-image-building-jsfejb3-applications
Packt
22 Oct 2009
15 min read
Save for later

Building JSF/EJB3 Applications

Packt
22 Oct 2009
15 min read
Building JSF/EJB3 Applications This practical article shows you how to create a simple data-driven application using JSF and EJB3 technologies. The article also shows you how to effectively use NetBeans IDE when building enterprise applications. What We Are Going to Build The sample application we are building throughout the article is very straightforward. It offers just a few pages. When you click the Ask us a question link on the welcomeJSF.jsp page, you will be taken to the following page, on which you can submit a question:     Once you’re done with your question, you click the Submit button. As a result, the application persist your question along with your email in the database. The next page will look like this:     The web tier of the application is build using the JavaServer Faces technology, while EJB is used to implement the database-related code. Software You Need to Follow the Article Exercise To build the sample discussed here, you will need the following software components installed on your computer: Java Standard Development Kit (JDK) 5.0 or higher Sun Java System Application Server Platform Edition 9 MySQL NetBeans IDE 5.5 Setting Up the Database The first step in building our application is to set up the database to interact with. In fact, you could choose any database you like to be the application’s backend database. For the purpose of this article, though, we will discuss how to use MySQL. To keep things simple, let’s create a questions table that contains just three columns, outlined in the following table: Column Type Description trackno INTEGER AUTO_INCREMENT PRIMARY KEY Stores a track number generated automatically when a row is inserted. user_email VARCHAR(50) NOT NULL   question VARCHAR(2000) NOT NULL   Of course, a real-world questions table would contain a few more columns, for example, dateOfSubmission containing the date and time of submitting the question. To create the questions table, you first have to create a database and grant the required privileges to the user with which you are going to connect to that database. For example, you might create database my_db and user usr identified by password pswd. To do this, you should issue the following SQL commands from MySQL Command Line Client:   CREATE DATABASE my_db; GRANT CREATE, DROP, SELECT, INSERT, UPDATE, DELETE ON my_db.* TO 'usr'@'localhost' IDENTIFIED BY 'pswd'; In order to use the newly created database for subsequent statements, you should issue the following statement:   USE my_db   Finally, create the questions table in the database as follows:   CREATE TABLE questions(      trackno INTEGER AUTO_INCREMENT PRIMARY KEY,      user_email VARCHAR(50) NOT NULL,      question  VARCHAR(2000) NOT NULL ) ENGINE = InnoDB;     Once you’re done, you have the database with the questions table required to store incoming users’ questions. Setting Up a Data Source for Your MySQL Database Since the application we are going to build will interact with MySQL, you need to have installed an appropriate MySQL driver on your application server. For example, you might want to install MySQL Connector/J, which is the official JDBC driver for MySQL. You can pick up this software from the "downloads" page of the MySQL AB website at http://mysql.org/downloads/. Install the driver on your GlassFish application server as follows: Unpack the downloaded archive containing the driver to any directory on your machine Add mysql-connector-java-xxx-bin.jar to the CLASSPATH environment variable Make sure that your GlassFish application server is up and running Launch the Application Server Admin Console by pointing your browser at http://localhost:4848/ Within the Common Tasks frame, find and double-click the ResourcesJDBCNew Connection Pool node On the New Connection Pool page, click the New… button The first step of the New Connection Pool master, set the fields as shown in the following table: Setting Value Name jdbc/mysqlPool Resource type javax.sql.DataSource Database Vendor mysql   Click Next to move on to the second page of the master On the second page of New Connection Pool, set the properties to reflect your database settings, like that shown in the following table: Name Value databaseName my_db serverName localhost port 3306 user usr password pswd   Once you are done with setting the properties, click Finish. The newly created jdbc/mysqlPool connection pool should appear on the list. To check it, you should click its link to open it in a window, and then click the Ping button. If everything is okay, you should see a message telling you Ping succeeded Creating the Project The next step is to create an application project with NetBeans. To do this, follow the steps below: Choose File/New project and then choose the EnterpriseEnterprise Application template for the project. Click Next On the Name and Location page of the master, specify the name for the project: JSF_EJB_App. Also make sure that Create EJB Module and Create Web Application Module are checked. And click Finish As a result, NetBeans generates a new enterprise application in a standard project, containing actually two projects: an EJB module project and Web application project. In this particular example, you will use the first project for EJBs and the second one for JSF pages. Creating Entity Beans and Persistent Unit You create entity beans and the persistent unit in the EJB module project—in this example this is the JSF_EJB_App-ejb project. In fact, the sample discussed here will contain the only entity bean: Question. You might automatically generate it and then edit as needed. To generate it with NetBeans, follow the steps below: Make sure that your Sun Java System Application Server is up and running In the Project window, right click JSF_EJB_App-ejb project, and then choose New/Entity Classes From Database. As a result, you’ll be prompted to connect to your Sun Java System Application Server. Do it by entering appropriate credentials. In the New Entity Classes from Database window, select jdbc/mysqlPool from the Data Source combobox. If you recall from the Setting up a Data Source for your MySQL database section discussed earlier in this article, jdbc/mysqlPool is a JDBC connection pool created on your application server In the Connect dialog appeared, you’ll be prompted to connect to your MySQL database. Enter password pswd, set the Remember password during this session checkbox, and then click OK In the Available Tables listbox, choose questions, and click Add button to move it to the Selected Tables listbox. After that, click Next On the next page of the New Entity Classes from Database master, fill up the Package field. For example, you might choose the following name: myappejb.entities. And change the class name from Questions to Question in the Class Names box. Next, click the Create Persistent Unit button In the Create Persistent Unit window, just click the Create button, leaving default values of the fields In the New Entity Classes from Database dialog, click Finish As a result, NetBeans will generate the Question entity class, which you should edit so that the resultant class looks like the following:   package myappejb.entities; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "questions") public class Question implements Serializable { @Id @Column(name = "trackno") private Integer trackno; @Column(name = "user_email", nullable = false) private String userEmail; @Column(name = "question", nullable = false) private String question; public Question() { } public Integer getTrackno() { return this.trackno; } public void setTrackno(Integer trackno) { this.trackno = trackno; } public String getUserEmail() { return this.userEmail; } public void setUserEmail(String userEmail) { this.userEmail = userEmail; } public String getQuestion() { return this.question; } public void setQuestion(String question) { this.question = question; } }     Once you’re done, make sure to save all the changes made by choosing File/Save All. Having the above code in hand, you might of course do without first generating the Question entity from the database, but simply create an empty Java file in the myappejb.entities package, and then insert the above code there. Then you could separately create the persistent unit. However, the idea behind building the Question entity with the master here is to show how you can quickly get a required piece of code to be then edited as needed, rather than creating it from scratch. Creating Session Beans To finish with the JSF_EJB_App-ejb project, let’s proceed to creating the session bean that will be used by the web tier. In particular, you need to create the QuestionSessionBean session bean that will be responsible for persisting the data a user enters on the askquestion page. To generate the bean’s frame with a master, follow the steps below: In the Project window, right click JSF_EJB_App-ejb project, and then choose New/Session Bean In the New Session Bean window, enter EJB name: QuestionSessionBean. Then specify the package: myappejb.ejb. Make sure that the Session Type is set to Stateless and Create Interface is set to Remote. Click Finish As a result, NetBeans should generate two Java files: QuestionSessionBean.java and QuestionSessionRemote.java. You should modify QuestionSessionBean.java so that it contains the following code:   package myappejb.ejb; import javax.annotation.Resource; import javax.ejb.Stateless; import javax.ejb.TransactionManagement; import javax.ejb.TransactionManagementType; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; import javax.transaction.UserTransaction; import myappejb.entities.Question; @Stateless <b>@TransactionManagement(TransactionManagementType.BEAN)</b> public class QuestionSessionBean implements myappejb.ejb.QuestionSessionRemote { /** Creates a new instance of QuestionSessionBean */ public QuestionSessionBean() { } @Resource private UserTransaction utx; @PersistenceUnit(unitName = "JSF_EJB_App-ejbPU") private EntityManagerFactory emf; private EntityManager getEntityManager() { return emf.createEntityManager(); } public void save(Question question) throws Exception { EntityManager em = getEntityManager(); try { utx.begin(); em.joinTransaction(); em.persist(question); utx.commit(); } catch (Exception ex) { try { utx.rollback(); throw new Exception(ex.getLocalizedMessage()); } catch (Exception e) { throw new Exception(e.getLocalizedMessage()); } } finally { em.close(); } } }   Next, modify the QuestionSessionRemote.java so that it looks like this:   package myappejb.ejb; import javax.ejb.Remote; import myappejb.entities.Question; @Remote public interface QuestionSessionRemote { void save(Question question) throws Exception; }   Choose File/Save All to save the changes made. That’s it. You just finished with your EJB module project. Adding JSF Framework to the Project Now that you have the entity and session beans created, let’s switch to the JSF_EJB_App-war project, where you’re building the web tier for the application.Before you can proceed to building JSF pages, you need to add the JavaServer Faces framework to the JSF_EJB_App-war project. To do this, follow the steps below: In the Project window, right click JSF_EJB_App-war project, and then choose Properties In the Project Properties window, select Frameworks from Categories, and click Add button. As a result, the Add a Framework dialog should appear In the Add a Framework dialog, choose JavaServer Faces and click OK Then click OK in the Project Properties dialog As a result, NetBeans adds the JavaServer Faces framework to the JSF_EJB_App-war project. Now if you extend the Configuration Files folder under the JSF_EJB_App-war project node in the Project window, you should see, among other configuration files, faces-config.xml there. Also notice the appearance of the welcomeJSF.jsp page in the Web Pages folder Creating JSF Managed Beans The next step is to create managed beans whose methods will be called from within the JSF pages. In this particular example, you need to create only one such bean: let’s call it QuestionController. This can be achieved by following the steps below: In the Project window, right click JSF_EJB_App-war project, and then choose New/Empty Java File In the New Empty Java File window, enter QuestionController as the class name and enter myappjsf.jsf in the Package field. Then, click Finish In the generated empty java file, insert the following code:   package myappjsf.jsf; import javax.ejb.EJB; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import myappejb.entities.Question; import myappejb.ejb.QuestionSessionBean; public class QuestionController { @EJB private QuestionSessionBean sbean; private Question question; public QuestionController() { } public Question getQuestion() { return question; } public void setQuestion(Question question) { this.question = question; } public String createSetup() { this.question = new Question(); this.question.setTrackno(null); return "question_create"; } public String create() { try { Integer trck = sbean.save(question); addSuccessMessage("Your question was successfully submitted."); } catch (Exception ex) { addErrorMessage(ex.getLocalizedMessage()); } return "created"; } public static void addErrorMessage(String msg) { FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg); FacesContext fc = FacesContext.getCurrentInstance(); fc.addMessage(null, facesMsg); } public static void addSuccessMessage(String msg) { FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg); FacesContext fc = FacesContext.getCurrentInstance(); fc.addMessage("successInfo", facesMsg); } }   Next, you need to add information about the newly created JSF managed bean to the faces-config.xml configuration file automatically generated when adding the JSF framework to the project. Find this file in the following folder: JSF_EJB_App-warWeb PagesWEB-INF in the Project window, and then insert the following tag between the and tags:   <managed-bean> <managed-bean-name>questionJSFBean</managed-bean-name> <managed-bean-class>myappjsf.jsf.QuestionController</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>   Finally, make sure to choose File/Save All to save the changes made in faces-config.xml as well as in QuestionController.java. Creating JSF Pages To keep things simple, you create just one more JSF page: askquestion.jsp, where a user can submit a question. First, though, let’s modify the welcomeJSF.jsp page so that you can use it to move on to askquestion.jsp and then return to, once a question has been submitted. To achieve this, modify welcomeJSF.jsp as follows:   <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <f:view> <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/> <h:form> <h1><h:outputText value="Ask us a question" /></h1> <h:commandLink action="#{questionJSFBean.createSetup}" value="New question"/> <br> </h:form> </f:view> </body> </html> Now you can move on and create askquestion.jsp. To do this, follow the steps below: In the Project window, right click JSF_EJB_App-war project, and then choose New/JSP In the New JSP File window, enter askquestion as the name for the page, and click Finish Modify the newly created askquestion.jsp so that it finally looks like this:   <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <html>     <head>         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />         <title>New Question</title>     </head>     <body>         <f:view>             <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>             <h1>Your question, please!</h1>             <h:form>                 <h:panelGrid columns="2">                     <h:outputText value="Your Email:"/>                     <h:inputText id="userEmail" value= "#{questionJSFBean.question.userEmail}" title="Your Email" />                     <h:outputText value="Your Question:"/>                     <h:inputTextarea id="question" value= "#{questionJSFBean.question.question}"  title="Your Question" rows ="5" cols="35" />                 </h:panelGrid>                 <h:commandLink action="#{questionJSFBean.create}" value="Create"/>                 <br>                 <a href="/JSF_EJB_App-war/index.jsp">Back to index</a>             </h:form>         </f:view>     </body> </html>   The next step is to set page navigation. Turning back to the faces-config.xml configuration file, insert the following code there.   <navigation-rule> <navigation-case> <from-outcome>question_create</from-outcome> <to-view-id>/askquestion.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <navigation-case> <from-outcome>created</from-outcome> <to-view-id>/welcomeJSF.jsp</to-view-id> </navigation-case> </navigation-rule> Make sure that the above tags are within the <faces-config> and </faces-config> root tags. Check It You are ready now to check the application you just created. To do this, right-click JSF_EJB_App-ejb project in the Project window and choose Deploy Project. After the JSF_EJB_App-ejb project is successfully deployed, right click the JSF_EJB_App-war project and choose Run Project. As a result, the newly created application will run in a browser. As mentioned earlier, the application contains very few pages, actually three ones. For testing purposes, you can submit a question, and then check the questions database table to make sure that everything went as planned. Summary Both JSF and EJB 3 are popular technologies when it comes to building enterprise applications. This simple example illustrates how you can use these technologies together in a complementary way.
Read more
  • 0
  • 0
  • 3251

article-image-oracle-web-rowset-part1
Packt
22 Oct 2009
6 min read
Save for later

Oracle Web RowSet - Part1

Packt
22 Oct 2009
6 min read
The ResultSet interface requires a persistent connection with a database to invoke the insert, update, and delete row operations on the database table data. The RowSet interface extends the ResultSet interface and is a container for tabular data that may operate without being connected to the data source. Thus, the RowSet interface reduces the overhead of a persistent connection with the database. In J2SE 5.0, five new implementations of RowSet—JdbcRowSet, CachedRowSet, WebRowSet, FilteredRowSet, and JoinRowSet—were introduced. The WebRowSet interface extends the RowSet interface and is the XML document representation of a RowSet object. A WebRowSet object represents a set of fetched database table rows, which may be modified without being connected to the database. Support for Oracle Web RowSet is a new feature in Oracle Database 10g driver. Oracle Web RowSet precludes the requirement for a persistent connection with the database. A connection is required only for retrieving data from the database with a SELECT query and for updating data in the database after all the required row operations on the retrieved data has been performed. Oracle Web RowSet is used for queries and modifications on the data retrieved from the database. Oracle Web RowSet, as an XML document representation of a RowSet facilitates the transfer of data. In Oracle Database 10g and 11g JDBC drivers, Oracle Web RowSet is implemented in the oracle.jdbc.rowset package. The OracleWebRowSet class represents a Oracle Web RowSet. The data in the Web RowSet may be modified without connecting to the database. The database table may be updated with the OracleWebRowSet class after the modifications to the Web RowSet have been made. A database JDBC connection is required only for retrieving data from the database and for updating the database. An XML document representation of the data in a Web RowSet may be obtained for data exchange. In this article, the Web RowSet feature in Oracle 10g database JDBC driver is implemented in JDeveloper 10g. An example Web RowSet will be created from a database. The Web RowSet will be modified and stored in the database table. In this article, we will learn the following: Creating a Oracle Web RowSet object Adding a row to Oracle Web RowSet Modifying the database table with Web RowSet In the second half of the article, we will cover the following : Reading a row from Oracle Web RowSet Updating a row in Oracle Web RowSet Deleting a row from Oracle Web RowSet Updating Database Table with modified Oracle Web RowSet Setting the Environment We will use Oracle database to generate an updatable OracleWebRowSet object. Therefore, install Oracle database 10g including the sample schemas. Connect to the database with the OE schema: SQL> CONNECT OE/<password> Create an example database table, Catalog, with the following SQL script: CREATE TABLE OE.Catalog(Journal VARCHAR(25), Publisher Varchar(25),Edition VARCHAR(25), Title Varchar(45), Author Varchar(25));INSERT INTO OE.Catalog VALUES('Oracle Magazine', 'OraclePublishing', 'July-August 2005', 'Tuning Undo Tablespace','Kimberly Floss');INSERT INTO OE.Catalog VALUES('Oracle Magazine', 'OraclePublishing', 'March-April 2005', 'Starting with Oracle ADF', 'SteveMuench'); Configure JDeveloper 10g for Web RowSet implementation. Create a project in JDeveloper. Select File | New | General | Application. In the Create Application window specify an Application Name and click on Next. In the Create Project window, specify a Project Name and click on Next. A project is added in the Applications Navigator. Next, we will set the project libraries. Select Tools | ProjectProperties and in the Project Properties window, select Libraries | Add Library to add a library. Add the Oracle JDBC library to project libraries. If the Oracle JDBC drivers version prior to the Oracle database 10g (R2) JDBC drivers version is used, create a library from the Oracle Web RowSet implementation classes JAR file: C:JDeveloper10.1.3jdbclibocrs12.jar. The ocrs12.jar is required only for JDBC drivers prior to Oracle database 10g (R2) JDBC drivers. In Oracle database 10g (R2) JDBC drivers OracleRowSet implementation classes are packaged in the ojdbc14.jar. In Oracle database 11g JDBC drivers Oracle RowSet implementation classes are packaged in ojdbc5.jar and ojdbc6.jar. In the Add Library window select the User node and click on New. In the Create Library window specify a Library Name, select the Class Path node and click on Add Entry. Add an entry for ocrs12.jar. As Web RowSet was introduced in J2SE 5.0, if J2SE 1.4 is being used we also need to add an entry for the RowSet implementations JAR file, rowset.jar. Download the JDBC RowSet Implementations 1.0.1 zip file, jdbc_rowset_tiger-1_0_1-mrel-ri.zip, from http://java.sun.com/products/jdbc/download.html#rowset1_0_1 and extract the JDBC RowSet zip file to a directory. Click on OK in the Create Library window. Click on OK in the Add Library window. A library for the Web RowSet application is added. Now configure an OC4J data source. Select Tools | Embedded OC4J Server Preferences. A data source may be configured globally or for the current workspace. If a global data source is created using Global | Data Sources, the data source is configured in the C:JDeveloper10.1.3jdevsystemoracle.j2ee.10.1.3.36.73embedded-oc4jconfig data-sources.xml file. If a data source is configured for the current workspace using Current Workspace | Data Sources, the data source is configured in the data-sources.xml file. For example, the data source file for the WebRowSetApp application is WebRowSetApp-data-sources.xml. In the Embedded OC4J Server Preferences window configure either a global data source or a data source in the current workspace. A global data source definition is available to all applications deployed in the OC4J server instance. A managed-data-source element is added to the data-sources.xml file. <managed-data-source name='OracleDataSource' connection-pool-name='Oracle Connection Pool' jndi-name='jdbc/OracleDataSource'/><connection-pool name='Oracle Connection Pool'><connection-factory factory-class='oracle.jdbc.pool.OracleDataSource' user='OE' password='pw'url="jdbc:oracle:thin:@localhost:1521:ORCL"></connection-factory></connection-pool> Add a JSP, GenerateWebRowSet.jsp, to the WebRowSet project. Select File | New | Web Tier | JSP | JSP. Click on OK. Select J2EE 1.3 or J2EE 1.4 in the Web Application window and click on Next. In the JSP File window specify a File Name and click on Next. Select the default settings in the Error Page Options page and click on Next. Select the default settings in the Tag Librarieswindow and click on Next. Select the default options in the HTML Options window and click on Next. Click on Finish in the Finish window. Next, configure the web.xml deployment descriptor to include a reference to the data source resource configured in the data-sources.xml file as shown in following listing: <resource-ref><res-ref-name>jdbc/OracleDataSource</res-ref-name><res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth></resource-ref>
Read more
  • 0
  • 0
  • 2372
article-image-debugging-ajax-using-microsoft-ajax-library-internet-explorer-and-mozilla-firefox
Packt
22 Oct 2009
8 min read
Save for later

Debugging AJAX using Microsoft AJAX Library, Internet Explorer and Mozilla Firefox

Packt
22 Oct 2009
8 min read
AJAX Debugging Overview Unfortunately, today’s tools for client-side debugging and tracing aren’t as evolved as their server-side counterparts. For example, things such as capturing ongoing communication traffic between the client and the server, or client-side debugging, aren’t usually supported by today’s IDEs (Integrated Development Environments) such as Microsoft Visual Studio 2005. The next version of Visual Studio (code-named Orcas at the time of writing) promises a lot of improvements in this area: Improved IntelliSense technology with support for JavaScript code, which provides coding hints based on specially-formatted comments in the code Breakpoints in inline JavaScript code These are only the most important new coming features; there are others as well. For more information we suggest that you browse and keep an eye on Scott Guthrie’s blog at http://weblogs.asp.net/scottgu/, the JScript blog at http://blogs.msdn.com/jscript/, Bertrand Le Roy’s blog at http://weblogs.asp.net/bleroy/. Until this new edition of Visual Studio is released, we can rely on third-party tools that can do a very good job at helping us develop our AJAX applications. You’ll find a number of tools for Internet Explorer and Mozilla Firefox for this purpose. Debugging and Tracing with Microsoft AJAX Library The common practices for debugging JavaScript code are: Putting alert messages throughout the code to get notified about the values of the variables Logging tracing messages in a <div> element While the first option is straightforward, the second option offers a centralized place for storing different messages and could be considered more appropriate. Nevertheless both options can come in quite handy depending on the circumstances. Microsoft AJAX Library offers the Sys.Debug object that has a series of methods that you can use for debugging and tracing. The diagram of this class is presented in figure below. The Debug class As we can easily see in the diagram, Sys.Debug offers the most common features that we can find also in other languages: assert(), trace(), traceDump(), fail(), and clearTrace(). assert(), trace(), and fail() automatically send the messages to the debugging console of the browser. To see the messages in IE you need to have the Web Development Helper, and for Firefox you need the Firebug plugin. Both of these tools are presented later in this article. Internally assert() calls fail() if the expression evaluates to false. fail() simply logs the message passed in by assert to the debugging console. trace() offers an interesting feature beside logging to the debugging console: it offers the possibility to log the trace message in a <textarea> element with the ID TraceConsole. If such an element is found, trace() will log this message in this element too. The clearTrace() function simply clears the TraceConsole element, if found. The traceDump() function traces all the information about an object including its properties. Internally this function uses the trace() function so that we can have the information logged in the browser’s debugging console, and in the TraceConsole element (if it exists). MicrosoftAjax.debug.js You might have wondered why the Microsoft AJAX Library comes with both release and debug version of the JavaScript file. The major features of the debug version of the library files are:  The script is nicely formatted. The names of variables are not obfuscated. The script contains code comments. Some of the functions have the optional summary data that will be used by Visual Studio “Orcas” for code auto-completion. The script outputs debugging-friendly information. Parameters are validated. Once the development stage is finished, you can switch your application to the release version of the script (MicrosoftAjax.js), which is smaller and doesn’t contain the debugging features presented above. Perhaps the most interesting features of the debug version are the last two: debugging-friendly information and parameter validation. Anonymous Functions vs. Pseudo-Named Functions We will explain these two concepts by taking a look at how different functions are defined in the debug and release version of the library. The debug version of the library contains: function Sys$_Debug$assert(condition, message, displayCaller) {   ...}Sys._Debug.prototype = {  assert: Sys$_Debug$assert,  ...} and: String.format = function String$format(format, args) {...} In the release version of the library we have: Sys._Debug.prototype = {  assert: function(c, a, b) {  ...} and: String.format = function() {...} In the release version, we have methods that are anonymous functions. This means that within a debugger stack trace the method name will read JScript anonymous function. This is not very useful for debugging purposes, is it? Call Stack showing anonymous functions However, the debug version of the library uses the dollar-syntax to provide alias names for our functions: String$format for String.format and Sys$Debug$assert for Sys.Debug.assert. When using the debug version of the file, the stack trace would look like: Call Stack showing named functions We can still notice some anonymous functions as they are the result of creating callback or delegate functions. The example shows two different ways of coding:  In the debug version, the function is declared outside the prototype and then referenced in the prototype declaration. In the release version, the declaration is done directly where the function is declared (outside or inside the prototype). Parameters Validation Another interesting feature that has not been documented in the Microsoft AJAX Library documentation is that of parameters validation. Type safety is one of the typical problems when it comes to using JavaScript. Although the dynamic type features are really useful, sometimes we might really want to make sure that a parameter or object is of a certain type. To check the data type of an object, you can try converting the object to the desired type, or using the methods defined by Type. Fortunately the Microsoft AJAX Library has a function that does the dirty work for us: Function._validateParams(). The class diagram in figure below shows the _validateParameter() and _validateParams() methods of the Function class. The Function class The Function._validateParams() function, even if it is declared as private (by convention, using the leading underscore), can be used by our scripts as it is used throughout the debug version of the Microsoft AJAX Library. Here’s an example of using this function: function Sys$_Debug$fail(message) {/// <param name="message" type="String" mayBeNull="true"></param>   var e = Function._validateParams(arguments,          [ {name: "message", type: String, mayBeNull: true} ]);   if (e) throw e; This shows how the parameter for the fail() function is validated as a String. We can also see the additional code comments inside the function, which are meant to be used by the IntelliSense feature in Visual Studio “Orcas” to check for the correctness of the parameter types. While the first parameter of _validateParams() represents an array of parameters to be checked, the second parameter is an array of JSON objects describing the validation rules for the array of parameters. Each JSON object contains a validation rule for a parameter. The JSON object is a dictionary of keys and values. The list of keys that can be used is described in the table that follows. Key Description name The name of the parameter type The allowed type for this parameter (ex: String, Array, Function, Sys.Component, etc.) mayBeNull Boolean value indicating whether this parameter can be passed as null or not domElement Boolean value indicating whether this parameter is a DOM element or not integer Boolean value indicating whether this parameter should have an integer value or not optional Boolean value indicating whether this parameter is optional or not parameterArray Boolean value indicating whether this parameter should be an Array or not elementType The allowed type for each element of an array (type must be Array) elementMayBeNull Boolean value indicating whether an array element could have null or not (type must be Array) elementDomElement Boolean value indicating whether each element of an array is a DOM element (type must be Array) elementInteger Boolean value indicating whether each element of an array should have an integer value (type must be Array) The function returns an error message if the parameters don’t validate and the error is typically thrown like this: if (e) throw e; This exception could be caught and the appropriate measures taken programmatically. If the exception is not caught, the error will pop up in the debugging console of the browser.
Read more
  • 0
  • 0
  • 3121

article-image-php-data-objects-error-handling
Packt
22 Oct 2009
11 min read
Save for later

PHP Data Objects: Error Handling

Packt
22 Oct 2009
11 min read
In this article, we will extend our application so that we can edit existing records as well as add new records. As we will deal with user input supplied via web forms, we have to take care of its validation. Also, we may add error handling so that we can react to non-standard situations and present the user with a friendly message. Before we proceed, let's briefly examine the sources of errors mentioned above and see what error handling strategy should be applied in each case. Our error handling strategy will use exceptions, so you should be familiar with them. If you are not, you can refer to Appendix A, which will introduce you to the new object-oriented features of PHP5. We have consciously chosen to use exceptions, even though PDO can be instructed not to use them, because there is one situation where they cannot be avoided. The PDO constructors always throw an exception when the database object cannot be created, so we may as well use exceptions as our main error‑trapping method throughout the code. Sources of Errors To create an error handling strategy, we should first analyze where errors can happen. Errors can happen on every call to the database, and although this is rather unlikely, we will look at this scenario. But before doing so, let's check each of the possible error sources and define a strategy for dealing with them. This can happen on a really busy server, which cannot handle any more incoming connections. For example, there may be a lengthy update running in the background. The outcome is that we are unable to get any data from the database, so we should do the following. If the PDO constructor fails, we present a page displaying a message, which says that the user's request could not be fulfilled at this time and that they should try again later. Of course, we should also log this error because it may require immediate attention. (A good idea would be emailing the database administrator about the error.) The problem with this error is that, while it usually manifests itself before a connection is established with the database (in a call to PDO constructor), there is a small risk that it can happen after the connection has been established (on a call to a method of the PDO or PDO Statement object when the database server is being shutdown). In this case, our reaction will be the same—present the user with an error message asking them to try again later. Improper Configuration of the Application This error can only occur when we move the application across servers where database access details differ; this may be when we are uploading from a development server to production server, where database setups differ. This is not an error that can happen during normal execution of the application, but care should be taken while uploading as this may interrupt the site's operation. If this error occurs, we can display another error message like: "This site is under maintenance". In this scenario, the site maintainer should react immediately, as without correcting, the connection string the application cannot normally operate. Improper Validation of User Input This is an error which is closely related to SQL injection vulnerability. Every developer of database-driven applications must undertake proper measures to validate and filter all user inputs. This error may lead to two major consequences: Either the query will fail due to malformed SQL (so that nothing particularly bad happens), or an SQL injection may occur and application security may be compromised. While their consequences differ, both these problems can be prevented in the same way. Let's consider the following scenario. We accept some numeric value from a form and insert it into the database. To keep our example simple, assume that we want to update a book's year of publication. To achieve this, we can create a form that has two fields: A hidden field containing the book's ID, and a text field to enter the year. We will skip implementation details here, and see how using a poorly designed script to process this form could lead to errors and put the whole system at risk. The form processing script will examine two request variables:$_REQUEST['book'], which holds the book's ID and $_REQUEST['year'], which holds the year of publication. If there is no validation of these values, the final code will look similar to this: $book = $_REQUEST['book'];$year = $_REQUEST['year'];$sql = "UPDATE books SET year=$year WHERE id=$book";$conn->query($sql); Let's see what happens if the user leaves the book field empty. The final SQL would then look like: UPDATE books SET year= WHERE id=1; This SQL is malformed and will lead to a syntax error. Therefore, we should ensure that both variables are holding numeric values. If they don't, we should redisplay the form with an error message. Now, let's see how an attacker might exploit this to delete the contents of the entire table. To achieve this, they could just enter the following into the year field: 2007; DELETE FROM books; This turns a single query into three queries: UPDATE books SET year=2007; DELETE FROM books; WHERE book=1; Of course, the third query is malformed, but the first and second will execute, and the database server will report an error. To counter this problem, we could use simple validation to ensure that the year field contains four digits. However, if we have text fields, which can contain arbitrary characters, the field's values must be escaped prior to creating the SQL. Inserting a Record with a Duplicate Primary Key or Unique Index Value This problem may happen when the application is inserting a record with duplicate values for the primary key or a unique index. For example, in our database of authors and books, we might want to prevent the user from entering the same book twice by mistake. To do this, we can create a unique index of the ISBN column of the books table. As every book has a unique ISBN, any attempt to insert the same ISBN will generate an error. We can trap this error and react accordingly, by displaying an error message asking the user to correct the ISBN or cancel its addition. Syntax Errors in SQL Statements This error may occur if we haven't properly tested the application. A good application must not contain these errors, and it is the responsibility of the development team to test every possible situation and check that every SQL statement performs without syntax errors. If this type of an error occurs, then we trap it with exceptions and display a fatal error message. The developers must correct the situation at once. Now that we have learned a bit about possible sources of errors, let's examine how PDO handles errors. Types of Error Handling in PDO By default, PDO uses the silent error handling mode. This means that any error that arises when calling methods of the PDO or PDOStatement classes go unreported. With this mode, one would have to call PDO::errorInfo(), PDO::errorCode(), PDOStatement::errorInfo(), or PDOStatement::errorCode(), every time an error occurred to see if it really did occur. Note that this mode is similar to traditional database access—usually, the code calls mysql_errno(),and mysql_error() (or equivalent functions for other database systems) after calling functions that could cause an error, after connecting to a database and after issuing a query. Another mode is the warning mode. Here, PDO will act identical to the traditional database access. Any error that happens during communication with the database would raise an E_WARNING error. Depending on the configuration, an error message could be displayed or logged into a file. Finally, PDO introduces a modern way of handling database connection errors—by using exceptions. Every failed call to any of the PDO or PDOStatement methods will throw an exception. As we have previously noted, PDO uses the silent mode, by default. To switch to a desired error handling mode, we have to specify it by calling PDO::setAttribute() method. Each of the error handling modes is specified by the following constants, which are defined in the PDO class: PDO::ERRMODE_SILENT – the silent strategy. PDO::ERRMODE_WARNING – the warning strategy. PDO::ERRMODE_EXCEPTION – use exceptions. To set the desired error handling mode, we have to set the PDO::ATTR_ERRMODE attribute in the following way: $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); To see how PDO throws an exception, edit the common.inc.php file by adding the above statement after the line #46. If you want to test what will happen when PDO throws an exception, change the connection string to specify a nonexistent database. Now point your browser to the books listing page. You should see an output similar to: This is PHP's default reaction to uncaught exceptions—they are regarded as fatal errors and program execution stops. The error message reveals the class of the exception, PDOException, the error description, and some debug information, including name and line number of the statement that threw the exception. Note that if you want to test SQLite, specifying a non-existent database may not work as the database will get created if it does not exist already. To see that it does work for SQLite, change the $connStr variable on line 10 so that there is an illegal character in the database name: $connStr = 'sqlite:/path/to/pdo*.db'; Refresh your browser and you should see something like this: As you can see, a message similar to the previous example is displayed, specifying the cause and the location of the error in the source code. Defining an Error Handling Function If we know that a certain statement or block of code can throw an exception, we should wrap that code within the try…catch block to prevent the default error message being displayed and present a user-friendly error page. But before we proceed, let's create a function that will render an error message and exit the application. As we will be calling it from different script files, the best place for this function is, of course, the common.inc.php file. Our function, called showError(), will do the following: Render a heading saying "Error". Render the error message. We will escape the text with the htmlspecialchars() function and process it with the nl2br() function so that we can display multi-line messages. (This function will convert all line break characters to tags.) Call the showFooter() function to close the opening and tags. The function will assume that the application has already called the showHeader() function. (Otherwise, we will end up with broken HTML.) We will also have to modify the block that creates the connection object in common.inc.php to catch the possible exception. With all these changes, the new version of common.inc.php will look like this: <?php/*** This is a common include file* PDO Library Management example application* @author Dennis Popel*/// DB connection string and username/password$connStr = 'mysql:host=localhost;dbname=pdo';$user = 'root';$pass = 'root';/*** This function will render the header on every page,* including the opening html tag,* the head section and the opening body tag.* It should be called before any output of the/*** This function will 'close' the body and html* tags opened by the showHeader() function*/function showFooter(){?></body></html><?php}/*** This function will display an error message, call the* showFooter() function and terminate the application* @param string $message the error message*/function showError($message){echo "<h2>Error</h2>";echo nl2br(htmlspecialchars($message));showFooter();exit();}// Create the connection objecttry{$conn = new PDO($connStr, $user, $pass);$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);}catch(PDOException $e){showHeader('Error');showError("Sorry, an error has occurred. Please try your requestlatern" . $e->getMessage());} As you can see, the newly created function is pretty straightforward. The more interesting part is the try…catch block that we use to trap the exception. Now with these modifications we can test how a real exception will get processed. To do that, make sure your connection string is wrong (so that it specifies wrong databasename for MySQL or contains invalid file name for SQLite). Point your browser to books.php and you should see the following window:
Read more
  • 0
  • 0
  • 6809

article-image-pop-image-widget-using-javascript-php-and-css
Packt
22 Oct 2009
7 min read
Save for later

Pop-up Image Widget using JavaScript, PHP and CSS

Packt
22 Oct 2009
7 min read
If you’re a regular blog reader then it’s likely that you’ve encountered the Recent Visitors widget form (http://mybloglog.com). This widget displays the profile like name, picture and sites authored by members of Mybloglog who have recently visited your blog. In the Mybloglog widget, when you move the mouse cursor to the member’s picture, you’ll see a popup displaying a brief description of that member. A glance at MyBlogLog widget The above image is of a MyBlogLog widget. As you can see in the right part of the widget, there is a list of the recent visitors to the blog from members of MyBlogLog. You may also have noticed that in the left part of the widget is a popup showing the details and an image of the visitor. This popup is displayed when the mouse is moved over the image on the widget. Now, let’s look at the code which we got from MyBlogLog to display the above widget. <script src="http://pub.mybloglog.com/comm3.php?mblID=2007121300465126&r= widget&is=small&o=l&ro=5&cs=black&ww=220&wc=multiple"></script> In the above script element, the language and type attributes are not specified. Although they are optional attributes in HTML - you must specify a value in the type attribute to make the above syntax valid in an XHTML web page. If you closely looked at the src attribute of the script element, you can see that the source page of the script is a .php file. You can use the JavaScript code with any file extension like .php , .asp, and so on , but whenever you use such a file in src attribute please note that the final output code of the file (after being parsed by server) should be a valid JavaScript code. Creating pop-up image widget This pop-up image widget is somewhat similar to MyBlogLog widget but it is a simplified version of that widget. This is a very simple widget with uses JavaScript, PHP and CSS. Here you’ll see four images in the widget and a pop-up image (corresponding to the chosen image) will be displayed when you move the mouse over it. After getting the core concept, you can extend the functionality to make this look fancier. Writing Code for Pop-up Image Widget As I’ve already discussed, this widget is going to contain PHP code, JavaScript and a little bit of CSS as well. For this, you need to write the code in a PHP file with the .php extension. First of all, declare the variables for storing the current mouse position and string variables for storing the string of the widget. var widget_posx=0;var widget_posy=0;var widget_html_css=''; The widget_posx variable is to hold the x co-ordinate values of the mouse position on the screen, whereas, the widget_posy variable will store the y co-ordinate. The widget_html_css variable stores the HTML and CSS elements which will be used later in the code. The (0,0) co-ordinate of the output devices like monitor is located at the top left position. So the mouse position 10,10 will be somewhere near the top left corner of monitor. After declaring the variables, let’s define an event handler to track the mouse position on the web page. document.onmousemove=captureMouse; As you can see above, we’ve called a function captureMouse() When the mouse is moved anywhere on the document (web page), the event handler which is the function captureMouse() is called on the onmousemove event. The Document object represents the entire HTML document and can be used to access and capture the events of all elements on a page. Each time a user moves the mouse one pixel, a mousemove event occurs. It engages system resources to process all mousemove events, hence, use this event carefully! Now, let’s look at the code of the captureMouse() function. function captureMouse(event){ if (!event){var event = window.event;}if (event.pageX || event.pageY) { widget_posx = event.pageX; widget_posy = event.pageY; } else if (event.clientX || event.clientY) { widget_posx = event.clientX; widget_posy = event.clientY; } } As you can see in the above function, the event variable is passed as a function parameter. This event variable is the JavaScript’s Event object. The Event object keeps track of various events that occur on the page, such as the user moving the mouse or clicking on the link, and allows you to react to them by writing code which is relevant to the event. if (!event){var event = window.event;} In the above code, the first line of the event handler ensures that if the browser doesn’t pass the event information to the above function, then we would obtain it from any explicit event registration of the window object. We can track different activity in the document by the event object with the help of its various defined properties. For example, if eventObj is the event object and we’ve to track whether the ctrl key is pressed (or not) - we can use the following code in JavaScript: eventObj.ctrlKey If we’ve assigned the x, y-position of mouse in the page using the pageX and pageY properties, we can also get the same mouse position of the mouse cursor using clientX and clientY property. Most browsers provide both pageX/pageY and clientX/clientY. Internet Explorer is the only current browser that provides clientX/clientY, but not pageX/pageY. To provide cross-browser support, we’ve used both pageX/pageY and clientX/clientY to get the mouse co-ordinates in the document, and assigned them to the widget_posx and widget_posy variables accordingly. Now, let’s look at widget_html_css variable, where we’re going to store the string which is going to be displayed in the widget. widget_html_css+='<style type="text/css">';widget_html_css+='.widgetImageCss';widget_html_css+='{ margin:2px;border:1px solid #CCCCCC;cursor:pointer}';widget_html_css+='</style>'; As you can see in the string of the above variable, we’ve added the style for the HTML element with the class name widgetImageCss within the style element. When applied, this class in the HTML adds a 2 pixel margins ‘brown color border’ to the element. Furthermore, the mouse cursor will be converted into pointer (a hand) which is defined with the cursor attribute in CSS. widget_html_css+='<div id="widget_popup"style="position:absolute;z-index:10; display:none">&nbsp;</div>'; Using the above code, we’re adding a division element with id widget_popup to the DOM. We’ve also added style to this element using inline styling. The position attribute of this element is set to absolute so that this element can move freely without disturbing the layout of the document. The z-index property is used for stacking the order of the element and in the above element it is set 10 so that this element will be displayed above all the other elements of the document. Finally, the display property is set to none for hiding the element at first. Afterwards, this element will be displayed with the pop-up image using JavaScript in the document. Elements can have negative stack orders i.e. you can set the z-index to -1 for an element. This will display it underneath the other elements on the page. Z-index only works on elements that have been positioned using CSS (such as position:absolute). Now, the PHP part of the codes comes in. We’ve used PHP to add the images to the widget_html_css string variables of JavaScript. We’ve used PHP in this part rather than using JavaScript for making this application flexible. JavaScript is a client side scripting language and can’t access the database or do any kind of server activity. Using PHP, you can extract and display the images from the database which might be the integral part of your desired widget.
Read more
  • 0
  • 0
  • 8547
article-image-creating-accessible-tables-joomla
Packt
22 Oct 2009
5 min read
Save for later

Creating Accessible Tables in Joomla!

Packt
22 Oct 2009
5 min read
Creating Accessible Tables Tables got a bad review in accessibility circles, because they used to create complex visual layouts. This was due to the limitations in the support for presentational specifications like CSS and using tables for layout was a hack—that worked in the real world—when you wanted to position something in a precise part of the web page. Tables were designed to present data of all shapes and sizes, and that is really what they should be used for. The Trouble with Tables So what are tables like for screen reader users? Tables often contain a lot of information, so sighted users need to look at the information at the top of the table (the header info), and sometimes the first column in each row to associate each data cell. Obviously this works for sighted users, but in order to make the tables accessible to a screen reader user we need to find a way of associating the data in each cell with its correct header so the screen reader can inform the user which header relates to each data cell. Screen reader users can navigate between data cells easily using the cursor keys. We will see how to make tables accessible in simple steps. There are methods of conveying the meaning and purpose of a table to the screen reader user by using the caption element and the summary attribute of the table element that you will find more on in the next section. We will learn how to build a simple table using Joomla! and the features contained within the WYSIWYG editors that can make the table more accessible. Before we do that though I want you to ask yourself about why you want to use tables (though sometimes it is unavoidable) and what forms should they take. Simple guidelines for tables: Try to make the table as simple as possible.    If possible don't span multiple cells etc. The simpler the table, the easier it is to make accessible.    Try to include the data you want to present in the body text of your site. Time for Action—Create an Accessible Table (Part 1) In the following example we will build a simple table that will list the names of some artists, some albums they have recorded, and the year in which they recorded the albums. First of all click the table icon from the TinyMCE interface and add a table with a suitable number of columns and rows.            By clicking on the Advanced tab you will see the Summary field. The summary information is very important. It provides the screen reader user a summary of the table. For example, I filled in the following text: "A list of some funk artists, my favorite among their records, and the year they recorded it in". My table then looked as follows: What Just Happened? There is still some work to be done in order to make the content more accessible. The controls that the WYSIWYG editor offers are also a little limited so we will have to edit the HTML by hand. Adding the summary information is a very good start. The text that I entered "A list of some funk artists, my favorite among their records, and the year they recorded it in." will be read out by the screen reader as soon as it receives a focus by the user. Time for Action—Create an Accessible Table (Part 2) Next we are going to add a Caption to the table, which will be helpful to both sighted and non-sighted users. This is how it's done. Firstly, select the top row of the table, as these items are the table heading. Then click on the Table Row properties icon beside the Tables icon and select Table Head under General Properties. Make sure that the Update current Row is selected in the dialogue box in the bottom left. You will apply these properties to your selected row. If you wish to add a caption to your table you need to add an extra row to the table and then select the contents of that row and add the Caption in the row properties dialogue box. This will tell the browser to display the caption text, in this case Funky Table Caption, else it will remain hidden. What Just Happened? By adding caption to the table, you provide useful information to the screen reader user. This caption should be informative and should describe something useful about the table. As the caption element is wrapped in a heading it is read out by the screen reader when the user starts exploring the table—so it is slightly different to the summary attribute, which is read out automatically. Does it Work? What we just did using the WYSIWYG editor, TinyMCE, is enough to make a good start towards creating a more accessible table, but we will have to work a little more in order to truly make the table accessible. So we will now edit the HTML. The good news is that you have made some good steps in the right direction and the final step is of associating the data cells with their suitable headers, as this is something that we cannot really do with the WYSIWYG editor alone, and is essential to make your tables truly accessible.
Read more
  • 0
  • 0
  • 2244

article-image-cherrypy-photoblog-application
Packt
22 Oct 2009
6 min read
Save for later

CherryPy : A Photoblog Application

Packt
22 Oct 2009
6 min read
A photoblog is like a regular blog except that the principal content is not text but photographs. The main reason for choosing a photoblog is that the range of features to be implemented is small enough so that we can concentrate on their design and implementation. The goals behind going through this application are as follows: To see how to slice the development of a web application into meaningful layers and therefore show that a web application is not very different from a rich application sitting on your desktop. To show that the separation of concerns can also be applied to the web interface itself by using principles grouped under the name of Ajax. To introduce common Python packages for dealing with common aspects of web development such as database access, HTML templating, JavaScript handling, etc. Photoblog Entities As mentioned earlier, the photoblog will try to stay as simple as possible in order to focus on the other aspects of developing a web application. In this section, we will briefly describe the entities our photoblog will manipulate as well as their attributes and relations with each other. In a nutshell our photoblog application will use the following entities and they will be associated as shown in the following figure: This figure is not what our application will look like but it shows the entities our application will manipulate. One photoblog will contain several albums, which in turn will host as many films as required, which will carry the photographs. In other words, we will design our application with the following entity structure: Entity: Photoblog Role: This entity will be the root of the application. Attributes: name: A unique identifier for the blog title: A public label for the blog Relations: One photoblog will have zero to many albums Entity: Album Role: An album carries a story told by the photographs as an envelope. Attributes: name: A unique identifier for the album title: A public label for the album author: The name of the album's author description: A simple description of the album used in feeds story: A story attached to the album created: A timestamp of when the album is being created modified: A timestamp of when the album is being modified blog_id: A reference to the blog handling the album Relations: One album will reference zero to several films Entity: Film Role: A film gathers a set of photographs. Attributes: name: A unique identifier for the film title: A public label for the film created: A timestamp of when the film is being created modified: A timestamp of when the film is being modified album_id: A reference to the album Relations: A film will reference zero to several photographs Entity: Photo Role: The unit of our application is a photograph. Attributes: name: A unique identifier for the photo legend: A legend associated with the photograph filename: The base name of the photograph on the hard-disk filesize: The size in bytes of the photograph width: Width of the photograph in pixels height: Height of the photograph in pixels created: A timestamp of when the photograph is being created modified: A timestamp of when the photograph is being modified film_id: A reference to the film carrying the photograph Relations: None Functionally, the photoblog application will provide APIs to manipulate those entities via the traditional CRUD interface: Create, Retrieve, Update, and Delete. Vocabulary Here is a list of the terms we will be using: Persistence: Persistence is the concept of data items outliving the execution of programs manipulating them. Simply put, it is the process of storing data in long lasting memory medium such as a disk. Database: A database is a collection of organized data. There are different organization models: hierarchical, network, relational, object-oriented, etc. A database holds the logical representation of its data. Database Management System (DBMS): A DBMS is a group of related software applications to manipulate data in a database. A DBMS platform should offer the following among other features: Persistence of the data A query language to manipulate data Concurrency control Security control Integrity control Transaction capabilities We will use DBMSes as the plural of DBMS. DBMSes Overview In this section, we will quickly review the different kinds of existing DBMSes. The goal is to quickly introduce their main characteristics. Relational Database Management System (RDBMS) Of all DBMSes, the RDBMS is the most common, whether it is in small applications or multi-national infrastructure. An RDBMS comes with a database based on the concepts of the relational model, a mathematical model that permits the logical representation of a collection of data through relations. A relational database should be a concrete implementation of the relational model. However, modern relational databases follow the model only to a certain degree. The following table shows the correlation between the terms of the relational model and the relational database implementation. Relational databases support a set of types to define the domain of scope a column can use. However, there are only a limited number of supported types, which can be an issue with complex data types as allowed in objected-oriented design. Structure Query Language more commonly known as SQL is the language used to define, manipulate, or control data within a relational database. The following table is a quick summary of SQL keywords and their contexts. A construction of these keywords is called an SQL statement. When executed, an SQL statement returns a collection of rows of the data matching the query or nothing. The relational model algebra uses the relation composition to compose operations across different sets; this is translated in the relational database context by joins. Joining tables allows complex queries to be shaped to filter out data. SQL provides the following three kinds of joins:   Union Type Description INNER JOIN Intersection between two tables. LEFT OUTER JOIN Limits the result set by the left table. So all results from the left table will be returned with their matching result in the right table. If no matching result is found, it will return a NULL value. RIGHT OUTER JOIN Same as the LEFT OUTER JOIN except that the tables are reversed.  
Read more
  • 0
  • 0
  • 1901
Modal Close icon
Modal Close icon