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

How-To Tutorials

7019 Articles
article-image-advanced-wordpress-themes
Packt
29 Jun 2010
14 min read
Save for later

Advanced WordPress Themes

Packt
29 Jun 2010
14 min read
(For more resources on Wordpress, see here.) Creating a basic WordPress theme is great. You learn about The Loop, find the appropriate template tags to display the information that you want, and then you write some HTML and CSS to tie it all together. However, there comes a time when you're ready to take your themes to the next level. That is what this article is all about. In this article, you'll learn how to provide your theme's users with options about what is displayed and how it is displayed. You'll also learn about localizing your theme for an international audience and showing users information based on their current role. Finally, this article covers the essentials for packaging and distributing your theme via the WordPress.org theme repository. You'll need to follow a few simple steps to make sure that your theme is accepted and that it provides users with the best possible experience. Adding a theme options page As a theme developer, you have to make a lot of choices when you create a theme. What text should be displayed in certain locations? Will that text always be appropriate? How many posts should you display in a featured item carousel? How many levels should the nested navigation menu have? Part of being a good developer is knowing when to make these decisions for your theme's users, and when to give the users a choice. Many WordPress users are not comfortable with editing PHP files, so you need to provide some other way for users to make these choices. The best way, in the context of a WordPress theme, is to provide the users with a theme options panel. Getting started You need to have created a WordPress theme containing at least a style.css file and an index.php file. How to do it... First, you need to decide what choice you want to give your users. In this recipe, we're going to assume that you want users to be able to change the color of the name of their site, which is located in the site header. Next, you have to create the options page that lets users make their choice and save it. Open your theme's directory and create a new directory inside it called admin. Inside the admin directory, create a file called options.php. Open the options.php file, and insert the following code: <?php$settings = $this->get_settings();?><div class="wrap"> <h2><?php _e('My Theme Options' ); ?></h2> <?php if('1'==$_GET['updated']) { ?> <div id="my-theme-options-updated" class="updated fade"><p><?php _e('Settings saved!' ); ?></p></div> <?php } ?> <form method="post"> <table class="form-table"> <tbody> <tr> <th scope="row"><label for="custom-theme-header-color"> <?php _e('Header Color'); ?></label></th> <td> #<input type="text" class="regular-text" name="custom-theme-header-color" id="custom-theme-header-color" value="<?php echo esc_attr( $settings[ 'header-color' ] ); ?>" /> </td> </tr> </tbody> </table> <p class="submit"> <?php wp_nonce_field( 'custom-theme-save-options' ); ?> <input type="submit" class="button-primary" name="custom-theme-save-options" id="custom-theme-save-options" value="<?php _e( 'Save' ); ?>" /> </p> </form></div> This file contains all of the code necessary for the theme options page. The next thing that you need to do is to hook the admin page into the WordPress administrative menu. Open or create your theme's functions.php file and insert the following code: if (!class_exists('My_Theme')) { class My_Theme { var $settings = null; function My_Theme() { add_action('admin_init', array(&$this, 'save_settings')); add_action('admin_menu', array(&$this, 'add_admin_stuff')); } function add_admin_stuff() { add_theme_page(__('My Theme'), __('My Theme'), 'switch_themes', 'my-theme', array(&$this, 'display_theme_admin_page')); } function display_theme_admin_page() { include (TEMPLATEPATH.'/admin/options.php'); } function save_settings() { if (isset($_POST['custom-theme-save-options']) &&check_admin_referer('custom-theme-save-options') && current_user_can('switch_themes')) { $settings = $this->get_settings(); $settings['header-color'] = stripslashes($_POST['custom-theme-header-color']); $this->set_settings($settings); wp_redirect(admin_url('themes.php?page=my-theme&updated=1')); } } function get_settings() { if (null === $this->settings) { $this->settings = get_option('My Theme CustomSettings', array()); } return $this->settings; } function set_settings($settings) { if (is_array($settings)) { $this->settings = $settings; update_option('My Theme Custom Settings', $this->settings); } } } $my_theme = new My_Theme(); function get_custom_theme_header_color() { global $my_theme; $settings = $my_theme->get_settings(); $color = $settings['header-color']; if(empty($color)) { $color = '000000'; } return $color; } function the_custom_theme_header_color() { echo get_custom_theme_header_color(); }} This file hooks into two different WordPress administrative hooks. First, you add the administrative menu page by hooking into admin_menu. Then, you hook to admin_init to process and save the custom options present on the custom admin page. After you save these files, go to your administrative menu and look at the sidebar on the left-hand side under the Appearance heading. You should see a My Theme link, as shown in the following screenshot: Now, click on the My Theme link under the Appearance menu heading. If you've done everything correctly, you should see a page that looks like the following screenshot: Enter a value such as 99000 and click on the Save button, and you'll see a Settings saved! success message, as seen in the following screenshot: Now, you need to use your custom value somewhere in your theme. Open up your theme header (usually header.php or index.php) and insert the following code between the opening and closing <head> tags: <h1 style="color:#<?php the_custom_theme_header_color(); ?>;"><?php bloginfo(); ?></h1> View your site in a browser to see the change in color of the site title (this is usually the only text that uses the <h1> tag) with the custom option set to hexadecimal color value 990000: Now, whatever value you set for the custom option that we created will be used as the color for the site title. How it works... There are quite a few moving parts here, so let's go through them one by one. First, you created the administrative page. This was saved to /yourthemefolder/admin/options.php. This file contains all of the items contained on a typical WordPress admin page: A containing <div> with the wrap class A <h2> tag with the custom theme options title A form that posts back to itself Form elements arranged inside a <table> with the form-table class With all of these elements in place, you get a slick looking administrative page that blends in with the rest of the WordPress admin control panel. Next, you created a small script within the functions.php file that hooks the administrative menu into place and saves the options when the page is posted. You hooked to admin_menu to add the administrative page and admin_init to save the options using the WordPress add_action() function that accepts a key value pair of the named action as a descriptive string and the actual action to take place. Your custom options are saved when three conditions are met: The form posts back to itself. The system verifies the security nonce from the form. The currently logged-in user has the ability to switch themes (usually just the blog administrator). The options are saved as an array to the WordPress options table by using the update_ option function. When you need to retrieve the options, you call get_option and pass the appropriate key. In addition to the hooks that provide the core functionality of this script, you created two template tags. The tag the_custom_theme_header_color() allowed you to access, and get_custom_theme_header_color() allowed you to print the values you stored on the custom options page. Finally, you used the template tags that you created to take advantage of your custom option on the front-end by adding <?php _the_custom_theme_header_color(); ?>; to the style of the <h1> tag that controls the color and size of the blog title. In this particular instance, you're allowing your theme's users to modify the color of the theme's header. However, endless possibilities exist as you become more familiar with WordPress, and by expanding the options, you allow your users to modify your themes. There's more… You can add additional theme option settings to customize how users can edit your theme. Diving into administrative settings for themes Visit the WordPress codex at http://codex.wordpress.org/Function_Reference to learn more about the functions available to you for creating custom theme edit forms in the administrative area of WordPress. Allowing for multiple theme color schemes In the previous recipe, we covered the general way in which you provide your theme's users with an options page. In this recipe, you'll implement one of the most straightforward features that many premium themes possess: a theme color scheme chooser. Getting started You need to have created a WordPress theme containing at least a style.css file and an index.php file. Inside the template file containing your theme's <head> tag, you need to call the wp_head function. How to do it... You're going to be controlling the color schemes that users can select, by putting each one in a different CSS file. As such, the first thing that you have to do is to create these files. Open your theme's directory and create a new directory named schemes. Inside the schemes directory, create the files blue.css, red.css, and green.css. They should contain the following styles: @charset "utf-8";/* Blue.CSS Color Schemes Document Chapter 11 Example 2 */body{ color:#00f; /* very bright medium blue*/ background-color:#99ccff; /* light blue*/}/* theme links*/a., a:link, a:hover, a:visited {}a., a:link{color:#000099;} /* medium dark blue*/a:hover{color: #0066FF;} /* bright medium blue*/a:visited{color:#000099;}/* blog title styles*/h1.blog-title, h1.blog-title a{ color:#000033; /* dark blue*/ text-decoration:none;}#header a { color: #000033; text-decoration: none;}#header a:hover { color: #0066FF; text-decoration: underline;}#header a:visited{color:#000099;}h2{ color:#003399; /* medium blue*/ text-decoration:none;} #header{ background:none; font-family:arial, verdana, sans-serif; }h2 a { color:#003399;/* medium blue */ text-decoration:none;}h3.storytitle, h3.storytitle a{ color:#003399; /* medium blue*/ text-decoration:none;} @charset "utf-8";/* Red.CSS Color Schemes Document Chapter 11 Example 2 */body{ color:#660000; /* dark red */ background-color:#ffffcc; /* light orange-pink*/}/* theme links*/a., a:link, a:hover, a:visited {}a., a:link{color:#ff0000;} /* bright red */a:hover{color: #ff0033} /* bright pink */a:visited{color:#ff0000;}/* blog title styles*/h1.blog-title, h1.blog-title a{ color:#ff3333; /* medium pink-red*/ text-decoration:none;}#header a { color: #ff3333; text-decoration: none;}#header a:hover { color: #ff0033; text-decoration: underline;}#header a:visited{color:#ff3333;}h2{ color:#660000; /* medium medium dull red*/ text-decoration:none;}h2 a { color:#660000; /* medium medium dull red*/ text-decoration:none;}h3.storytitle, h3.storytitle a{ color:#ff3333; /* medium pink-red*/ text-decoration:none;}@charset "utf-8";/* Green.CSS Color Schemes Document Chapter 11 Example 2 */body{ color:#009933; /* dull medium green*/ background-color:#005826; /* dull dark green */}/* theme links*/a., a:link, a:hover, a:visited {}a., a:link{color:#00ff00;} /* bright light neon green*/a:hover{color: #33ff00;} /* bright green*/a:visited{color:#00ff00;}/* blog title styles*/h1.blog-title, h1.blog-title a{ color:#99cc99; /* light pale green */ text-decoration:none;}h2{ color:#33cc66; /* medium green */ text-decoration:none;}h2 a { color:#33cc66; /* medium green*/ text-decoration:none;}h3.storytitle, h3.storytitle a{ color:#33cc66; /* medium green*/ text-decoration:none;} Next, you have to create the options page that lets users make their choice and save it. Open your theme's directory and create a new directory inside it called admin. Inside the admin directory, create a file called options.php. Open the options.php file, and insert the following code: <?php$settings = $this->get_settings();$custom_schemes = $this->get_custom_themes();?><div class="wrap"> <h2><?php _e('My Theme Options' ); ?></h2> <?php if('1'==$_GET['updated']) { ?> <div id="my-theme-options-updated" class="updated fade"> <p><?php _e( 'Settings saved!' ); ?></p></div> <?php } ?> <form method="post"> <table class="form-table"> <tbody> <tr> <th scope="row"><label for="custom-theme-header-color"> <?php _e('Custom Color Scheme'); ?></label></th> <td> <select name="custom-theme-color"> <option <?php selected( $settings[ 'color' ], '' ); ?> value=""><?php _e('None'); ?></option> <?php foreach( (array)$custom_schemes as $key => $name ) { ?> <option <?php selected( $settings[ 'color' ], $key ); ?> value="<?php echo esc_attr($key); ?>"><?php echo esc_html($name); ?></option> <?php } ?> </select> </td> </tr> </tbody> </table> <p class="submit"> <?php wp_nonce_field( 'custom-theme-save-options' ); ?> <input type="submit" class="button-primary" name="custom-theme-save-options" id="custom-theme-save-options" value="<?php _e( 'Save'); ?>" /> </p> </form></div> This file contains all of the code necessary for the theme options page. This particular options page contains a <select> drop-down menu that displays the available color schemes to the theme's user. The next thing that you need to do is to hook the admin page into the WordPress administrative menu. Open or create your themes functions.php file, and insert the following code: <?php if (!class_exists('My_Theme')) { class My_Theme { var $settings = null; function My_Theme() { add_action('admin_init', array(&$this, 'save_settings')); add_action('admin_menu', array(&$this, 'add_admin_stuff')); add_action('init', array(&$this, 'enqueue_color_css')); } function add_admin_stuff() { add_theme_page(__('My Theme'), __('My Theme'), 'switch_themes', 'my-theme', array(&$this, 'display_theme_admin_page')); } function display_theme_admin_page() { include (TEMPLATEPATH.'/admin/options.php'); } function enqueue_color_css() { $settings = $this->get_settings(); if( !empty( $settings['color'] ) && !is_admin() ) { wp_enqueue_style( 'custom-theme-color', get_bloginfo( 'stylesheet_directory' ) . '/schemes/' . $settings[ 'color' ] ); } } function get_custom_themes() { $schemes_dir = TEMPLATEPATH . '/schemes/'; $schemes = array(); if( is_dir($schemes_dir) && is_readable( $schemes_dir ) ) { $dir = opendir($schemes_dir); while(false !== ($file = readdir($dir))) { if('.' != $file && '..' != $file) { $scheme_name = ucwords(str_replace( array('-','_','.css'), array(' ',' ',''), $file)); $schemes[$file] = $scheme_name; } } } return $schemes; } function save_settings() { if (isset($_POST['custom-theme-save-options']) && check_admin_referer('custom-theme-save-options') && current_user_can('switch_themes')) { $settings = $this->get_settings(); $settings['color'] = stripslashes( $_POST['custom-theme-color']); $this->set_settings($settings); wp_redirect(admin_url('themes.php?page=my-theme&updated=1')); } } function get_settings() { if (null === $this->settings) { $this->settings = get_option( 'My Theme Custom Settings', array()); } return $this->settings; } function set_settings($settings) { if (is_array($settings)) { $this->settings = $settings; update_option('My Theme Custom Settings', $this->settings); } } } $my_theme = new My_Theme();} This file hooks into two different WordPress administrative hooks. First, you add the administrative menu page by hooking to admin_menu. Then, you hook to admin_init to process and save the custom options present on the custom admin page. Finally, you hook to the init hook to enqueue the custom CSS stylesheet the user has selected. After you save these files, go to your administrative menu and look at the sidebar on the left-hand side, under the Appearance heading. You should see a My Theme link, as shown in the following screenshot: Now, click on the My Theme link under the Appearance menu heading. If you've done everything correctly, you should see an administrative page that looks like the one shown in the following screenshot: Select a value, such as Red, from the drop-down selection menu, and then click on the Save button. You'll see the Settings saved! message, as well as the chosen color scheme selected in the Custom Color Scheme drop-down menu. Finally, you can view the results of the color scheme change by opening up your site in a browser window. In the following screenshot, you can see what the page header of each of the three color schemes will look like:
Read more
  • 0
  • 0
  • 1860

article-image-optimizing-your-mysql-servers-performance-using-indexes
Packt
29 Jun 2010
11 min read
Save for later

Optimizing your MySQL Servers' performance using Indexes

Packt
29 Jun 2010
11 min read
Introduction One of the most important features of relational database management systems—MySQL being no exception—is the use of indexes to allow rapid and efficient access to the enormous amounts of data they keep safe for us. In this article, we will provide some useful recipes for you to get the most out of your databases. Infinite storage, infinite expectations We have got accustomed to nearly infinite storage space at our disposal—storing everything from music to movies to high resolution medical imagery, detailed geographical information,or just plain old business data. While we take it for granted that we hardly ever run out of space, we also expect to be able to locate and retrieve every bit of information we save in an instant. There are examples everywhere in our lives—business and personal: Your pocket music player's library can easily contain tens of thousands of songs and yet can be browsed effortlessly by artist name or album title, or show you last week's top 10 rock songs. Search engines provide thousands of results in milliseconds for any arbitrary search term or combination. A line of business application can render your sales numbers charted and displayed on a map, grouped by sales district in real-time. These are a few simple examples, yet for each of them huge amounts of data must be combed to quickly provide just the right subset to satisfy each request. Even with the immense speed of modern hardware, this is not a trivial task to do and requires some clever techniques. Speed by redundancy Indexes are based on the principle that searching in sorted data sets is way faster than searching in unsorted collections of records. So when MySQL is told to create an index on one or more columns, it copies these columns' contents and stores them in a sorted manner. The remaining columns are replaced by a reference to the original table with the unsorted data. This combines two benefits—providing fast retrieval while maintaining reasonably efficient storage requirements. So, without wasting too much space this approach enables you to create several of those indexes (or indices, both are correct) at a relatively low cost. However, there is a drawback to this as well: while reading data, indexes allow for immense speeds, especially in large databases; however, they do slow down writing operations. In the course of INSERTs, UPDATEs, and DELETEs, all indexes need to be updated in addition to the data table itself. This can place significant additional load on the server, slowing down all operations. For this reason, keeping the number of indexes as low as possible is paramount, especially for the largest tables where they are most important. In this article, you'll find some recipes that will help you to decide how to define indexes and show you some pitfalls to avoid. Storage engine differences We will not go into much detail here about the differences between the MyISAM and the InnoDB storage engines offered by MySQL. However, regarding indexes there are some important differences to know between MySQL's two most important storage engines. They influence some decisions you will have to make. MyISAM In the figure below you can see a simplified schema of how indexes work with the MyISAM storage engine. Their most important property can be summed up as "all indexes are created equal". This means that there is no technical difference between the primary and secondary keys. The diagram shows a single (theoretical) data table called books. It has three columns named isbn, title, and author. This is a very simple schema, but it is sufficient for explanation purposes. The exact definition can be found in the Adding indexes to tables recipe in this article. For now, it is not important. MyISAM tables store information in the order it is inserted. In the example, there are three records representing a single book each. The ISBN number is declared as the primary key for this table. As you can see, the records are not ordered in the table itself—the ISBN numbers are out of what would be their lexical order. Let's assume they have been inserted by someone in this order. Now, have a look at the first index—the PRIMARY KEY. The index is sorted by the isbn column. Associated with each index entry is a row pointer that leads to the actual data record in the books table. When looking up a specific ISBN number in the primary key index, the database server follows the row pointer to retrieve the remaining data fields. The same holds true for the other two indexes IDX_TITLE and IDX_AUTHOR, which are sorted by the respective fields and also contain a row pointer each. Looking up a book's details by any one of the three possible search criteria is a two-part operation: first, find the index record, and then follow the row pointer to get the rest of the data. With this technique you can insert data very quickly because the actual data records are simply appended to the table. Only the relatively small index records need to be kept in order, meaning much less data has to be shuffled around on the disk. There are drawbacks to this approach as well. Even in cases where you only ever want to look up data by a single search column, there will be two accesses to the storage subsystem—one for the index, another for the data. InnoDB However, InnoDB is different. Its index system is a little more complicated, but it has some advantages: Primary (clustered) indexes Whereas in MyISAM all indexes are structured identically, InnoDB makes a distinction between the primary key and additional secondary ones. The primary index in InnoDB is a clustered index. This means that one or more columns of each record make up a unique key that identifies this exact record. In contrast to other indexes, a clustered index's main property is that it itself is part of the data instead of being stored in a different location. Both data and index are clustered together. An index is only serving its purpose if it is stored in a sorted fashion. As a result, whenever you insert data or modify the key column(s), it needs to be put in the correct location according to the sort order. For a clustered index, the whole record with all its data has to be relocated. That is why bulk data insertion into InnoDB tables is best performed in correct primary key order to minimize the amount of disk I/O needed to keep the records in index order. Moreover, the clustered index should be defined so that it is hardly ever changed for existing rows, as that too would mean relocating full records to different sectors on the disk. Of course, there are significant advantages to this approach. One of the most important aspects of a clustered key is that it actually is a part of the data. This means that when accessing data through a primary key lookup, there is no need for a two-part operation as with MyISAM indexes. The location of the index is at the same time the location of the data itself—there is no need for following a row pointer to get the rest of the column data, saving an expensive disk access. Secondary indexes Consider if you were to search for a book by title to find out the ISBN number. An index on the name column is required to prevent the database from scanning through the whole (ISBN-sorted) table. In contrast to MyISAM, the InnoDB storage engine creates secondary indexes differently. Instead of record pointers, it uses a copy of the whole primary key for each record to establish the connection to the actual data contents. In the previous figure, have a look at the IDX_TITLE index. Instead of a simple pointer to the corresponding record in the data table, you can see the ISBN number duplicated as well. This is because the isbn column is the primary key of the books table. The same goes for the other indexes in the figure—they all contain the book ISBN number as well. You do not need to (and should not) specify this yourself when creating and indexing on InnoDB tables, it all happens automatically under the covers. Lookups by secondary index are similar to MyISAM index lookups. In the first step, the index record that matches your search term is located. Then secondly, the remaining data is retrieved from the data table by means of another access—this time by primary key. As you might have figured, the second access is optional, depending on what information you request in your query. Consider a query looking for the ISBN numbers of all known issues of Moby Dick: SELECT isbn FROM books WHERE title LIKE 'Moby Dick%'; Issued against a presumably large library database, it will most certainly result in an index lookup on the IDX_TITLE key. Once the index records are found, there is no need for another lookup to the actual data pages on disk because the ISBN number is already present in the index. Even though you cannot see the column in the index definition, MySQL will skip the second seek saving valuable I/O operations. But there is a drawback to this as well. MyISAM's row pointers are comparatively small. The primary key of an InnoDB table can be much bigger—the longer the key, the more the data that is stored redundantly. In the end, it can often be quite difficult to decide on the optimal balance between increased space requirements and maintenance costs on index updates. But do not worry; we are going to provide help on that in this article as well. General requirements for the recipes in this article All the recipes in this article revolve around changing the database schema. In order to add indexes or remove them, you will need access to a user account that has an effective INDEX privilege or the ALTER privilege on the tables you are going to modify. While the INDEX privilege allows for use of the CREATE INDEX command, ALTER is required for the ALTER TABLE ADD INDEX syntax. The MySQL manual states that the former is mapped to the latter automatically. However, an important difference exists: CREATE INDEX can only be used to add a single index at a time, while ALTER TABLE ADD INDEX can be used to add more than one index to a table in a single go. This is especially relevant for InnoDB tables because up to MySQL version 5.1 every change to the definition of a table internally performs a copy of the whole table. While for small databases this might not be of any concern, it quickly becomes infeasible for large tables due to the high load copying may put on the server. With more recent versions this might have changed, but make sure to consult your version's manual. In the recipes throughout this article, we will consistently use the ALTER TABLE ADD INDEX syntax to modify tables, assuming you have the appropriate privileges. If you do not, you will have to rewrite the statements to use the CREATE INDEX syntax. Adding indexes to tables Over time requirements for a software product usually change and affect the underlying database as well. Often the need for new types of queries arises, which makes it necessary to add one or more new indexes to perform these new queries fast enough. In this recipe, we will add two new indexes to an existing table called books in the library schema. One will cover the author column, the other the title column. The schema and table can be created like this: mysql> CREATE DATABASE library;mysql> USE library;mysql> CREATE TABLE books (isbn char(13) NOT NULL,author varchar(64) default NULL,title varchar(64) NOT NULL,PRIMARY KEY (isbn)) ENGINE=InnoDB; Getting ready Connect to the database server with your administrative account.
Read more
  • 0
  • 0
  • 2111

article-image-build-your-own-application-access-twitter-using-java-and-netbeans-part-4
Packt
28 Jun 2010
7 min read
Save for later

Build your own Application to access Twitter using Java and NetBeans: Part 4

Packt
28 Jun 2010
7 min read
In the 3rd part of this article series, we learnt about: Added a Tabbed Pane component to your SwingAndTweet application, to show your own timeline on one tab and your friend’s timeline on another tab Used a JScrollPane component to add vertical and horizontal scrollbars to your friends’ timeline list Used the getFriendsTimeline() method from the Twitter4J API to get the 20 most recent tweets from your friend’s timeline Applied font styles to your JLabel components via the Font class Added a black border to separate each individual tweet by using the BorderFactory and Color classes Added the date and time of creation of each individual tweet by using the getCreatedAt() method from the twitter4j.Status interface, along with the Date class. All those things, we learnt in the third part of the article series were a big improvement for our Twitter client, but wouldn’t it be cool if you could click on the URL links from your friends’ time line and then a web browser window would open automatically to show you the related webpage? Well, after reading this part of the article series, you’ll be able to integrate this functionality into your own Twitter client among other things. Here are the links to the earlier articles of this article series: Read Build your own Application to access Twitter using Java and NetBeans: Part 1 Read Build your own Application to access Twitter using Java and NetBeans: Part 2 Read Build your own Application to access Twitter using Java and NetBeans: Part 3 Using a JEditorPane component Till now, we’ve been working with JPanel objects to show your Twitter information inside the JTabbedPane component. But as you can see from your friends’ tweets, the URL links that show up aren’t clickable. And how can we make them clickable? Well, fortunately for us there’s a Swing component called JEditorPane that will let us use HTML markup, so the URL hyperlinks will show up as if you were on a web page. Cool, huh? Now let’s start with the dirty job… Open your NetBeans IDE along with your SwingAndTweet project, and make sure you’re in the Source View. Scroll up to the import declarations section and type import javax.swing.JEditorPane; right below the last import declaration, so your code looks as shown below: Now scroll down to the last line of code, JLabel statusUser;, and type JEditorPane statusPane; just below that line, as shown in the following screenshot: The next step is to add statusPane to the JTabbedPane1 component in your application. Scroll through the code until you locate the //code for the Friends timelineline and the try-block code below that line; then type the following code block just above the for statement: String paneContent = new String();statusPane = new JEditorPane();statusPane.setContentType("text/html");statusPane.setEditable(false); The following screenshot shows how your code must look like after inserting the above block of code (the red square indicates the lines you must add): Now scroll down through the code inside the for statement and type paneContent = paneContent + statusUser.getText() + "<br>" + statusText.getText() + "<hr>"; right after the jPanel1.add(individualStatus); line, as shown below: Then add the following two lines of code after the closing brace of the try block: statusPane.setText(paneContent);jTabbedPane1.add("Friends - Enhanced", statusPane); The following screenshot shows how your code must look like after the insertion: Run your application and log into your Twitter account. A new tab will appear in your Twitter client, and if you click on it you’ll see your friends’ latest tweets, as in the following screenshot: If you take a good look at the screen, you’ll notice the new tab you added with the JEditorPane component doesn’t show a vertical scroll bar so you can scroll up and down to see the complete list. That’s pretty easy to fix: First add the import javax.swing.JScrollPane; line to the import declarations section and then replace the jTabbedPane1.add("Friends - Enhanced", statusPane); line you added on step 9 with the following lines: JScrollPane editorScrollPane = new JScrollPane(statusPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, // vertical bar policy JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ); // horizontal bar policyjTabbedPane1.add("Friends - Enhanced", editorScrollPane); Your code should now look like this: Run your Twitter application again and this time you’ll see the vertical scrollbar: Let’s stop for a while to review our progress so far. In the first step above the exercise, you added an import declaration to tell the Java compiler that we need to use an object from the JEditorPane class. In step 3, you added a JEditorPane object called statusPane to your application. This object acts as a container for your friends’ tweets. And in case you’re wondering why we didn’t use a regular JPanel object, just remember that we want to make the URL links in your friends’ tweets clickable, so when you click on one of them, a web browser window will pop up to show you the web page associated to that hyperlink. Now let’s get back to our exercise. In step 4, you added four lines to your application’s code. The first line: String paneContent = new String(); creates a String variable called paneContent to store the username and text of each individual tweet from your friends’ timeline. The next three lines: statusPane = new JEditorPane();statusPane.setContentType("text/html");statusPane.setEditable(false); create a JEditorPane object called statusPane, set its content type to text/html so we can include HTML markup and make the statusPane non-editable, so nothing gets messed up when showing your friends’ timeline. Now that we have the statusPane ready to roll, we need to fill it up with the information related to each individual tweet from your friends. That’s why we need the paneContent variable. In step 6, you inserted the following line: paneContent = paneContent + statusUser.getText() + "<br>" + statusText.getText() + "<hr>"; inside the for block to add the username and the text of each individual tweet to the paneContent variable. The <br> HTML tag inserts a line break so the username appears in one line and the text of each tweet appears in another line. The <hr> HTML tag inserts a horizontal line to separate one tweet from the other. Once the for loop ends, we need to add the information from the paneContent variable to the JEditorPane object called statusPane. That’s why in step 7, you added the following line: statusPane.setText(paneContent); and then the jTabbedPane1.add("Friends - Enhanced", statusPane); line creates a new tab in the jTabbedPane1 component and adds the statusPane component to it, so you can see the friends timeline with HTML markup. In step 10, you learned how to create a JScrollPane object called editorScrollPane to add scrollbars to your statusPane component and integrate them into the jTabbedPane1 container. In this example, the JScrollPane constructor requires arguments: the statusPane component, the vertical scrollbar policy and the horizontal scrollbar policy. There are three options you can choose for your vertical and horizontal scrollbars: show them as needed, never show them or always show them. In this specific case, we need the vertical scrollbar to show up as needed, in case the list of your friends’ tweets doesn’t fit the screen, so we use the JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED policy. And since we don’t need the horizontal bar to show up because the statusPane component can adjust its horizontal size to fit your application’s window, we use the JScrollPane.HORIZONTAL_SCROLLBAR_NEVER policy. The last line of code from step 10 adds the editorScrollPane component to the jTabbedPane1 container instead of adding the statusPane component directly, because now the JEditorPane component is contained within the JScrollPane component. Now let’s see how to convert the URL links to real hyperlinks.
Read more
  • 0
  • 0
  • 2262

article-image-oracle-enterprise-manager-grid-control
Packt
28 Jun 2010
9 min read
Save for later

Oracle Enterprise Manager Grid Control

Packt
28 Jun 2010
9 min read
Evolution of IT systems: As architectural patterns moved from monolithic systems to distributed systems, not all IT systems were moved to the newest patterns. Some new systems were built with new technologies and patterns whereas existing systems that were performing well enough continued on earlier technologies. Best of breed approach: With multi-tiered architectures, enterprises had the choice of building each tier using best of breed technology for that tier. For example, one system could be built using a J2EE container from vendor A, but a database from vendor B. Avoiding single vendors and technologies: Enterprises wanted to avoid dependence on any single vendor and technology. This led to systems being built using different technologies. For example, an order-booking system built using .NET technologies on Windows servers, but an order shipment system built using J2EE platform on Linux servers. Acquisitions and Mergers: Through acquisitions and mergers, enterprises have inherited IT systems that were built using different technologies. Frequently, new systems were added to integrate the systems of two enterprises but the new systems were totally different from the existing systems. For example, using BPEL process manager to integrate a CRM system with a transportation management system. We see that each factor for diversity in the data center has some business or strategic value. At the same time, such diversity makes management of the data center more complex. To manage such data centers we need a special product like Oracle's Enterprise Manager Grid Control that can provide a unified and centralized management solution for the wide array of products. In any given data center, there are lots of repetitive operations that need to be executed on multiple servers (like applying security patches on all Oracle Databases). As data centers move away from high-end servers to a grid of inexpensive servers, the number of IT resources increases in the data center and so does the cost of executing repetitive operations on the grid. Enterprise Manager Grid Control provides solutions to reduce the cost of any grid by automating repetitive operations that can be simultaneously executed on multiple servers. Enterprise Manager Grid Control works as a force multiplier by providing support for executing the same operations on multiple servers at the cost of one operation. As organizations put more emphasis on business and IT alignment, that requires a view of IT resources overlaid with business processes and applications is required. Enterprise Manager Grid Control provides such a view and improves the visibility of IT and business processes in a given data center. By using Enterprise Manager Grid Control, administrators can see IT issues in the context of business processes and they can understand how business processes are affected by IT performance. In this article, we will get to know more about Oracle's Enterprise Manager Grid Control by covering the following aspects: Key features of Enterprise Manager Grid Control: Comprehensive view of data center Unmanned monitoring Historical data analysis Configuration management Managing multiple entities as one Service level management Scheduling Automating provisioning Information publishing Synthetic transaction Manage from anywhere Enterprise Manager Product family Range of products managed by Enterprise Manager: Range of products EM extensibility Enterprise Manager Grid Control architecture. Multi-tier architecture Major components High availability Summary of learning Key features of Enterprise Manager Grid Control Typical applications in today's world are built with multi-tiered architecture; to manage such applications a system administrator has to navigate through multiple management tools and consoles that come along with each product. Some of the tools have a browser interface, some have a thick client interface, or even a command line interface. Navigating through multiple management tools often involves doing some actions from a browser or running some scripts or launching a thick client from the command line. For example, to find bottlenecks in a J2EE application in the production environment, an administrator has to navigate through the management console for the HTTP server, the management console for the J2EE container, and the management console for the database. Enterprise Manager Grid Control is a systems management product for the monitoring and management of all of the products in the data center. For the scenario explained above, Enterprise Manager provides a common management interface to manage an HTTP server, J2EE server and database. Enterprise Manager provides this unified solution for all products in a data center. In addition to basic monitoring, Enterprise Manager provides a unified interface for many other administration tasks like patching, configuration compliance, backup-recovery, and so on. Some key features of Enterprise Manager are explained here. Comprehensive view of the data center Enterprise Manager provides a comprehensive view of the data center, where an administrator can see all of the applications, servers, databases, network devices, storage devices, and so on, along with performance and configuration data. As the number of all such resources is very high, this Enterprise Manager highlights the resources that need immediate attention or that may need attention in near future. For example, a critical security patch is available that needs to be applied on some Fusion Middleware servers, or a server that has 90% CPU utilization. The following figure shows one such view of a data center, where users can see all entities that are monitored, that are up, that are down, that have performance alerts, that have configuration violations and so on. The user can drill down to fine-grained views from this top-level view. The data in the top-level view and the fine-grained drill-down view can be broadly summarized in the following categories: Performance data Data that shows how an IT resource is performing, that includes the current status, overall availability over a period of time, and other performance indicators that are specific to the resource like the average response time for a J2EE server. Any violation of acceptable performance thresholds is highlighted in this view. Configuration data Configuration data is the configuration parameters or, configuration files captured from an IT resource. Besides the current configuration, changes in configuration are also tracked and available from Enterprise Manager. Any violation of configuration conformance is also available. For example, if a data center policy mandates that only port 80 should be open on all servers, Enterprise Manager captures any violation of that policy. Status of scheduled operations In any data center there are some scheduled operations, these operations could be something like a system administration task such as taking a backup of a database server or some batch process that moves data across systems, for example, moving orders from fulfillment to shipping. Enterprise Manager provides a consolidated view of the status of all such scheduled operations. Inventory Enterprise Manager provides a listing of all hardware and software resources with details like version numbers. All of these resources are also categorized in different buckets – for example, Oracle Application Server, WebLogic application Server, WebSphere application are all categorized in the middleware bucket. This categorization helps the user to find resources of the same or similar type. Enterprise Manager. It also captures the finer details of software resources—like patches applied. The following figure shows one such view where the user can see all middleware entities like Oracle WebLogic Server, IBM WebSphere Server, Oracle Application Server, and so on. Oracle Enterprise Manager Grid Control" border="0" alt="Oracle Enterprise Manager Grid Control" title="Oracle Enterprise Manager Grid Control" /> Unmanned monitoring Enterprise Manager monitors IT resources around the clock and it gathers all performance indicators at every fixed interval. Whenever a performance indicator goes beyond the defined acceptable limit, Enterprise Manager records that occurrence. For example, if the acceptable limit of CPU utilization for a server is 70%, then whenever CPU utilization of the server goes above 70% then that occurrence is recorded. Enterprise Manager can also send notification of any such occurrence through common notification mechanisms like email, pager, SNMP trap, and so on. Historical data analysis All of the performance indicators captured by Enterprise Manager are saved in the repository. Enterprise Manager provides some useful views of the data using the system administrator that can analyze data over a period of time. Besides the fine-grained data that is collected at every fixed interval, it also provides coarse views by rolling up the data every hour and every 24 hours. Configuration management Enterprise Manager gathers configuration data for IT resources at regular intervals and checks for any configuration compliance violation. Any such violation is captured and can be sent out as a notification. Enterprise Manager comes with many out-of-the-box configuration compliance rules that represent best practices; in addition to that, system administrators can configure their own rules. All of the configuration data is also saved in the Enterprise Manager repository. Using data, the system administrator can compare the configuration of two similar IT resources or compare the configuration of the same IT resource at two different points in time. The system administrator can also see the configuration change history. Managing multiple entities as one Most of the more recent applications are built with multi-tiered architecture and each tier may run on different IT resources. For example, an order booking application can have all of its presentation and business logic running on a J2EE server, all business data persisted in a database, all authentication and authorization performed through an LDAP server, and all of the traffic to the application routed through an HTTP server. To monitor such applications, all of the underlying resources need to be monitored. Enterprise Manager provides support for grouping such related IT resources. Using this support, the system administrator can monitor all related resources as one entity and all performance indicators for all related entities can be monitored from one interface. Service level management Enterprise Manager provides necessary constructs and interfaces for managing service level agreements that are based on the performance of IT resources. Using these constructs, the user can define indicators to measure service levels and expected service levels. For example, a service representing a web application can have the same average JSP response time as a service indicator, the expected service level for this service is to have the service indicator below three seconds for 90% of the time during business hours. Enterprise Manager keeps track of all such indicators and violations in the context of a service and at any time the user can see the status of such service level agreements over a defined time period.
Read more
  • 0
  • 0
  • 2769

article-image-displaying-posts-and-pages-using-wordpress-loop
Packt
28 Jun 2010
12 min read
Save for later

Displaying Posts and Pages Using Wordpress Loop

Packt
28 Jun 2010
12 min read
(For more resources on Wordpress, see here.) The Loop is the basic building block of WordPress template files. You'll use The Loop when displaying posts and pages, both when you're showing multiple items or a single one. Inside of The Loop you use WordPress template tags to render information in whatever manner your design requires. WordPress provides the data required for a default Loop on every single page load. In addition, you're able to create your own custom Loops that display post and page information that you need. This power allows you to create advanced designs that require a variety of information to be displayed. This article will cover both basic and advanced Loop usage and you'll see exactly how to use this most basic WordPress structure. Creating a basic Loop The Loop nearly always takes the same basic structure. In this recipe, you'll become acquainted with this structure, find out how The Loop works, and get up and running in no time. How to do it... First, open the file in which you wish to iterate through the available posts. In general, you use The Loop in every single template file that is designed to show posts. Some examples include index.php, category.php, single.php, and page.php. Place your cursor where you want The Loop to appear, and then insert the following code: <?phpif( have_posts() ) { while( have_posts() ) { the_post(); ?> <h2><?php the_title(); ?></h2> <?php }}?> Using the WordPress theme test data with the above Loop construct, you end up with something that looks similar to the example shown in following screenshot: Depending on your theme's styles, this output could obviously look very different. However, the important thing to note is that you've used The Loop to iterate over available data from the system and then display pieces of that data to the user in the way that you want to. From here, you can use a wide variety of template tags in order to display different information depending on the specific requirements of your theme. How it works... A deep understanding of The Loop is paramount to becoming a great WordPress designer and developer, so you should understand each of the items in the above code snippet fairly well. First, you should recognize that this is just a standard while loop with a surrounding if conditional. There are some special WordPress functions that are used in these two items, but if you've done any PHP programming at all, you should be intimately familiar with the syntax here. If you haven't experienced programming in PHP, then you might want to check out the syntax rules for if and while constructs at http://php.net/if and http://php.net/ while, respectively. The next thing to understand about this generic loop is that it depends directly on the global $wp_query object. $wp_query is created when the request is parsed, request variables are found, and WordPress figures out the posts that should be displayed for the URL that a visitor has arrived from. $wp_query is an instance of the WP_Query object, and the have_posts and the_post functions delegate to methods on that object. The $wp_query object holds information about the posts to be displayed and the type of page being displayed (normal listing, category archive, date archive, and so on). When have_posts is called in the if conditional above, the $wp_query object determines whether any posts matched the request that was made, and if so, whether there are any posts that haven't been iterated over. If there are posts to display, a while construct is used that again checks the value of have_posts. During each iteration of the while loop, the the_post function is called. the_post sets an index on $wp_query that indicates which posts have been iterated over. It also sets up several global variables, most notably $post. Inside of The Loop, the the_title function uses the global $post variable that was set up in the_post to produce the appropriate output based on the currently-active post item. This is basically the way that all template tags work. If you're interested in further information on how the WP_Query class works, you should read the documentation about it in the WordPress Codex at http://codex.wordpress.org/Function_ Reference/WP_Query. You can find more information about The Loop at http://codex. wordpress.org/The_Loop. Displaying ads after every third post If you're looking to display ads on your site, one of the best places to do it is mixed up with your main content. This will cause visitors to view your ads, as they're engaged with your work, often resulting in higher click-through rates and better paydays for you. How to do it... First, open the template in which you wish to display advertisements while iterating over the available posts. This will most likely be a listing template file like index.php or category. php. Decide on the number of posts that you wish to display between advertisements. Place your cursor where you want your loop to appear, and then insert the following code: <?phpif( have_posts() ) { $ad_counter = 0; $after_every = 3; while( have_posts() ) { $ad_counter++; the_post(); ?> <h2><?php the_title(); ?></h2> <?php // Display ads $ad_counter = $ad_counter % $after_every; if( 0 == $ad_counter ) { echo '<h2 style="color:red;">Advertisement</h2>'; } }}?> If you've done everything correctly, and are using the WordPress theme test data, you should see something similar to the example shown in the following screenshot: Obviously, the power here comes when you mix in paying ads or images that link to products that you're promoting. Instead of a simple heading element for the Advertisement text, you could dynamically insert JavaScript or Flash elements that pull in advertisements for you. How it works... As with the basic Loop, this code snippet iterates over all available posts. In this recipe, however, a counter variable is declared that counts the number of posts that have been iterated over. Every time that a post is about to be displayed, the counter is incremented to track that another post has been rendered. After every third post, the advertisement code is displayed because the value of the $ad_counter variable is equal to 0. It is very important to put the conditional check and display code after the post has been displayed. Also, notice that the $ad_counter variable will never be greater than 3 because the modulus operator (%) is being used every time through The Loop. Finally, if you wish to change the frequency of the ad display, simply modify the $after_every variable from 3 to whatever number of posts you want to display between ads. Removing posts in a particular category Sometimes you'll want to make sure that posts from a certain category never implicitly show up in the Loops that you're displaying in your template. The category could be a special one that you use to denote portfolio pieces, photo posts, or whatever else you wish to remove from regular Loops. How to do it... First, you have to decide which category you want to exclude from your Loops. Note the name of the category, and then open or create your theme's functions.php file. Your functions. php file resides inside of your theme's directory and may contain some other code. Inside of functions.php, insert the following code: add_action('pre_get_posts', 'remove_cat_from_loops');function remove_cat_from_loops( $query ) { if(!$query->get('suppress_filters')) { $cat_id = get_cat_ID('Category Name'); $excluded_cats = $query->get('category__not_in'); if(is_array($excluded_cats)) { $excluded_cats[] = $cat_id; } else { $excluded_cats = array($cat_id); } $query->set('category__not_in', $excluded_cats); } return $query;} How it works... In the above code snippet, you are excluding the category with the name Category Name. To exclude a different category, change the Category Name string to the name of the category you wish to remove from loops. You are filtering the WP_Query object that drives every Loop. Before any posts are fetched from the database, you dynamically change the value of the category__not_in variable in the WP_Query object. You append an additional category ID to the existing array of excluded category IDs to ensure that you're not undoing work of some other developer. Alternatively, if the category__not_in variable is not an array, you assign it an array with a single item. Every category ID in the category__not_in array will be excluded from The Loop, because when the WP_Query object eventually makes a request to the database, it structures the query such that no posts contained in any of the categories identified in the category__not_in variable are fetched. Please note that the denoted category will be excluded by default from all Loops that you create in your theme. If you want to display posts from the category that you've marked to exclude, then you need to set the suppress_filters parameter to true when querying for posts, as follows: query_posts( array( 'cat'=>get_cat_ID('Category Name'), 'suppress_filters'=>true)); Removing posts with a particular tag Similar to categories, it could be desirable to remove posts with a certain tag from The Loop. You may wish to do this if you are tagging certain posts as asides, or if you are saving posts that contain some text that needs to be displayed in a special context elsewhere on your site. How to do it... First, you have to decide which tag you want to exclude from your Loops. Note the name of the tag, and then open or create your theme's functions.php file. Inside of functions.php, insert the following code: add_action('pre_get_posts', 'remove_tag_from_loops');function remove_tag_from_loops( $query ) { if(!$query->get('suppress_filters')) { $tag_id = get_term_by('name','tag1','post_tag')->term_id; $excluded_tags = $query->get('tag__not_in'); if(is_array( $excluded_tags )) { $excluded_tags[] = $tag_id; } else { $excluded_tags = array($tag_id); } $query->set('tag__not_in', $excluded_tags); } return $query;} How it works... In the above code snippet, you are excluding the tag with the slug tag1. To exclude a different tag, change the string tag1 to the name of the tag that you wish to remove from all Loops. When deciding what tags to exclude, the WordPress system looks at a query parameter named tag__not_in, which is an array. In the above code snippet, the function appends the ID of the tag that should be excluded directly to the tag__not_in array. Alternatively, if tag__not_in isn't already initialized as an array, it is assigned an array with a single item, consisting of the ID for the tag that you wish to exclude. After that, all posts with that tag will be excluded from WordPress Loops. Please note that the chosen tag will be excluded, by default, from all Loops that you create in your theme. If you want to display posts from the tag that you've marked to exclude, then you need to set the suppress_filters parameter to true when querying for posts, as follows: query_posts( array( 'tag'=>get_term_by('name','tag1','post_tag')->term_id, 'suppress_filters'=>true )); Highlighting sticky posts Sticky posts are a feature added in version 2.7 of WordPress and can be used for a variety of purposes. The most frequent use is to mark posts that should be "featured" for an extended period of time. These posts often contain important information or highlight things (like a product announcement) that the blog author wants to display in a prominent position for a long period of time. How to do it... First, place your cursor inside of a Loop where you're displaying posts and want to single out your sticky content. Inside The Loop, after a call to the_post, insert the following code: <?phpif(is_sticky()) { ?> <div class="sticky-announcer"> <p>This post is sticky.</p> </div> <?php}?> Create a sticky post on your test blog and take a look at your site's front page. You should see text appended to the sticky post, and the post should be moved to the top of The Loop. You can see this in the following screenshot: How it works... The is_sticky function checks the currently-active post to see if it is a sticky post. It does this by examining the value retrieved by calling get_option('sticky_posts'), which is an array, and trying to find the active post's ID in that array. In this case, if the post is sticky then the sticky-announcer div is output with a message. However, there is no limit to what you can do once you've determined if a post is sticky. Some ideas include: Displaying a special icon for sticky posts Changing the background color of sticky posts Adding content dynamically to sticky posts Displaying post content differently for sticky posts
Read more
  • 0
  • 0
  • 10788

article-image-packt-special-offer
Packt
28 Jun 2010
1 min read
Save for later

Packt Special Offer

Packt
28 Jun 2010
1 min read
Quantity of Books Discount 1 10% 2-4 18% 5-10 20%       If you are looking at purchasing books in greater quantities, I would like to suggest that you contact us directly, and we can discuss the possibility of a further discount.  Email BulkSales@PacktPub.com to find out more.        The above special offers have currently been frozen and are no longer being automatically applied in your cart. If you would like to make use of them, though, feel free to email BulkSales@PacktPub.com.   Featured Articles How to Focus on Business Results Negotiation Strategy for Effective Implementation of COTS Software Installing SBS 2008 and Connecting to the Internet Search Engine Optimization in WordPress for Bussiness Bloggers-part1 Writing Tips for Bloggers Securing the Small Business Server 2008  
Read more
  • 0
  • 0
  • 3842
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-jasperreports-36-creating-report-model-beans-java-applications
Packt
26 Jun 2010
3 min read
Save for later

JasperReports 3.6: Creating a Report from Model Beans of Java Applications

Packt
26 Jun 2010
3 min read
(For more resources on JasperReports, see here.) Getting ready You need a Java JAR file that contains class files for the JavaBeans required for this recipe. A custInvoices.jar file is contained in the source code (chap4). Unzip the source code file for this article and copy the Task5 folder from the unzipped source code to a location of your choice. How to do it... Let's start using Java objects as data storage units. Open the ModelBeansReport.jrxml file from the Task5 folder of the source code for this article (chapt 4). The Designer tab of iReport shows a report containing data in the Title, Column Header, Customer Group Header1 and Detail 1 sections, as shown in the following screenshot: If you have not made any database connection so far in your iReport installation, you will see an Empty datasource shown selected in a drop-down list just below the main menu. Click on the Report Datasources icon, shown encircled to the right of the drop-down list in the following screenshot: A new window named Connections / Datasources will open, as shown next. This window lists an Empty data source as well as the datasources you have made so far. Click the New button at the top-right of the Connections / Datasources window. This will open a new Datasource selection window, as shown in the following screenshot: Select JavaBeans set datasource from the datasource types, as shown next. Click the Next button. A new window named JavaBeans set datasource will open, as shown in the following screenshot: Enter CustomerInvoicesJavaBeans as the name of your new connection in the text box beside the Name field, as shown in the following screenshot: Enter com.CustomerInvoicesFactory as the name of the factory class in the text box beside the Factory class field, as shown in the following screenshot: This com.CustomerInvoicesFactory class provides iReport with access to JavaBeans that contain your data. Enter getBeanCollection as the name of the static method in the text box beside The static method... field, as shown in the following screenshot: Leave the rest of the fields at their default values. Click the Test button to test your new connection to the JavaBeans datasource. You will see an Exception message dialog. This exception message occurs because iReport can't find your factory class. Dismiss the message box by clicking OK. Click the Save button at the bottom of the JavaBeans set datasource window and close the Connections / Datasources window as well.
Read more
  • 0
  • 0
  • 3196

article-image-jasperreports-36-using-multiple-relational-databases-generate-report
Packt
26 Jun 2010
4 min read
Save for later

JasperReports 3.6: Using Multiple Relational Databases to Generate a Report

Packt
26 Jun 2010
4 min read
(For more resources on JasperReports, see here.) Refer to the installPostgreSQL.txt file included in the source code download (chap4) to install and run PostgreSQL, which should be up and running before you proceed. The source code also includes two files named copySampleDataIntoPGS.txt and copySamplePaymentStatusDataIntoPGS.txt. The copySampleDataIntoPGS.txt file will help you to create a database named jasperdb5 and create a table named CustomerInvoices with five columns (InvoiceID, CustomerName, InvoicePeriod, ProductName, and InvoiceValue) and copy sample data for this article. Similarly, the copySamplePaymentStatusDataIntoPGS.txt file will help you to create a database named jasperdb5a and create a table named PaymentDetails with two columns (InvoiceID and PaymentStatus) and copy sample data. You will be using two JRXML files MultiDBReport.jrxml and PaymentStatusSubreport.jrxml in this recipe. You will find these files in the Task4 folder of the source code download for this chapter. The MultiDBReport.jrxml file is the master report, which uses the other file as a subreport. The master report has to refer to its subreport using a complete path (you cannot use relative paths). This means you have to copy the two JRXML files to the c:JasperReportsCookBookSamples folder on your PC. I have hardcoded this complete path in the master report (MultiDBReport.jrxml). How to do it... You are about to discover tricks for using multiple databases in a single report in the following simple steps: Open the PaymentStatusSubreport.jrxml file from the c:JasperReportsCookBookSamples folder. The Designer tab of iReport shows an empty report, as shown in the following screenshot: Right-click on the Parameters node in the Report Inspector window on the left of the Designer tab, as shown next. Choose the Add Parameter option from the pop-up menu. The Parameters node will expand to show the newly added parameter named parameter1 at the end of the parameters list. Click on parameter1, its properties will appear in the Properties window below the palette of components on the right of your iReport main window. Click on the Name property of the parameter and type InvoiceID as its value. The name of the parameter1 parameter will change to InvoiceID. Click on the Parameter Class property and select java.lang.Integer as its value. Click on the Default Value Expression property and enter 0 as its value, as shown in the following screenshot. Leave the rest of the parameter properties at their default values. Click the Report query button on the right of the Preview tab; a Report query dialog will appear, as shown in the following screenshot: Type SELECT * FROM paymentdetails WHERE invoiceid = $P{InvoiceID} in the Query editor. The fields of the paymentdetails table will be shown in the lower-half of the Report query dialog. Click the OK button, as shown in the following screenshot: Double-click the Fields node in the Report Inspector window. You will see that it contains invoiceid and paymentstatus fields, as shown below. Drag-and-drop the paymentstatus field from the Fields node into the top-left corner of the Detail 1 section, as shown in the following screenshot: Select PaymentDetails in the datasources drop-down list, as shown in the left image given below. Then switch to the Preview tab; a Parameter prompt dialog will appear, which will ask you for the invoice ID, as shown in the right image given below. Enter 1001 as the value of the InvoiceID parameter. You will see a report containing a single record showing the payment status of the invoice having the ID 1001. Switch back to the Designer tab. Click anywhere in the Page Header section; its properties will appear in the Properties window below the palette. Select the Band height property and set 0 as its value, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 3842

article-image-jasperreports-36-creating-report-xml-data-using-xpath
Packt
24 Jun 2010
3 min read
Save for later

JasperReports 3.6: Creating a Report from XML Data using XPath

Packt
24 Jun 2010
3 min read
XML is a popular data source used in many applications. JasperReports allows you to generate reports directly from XML data. This first section of the article teaches you how to connect iReport to an XML file stored on your PC. In the second section of this article by Bilal Siddiqui, author of JasperReports 3.6 Development Cookbook, you will create a report from data stored in an XML file. In order to process an XML file and extract information from it, JasperReports uses XPath, which is a popular query language to filter XML data. So you will also learn how to use XPath expressions for report generation. (For more resources on JasperReports, see here.) Connecting to an XML datasource XML is a popular data source used in many applications. JasperReports allows you to generate reports directly from XML data. This section teaches you how to connect iReport to an XML file stored on your PC. Getting ready You need an XML file that contains report data. The EventsData.xml file is contained in the source code download (chap4). Unzip the source code file for this article (chap:4) and copy the Task2 folder from the unzipped source code to a location of your choice. How to do it... Run iReport; it will open showing a Welcome Window, as shown in the following screenshot: If you have not made any database connection so far in your iReport installation, you will see an Empty datasource shown selected in a drop-down list just below the main menu. Click on the Report Datasources icon shown encircled to the right of the drop-down list in the screen-shot shown below: A new window named Connections / Datasources will open, as shown below. This window lists an Empty datasource as well as the data sources you have made so far. Click the New button at the top-right of the Connections / Datasources window. This will open a new Datasource selection window, as shown in the following screenshot: Select XML file datasource from the datasources type list. Click Next. A new window named XML file datasource will open, as in the following screenshot: Enter XMLDatasource as the name for your new connection for the XML datasource in the text box beside the Name text field, as shown in the following screenshot: Click the Browse button beside the XML file text box to browse to the EventsData.xml file located in the Task2 folder that you copied in the Getting ready section. Click the Open button, as shown in the following screenshot: Select the Use the report XPath expression when filling the report option in the XML file datasource window, as shown in the following screenshot: Leave the other fields at their default values. Click the Test button to test the new XML datasource connection. You will see a Connection test successful message dialog. Click the Save button to save the newly created connection. A Connections / Datasources window will open showing your new XML datasource connection set as the default connection in the connections list, as shown highlighted in the following screenshot:
Read more
  • 0
  • 0
  • 7168

article-image-product-management-compiere-3
Packt
24 Jun 2010
7 min read
Save for later

Product Management with Compiere 3

Packt
24 Jun 2010
7 min read
(For more resources on Compiere 3, see here.) The product definition The concept of a product in Compiere is that it is something that you buy or sell and has a price. It would include: Inventory items (items that you store and track) Non-stock items (still items, but you do not store or track them) Services Resources Expense types In addition to a product, Compiere allows for charges (account aliases), as well as customer assets on transactional lines. When to use a charge and not a product: It's logical to use charges where a mere account entry is required and the many descriptions that a product requires are not required for the transaction. An example would be marketing or an admin expense. When to use a customer asset and not a product: Customer assets are extended instances of a Compiere product. An example would be where a Desktop PC is sold or purchased and becomes an asset or equipment type that need to be tracked.Customer assets are therefore used for asset or equipment related business process information. Products allow for many descriptive attributes in its master setup. Describing a product Product information and features can be extended and described in Compiere in the following manner: Basic Product Information: Basic product information includes search key values, Descriptions, Unit of Measure, UPC, EAN. Critical for basic product information are Product categories, which group products into related products. Product BOM (Bill of Material): More advanced products would include BOM kits that are made up of other products (referred to as BOM components). Substitute / Related Products: This refers to products that may be related to the product being searched for. Product Replenishment: This describes the rules of how a product would be replenished. This would, for instance, include minimum and maximum quantities to hold in stock. Product Purchasing information: This refers to the set-up around how a product is purchased—for instance the default vendor and the vendor's product code. Product Locator: Where products are currently located in the warehouse. Product Business Partner: This describes additional information used when products are purchased. Product Price: A product may have multiple price lists attached to it, and depending on the Business Partner or transactional document this can be defaulted as required. Product Accounting: This describes which standard account elements are to be used for a transactional document. Usually, similar products have the same accounting rules and as such the accounting for Product Categories would be setup and maintained, rather than individual product categories. Product Unit of Measure conversions: Where applicable, products may have conversions applicable to them—for instance converting a 6-pack quantity sold to an, each, quantity during purchasing. Product Attributes: Attribute sets allow you to further extend the product information into, for example, instance sets such as lots and serial numbers.Non-instance sets are also catered for, such as colour or size sets that can be used for searching the products. Setting up a Product Prior to setting up a product, you should make sure that the following is set up: Warehouse and Locators: The system logic here is that a Product must be sold/delivered from somewhere within the organization. Make sure that you set up your warehouse and Locators first. Use virtual warehouse and locators where they are not physical. Units of Measure: Review the system standard units of measure and add your own units of measure if applicable. Product Categories: Define your groupings prior to setting up products since it will reduce data maintenance time. Tax Categories: Pre-define the applicable tax categories if they are product specific. Price lists: In order to use a product it must have a price which is set up through Price Lists (it includes sales and/or purchase price lists). The above set-up is performed through the Product Setup menu items, which are grouped as follows in the main menu: You start entering a product through the Product window: The additional Product Descriptions (listed above) are added through the following tabs in the Product window: Price Lists In order for products to be used in the sales or purchasing cycle, they must have prices. A product can have the following three line prices set up: List Price: The list price before discounts of a product. Standard Price: The standard price of a product. Limit Price: The lowest price at which a product can be sold or purchased.Usually used by management as a pricing control limit for sales reps. The product price information (in the context of the price list version) is accessed through the Product Price| window: Pricing logic flow Price lists determine the price to be used in the context of the transaction(sales / purchase) and the chosen Business Partner. The basic logic for determining the price is as follows: A price list has a version, and the latest version of a price list is used during sales or purchasing (or both). If a Business Partner (customer or vendor) is assigned a Price list, then this Price List is used to determine the price for the transaction. If a Business Partner is not assigned a price list, then the Business Partner Group's defined price lists is used. If the Business Partner Groups' price list is not defined, then the default sales or purchase price list is used (this is indicated throught the isDefault checkbox in the price list window header). If a product is not assigned the relevant price list, an error is given and the user cannot continue. The system also considers that a price list is Tenant and Organization specific. In terms of price discounting, a product can be assigned to a Discount Schema. In such a case, the following discount schema options are available: Price lists: This is the normal type of discount calculation, and is based on the price list-that is—a discount off the list price based on a distributor or reseller price list. Flat Percentage: This refers to a flat percentage discount arrangement. Quantity Discount Breaks: This discount schema refers to quantity breaks, where items purchased at different quantity levels attract more discount-for example,—100/10% or 1000/20%. Setting Up a Price List and version As mentioned, a price list can have one or more versions, which are time based. This is set up as follows: Enter a price list through the Price List window. Here, we enter a sales pricelist as follows: A price list may be set up to be inclusive of tax. In this case the accounts posting on the document is adjusted to reflect the inclusive tax accounting. Enforcing price limits ensures that the end-user cannot enter a price lower that the price lists, limit price for the product. Create one or many price list versions through the Price List | Version tab, with the following options: Dicscount Schema: This specifies the discount rules to be applied when creating or updating the price list. Base Price List: This indicates a price list upon which to base the discount schema rules. Valid from date: The price list will be used for new order or invoice transactions from this date. Transactions prior to this date will not be affected. A price list is either imported, manually entered, or updated based on another price list, through the discount schema.
Read more
  • 0
  • 0
  • 1806
article-image-jasperreports-36-creating-report-relational-data
Packt
24 Jun 2010
2 min read
Save for later

JasperReports 3.6: Creating a Report from Relational Data

Packt
24 Jun 2010
2 min read
(For more resources on JasperReports, see here.) Getting ready You will need PostgreSQL to follow this recipe. Refer to the installPostgreSQL.txt file included in the source code download (chap4), which shows how you will install and run PostgreSQL. Note that your installation of PostgreSQL should be up and running before you proceed. The source code for this article also includes a file named CreateDbIntoPGS.txt, which will help you to create a database named jasperdb5. How to do it... The following simple steps will show you how to connect iReport to a database: Run iReport; it will open with a Welcome Window, as shown in the following screenshot: If you have not made any database connection so far in your iReport installation, you will see an Empty datasource shown selected in a drop-down list just below the main menu. Click on the Report Datasources icon shown encircled to the right of the drop-down list, as shown in the following screenshot: A new window named Connections / Datasources will open, as shown in the following screenshot. This window lists an Empty datasource as well as the datasources you have made so far. Click the New button shown at the top right of the Connections / Datasources window. This will open a new Datasource selection window, as shown in the following screenshot: You will see Database JDBC connection is selected by default. Click the Next button at the bottom of the Datasource window. A new window named Database JDBC connection will open, as shown in the following screenshot: Enter PG as the name for your new database connection in the input box beside the Name field. PG is just a name for the database connection you are creating. You can give any name and create any number of database connections. Click on the JDBC Driver drop-down list; it will drop-down to show a list of available JDBC drivers. As you are connecting to the PostgreSQL database, select the Postgre SQL (org.postgresql.Driver) option from the drop-down list, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 1790

article-image-trivadis-integration-architecture-blueprint-implementation-scenarios
Packt
24 Jun 2010
4 min read
Save for later

The Trivadis Integration Architecture Blueprint: Implementation scenarios

Packt
24 Jun 2010
4 min read
(For more resources on Trivadis Integration and SOA, see here.) Service-oriented integration scenarios These scenarios show how the service-oriented integration business patterns can be implemented. These business patterns are as follows: Process integration: The process integration pattern extends the 1: N topology of the broker pattern. It simplifies the serial execution of business services, which are provided by the target applications. Workflow integration: The workflow integration pattern is a variant of the serial process pattern. It extends the capability of simple serial process orchestration to include support for user interaction in the execution of individual process steps. Implementing the process integration business pattern In the scenario shown in the following diagram, the process integration business pattern is implemented using BPEL. Trigger: An application places a message in the queue. Primary flow: The message is extracted from the queue through JMS and a corresponding JMS adapter. A new instance of the BPEL integration process is started and the message is passed to the instance as input. The integration process orchestrates the integration and calls the systems that are to be integrated in the correct order. A content-based router in the mediation layer is responsible for ensuring that the correct one of the two systems is called. However, from a process perspective, this is only one stage of the integration. In the final step, a "native" integration of an EJB session bean is carried out using an EJB adapter. Variant with externalized business rules in a rule engine A variant of the previous scenario has the business rules externalized in a rule engine, in order to simplify the condition logic in the integration process. This corresponds to the external business rules variant of the process integration business pattern, and is shown in the form of a scenario in the following diagram: Trigger: The JEE application sends an SOAP request. Primary flow: The SOAP request initiates a new instance of the integration process. The integration process is implemented as before, with the exception that in this case, a rule engine is integrated before evaluating the condition. The call to the rule engine from BEPL takes the form of a web service call through SOAP. Other systems can be integrated via a DB adapter as shown here, for example to enable them to write to a table in an Oracle database. Variant with batch-driven integration process In this variant, the integration process is initiated by a time-based event. In this case, a job scheduler added before the BPEL process triggers an event at a specified time, which starts the process instance. The process is started by the scheduler via a web service call. The following diagram shows the scenario: Trigger: The job scheduler building block does a web service request at a specified time. Primary flow: The call from the job scheduler via SOAP initiates a new integration process instance. As in the previous variants, the BPEL process executes the necessary integration steps and, depending on the situation, integrates one system via a database adapter, and the other directly via a web service call. Implementing the workflow business pattern In this scenario, additional user interaction is added to the integration process scenario. As a result, the integration process is no longer fully automated. It is interrupted at a specific point by interaction with the end user, for example to obtain confirmation for a certain procedure. This scenario is shown in the following diagram: Trigger: An application places a message in the queue. Primary flow: The message is removed from the queue by the JMS adapter and a new instance of the integration process is started. The user interaction takes place through the asynchronous integration of a task service. It creates a new task, which is displayed in the user's task list. As soon as the user has completed the task, the task service returns a callback to the relevant instance of the integration process, and by that, informs the process of the user's decision. The integration process responds to the decision and executes the remaining steps.
Read more
  • 0
  • 0
  • 3769

article-image-trivadis-integration-architecture-blueprint
Packt
24 Jun 2010
7 min read
Save for later

The Trivadis Integration Architecture Blueprint

Packt
24 Jun 2010
7 min read
(For more resources on Trivadis Integration and SOA, see here.) Introduction With the widespread use of service-oriented architecture (SOA), the integration of different IT systems has gained a new relevance. The era of isolated business information systems—so-called silos or stove-pipe architectures—is finally over. It is increasingly rare to find applications developed for a specific purpose that do not need to exchange information with other systems. Furthermore, SOA is becoming more and more widely accepted as a standard architecture. Nearly all organizations and vendors are designing or implementing applications with SOA capability. SOA represents an end-to-end approach to the IT system landscape as the support function for business processes. Because of SOA, functions provided by individual systems are now available in a single standardized form throughout organizations, and even outside their corporate boundaries. In addition, SOA is finally offering mechanisms that put the focus on existing systems, and make it possible to continue to use them. Smart integration mechanisms are needed to allow existing systems, as well as the functionality provided by individual applications, to be brought together into a new fully functioning whole. For this reason, it is essential to transform the abstract concept of integration into concrete, clearly structured, and practical implementation variants. The Trivadis Integration Architecture Blueprint indicates how integration architectures can be implemented in practice. It achieves this by representing common integration approaches, such as Enterprise Application Integration (EAI); Extract, Transform, and Load (ETL); event-driven architecture (EDA); and others, in a clearly and simply structured blueprint. It creates transparency in the confused world of product developers and theoretical concepts. The Trivadis Integration Architecture Blueprint shows how to structure, describe, and understand existing application landscapes from the perspective of integration. The process of developing new systems is significantly simplified by dividing the integration architecture into process, mediation, collection and distribution, and communication layers. The blueprint makes it possible to implement application systems correctly without losing sight of the bigger picture: a high performance, flexible, scalable, and affordable enterprise architecture. Standards, components, and patterns used The Trivadis Integration Architecture Blueprint uses common standardized techniques, components, and patterns, and is based on the layered architecture principle. A layered architecture divides the overall architecture into different layers with different responsibilities. Depending on the size of the system and the problem involved, each layer can be broken down into further layers. Layers represent a logical construct, and can be distributed across one or more physical tiers. In contrast to levels, layers are organized hierarchically, and different layers can be located on the same level. Within the individual layers, the building blocks can be strongly cohesive. Extensive decoupling is needed between the layers. The rule is that higher-level layers can only be dependent on the layers beneath them and not vice versa. Each building block in a layer is only dependent on building blocks in the same layer, or the layers beneath. It is essential to create a layer structure that isolates the most important cohesive design aspects from one another, so that the building blocks within the layers are decoupled. The blueprint is process oriented, and its notation and structure are determined by the blueprint's dependencies and information flow in the integration process. An explanation of how the individual layers, their building blocks, and tasks can be identified from the requirements of the information flow is given on the basis of a simple scenario. In this scenario, the information is transported from one source to another target system using an integration solution. In the blueprint, the building blocks and scenarios are described using familiar design patterns from different sources: (Hohpe, Wolf 2004) (Adams et al. 2001) (Coral8 2007) (Russel et al. 2006) These patterns are used in a shared context on different layers. The Trivadis Integration Architecture Blueprint includes only the integration-related parts of the overall architecture, and describes the specific view of the technical integration domain in an overall architecture. It focuses on the information flow between systems in the context of domain-driven design. Domain-driven design is a means of communication, which is based on a profound understanding of the relevant business domain. This is subsequently modeled specifically for the application in question. Domain models contain no technical considerations and are restricted exclusively to business aspects. Domain models represent an abstraction of a business domain, which aims to capture the exemplary aspects of a specific implementation for this domain. The objectives are: To significantly simplify communication between domain experts and developers by using a common language (the domain model) To enable the requirements placed on the software to be defined more accurately and in a more targeted way It must be possible to describe, specify, and document the software more precisely and more comprehensibly, using a clearly defined language, which will make it easier to maintain The technical aspects of architecture can be grouped into domains in order to create specific views of the overall system. These domains cover security, performance, and other areas. The integration of systems and information also represents a specific view of the overall system, and can be turned into a domain. Integration domain is used to mean different things in different contexts. One widely used meaning is "application domain," in other words, a clearly defined, everyday problem area where computer systems and software are used. Enterprise architectures are often divided into business and technical domains: Business domains may include training, resource management, purchasing, sales or marketing, for example. Technical domains are generally areas such as applications, integration, network, security, platforms, systems, data, and information management. The blueprint, however, sees integration as a technical domain, which supports business domains, and has its own views that can be regarded as complementary to the views of other architecture descriptions. In accordance with Evans (Evans, 2004), the Trivadis Integration Architecture Blueprint is a ubiquitous language for describing integration systems. This and the structure of the integration domain on which it is based, have been tried and tested in a variety of integration projects using different technologies and products. The blueprint has demonstrated that it offers an easy-to-use method for structuring and documenting implementation solutions. As domain models for integration can be formulated differently depending on the target platform (for example, an object-oriented system or a classic ETL solution), the domain model is not described in terms of object orientation. Instead, the necessary functionality takes the form of building blocks (which are often identical with familiar design patterns) on a higher level of abstraction. This makes it possible to use the blueprint in a heterogeneous development environment with profitable results. An architecture blueprint is based on widely used, tried-and-tested techniques, components, and patterns, which are grouped into a suitable structure to meet the requirements of the target domain. The concepts, the functionality, and the building blocks to be implemented are described in an abstract form in blueprints. These are then replaced or fine-tuned by product-specific building blocks in the implementation project. Therefore, the Trivadis Integration Architecture Blueprint has been deliberately designed to be independent of individual vendors, products, and technologies. It includes integration scenarios and proposals that apply to specific problems, and can be used as aids during the project implementation process. The standardized view of the integration domain and the standardized means of representation enable strategies, concepts, solutions, and products to be compared with one another more easily in evaluations of architectures. The specifications of the blueprint act as guidelines. Differences between this model and reality may well occur when the blueprint is implemented in a specific project. Individual building blocks and the relationships between them may not be needed, or may be grouped together. For example, the adapter and mapper building blocks may be joined together to form one component in implementation processes or products.
Read more
  • 0
  • 0
  • 5797
article-image-material-management-using-compiere-3
Packt
24 Jun 2010
3 min read
Save for later

Material Management Using Compiere 3

Packt
24 Jun 2010
3 min read
(Read more interesting articles on Compiere  here.) Material Management Material management within Compiere focuses on the physical side of storing and tracking items that are defined as being physically stocked. Central to this is the warehouse and its locators, into which and from where products are received, moved or shipped. In this article we will deal with Compiere standard functionality. An advanced Warehouse Management module with additional features is also available. Warehouse Overview Warehouses belong to Organizations, and it is recommended that you have a one-to-one relationship if user security role access is an issue, because roles are organization specific. Warehouses can have multiple locators and one default locator is selected. Warehouses and locators are set up through the Warehouse & Locators window: On the Locator tab, the warehouse locators are defined as follows: Adjusting Product Quantities Product quantities are adjusted through the Physical Inventory and Internal Use inventory windows. Physical Inventory adjustments are made during inventory counts or ad hoc manual inventory quantity adjustments, while Internal Use Inventory adjustments are made when items are expensed directly to a specific charge account: Physical Inventory Entry Updating material item quantities is done through a physical inventory transaction.The book (system) values are updated to the applicable quantities counted, and the adjustment is passed to the product. An example of this would be for a product with a book quantity of 10 and a physical quantity of 20, where an adjustment of a positive quantity of 10 will be made. We shall demonstrate the process of quantity counting to perform a physical adjustment. Preparing a quantity count is done through the Physical Inventory window: Create a count list of a Product Category: Note that you can also set the Inventory Count to Zero, which would indicate a blind count. The correct count quantities need to be updated for each product and location, and the Physical Inventory transaction completed to correct the stock quantities: Internal Use Inventory Internal use inventory transactions are used for where products are written off or expensed, and not necessarily sold or shipped to customers. The transaction window Internal Use Inventory is completed for this purpose: In the example illustrated below, the Product Quantity is charged to Marketing Expenses, based on its default Unit of Measure on the Internal Use Inventory line, as follows: Moving Inventory There are two reasons for moving inventory: External: Material Shipments to Customers and Material Receipts from Vendors. Internal: Internal Warehouse movements within the warehouse. Movements between warehouses are also regarded as external and explicit. Material shipment and receipt documents need to be created as such (also refer to the Compiere concept or Counter Documents where, in such cases, explicit inter-organization counter transactions can be automatically created, if this has been set up). Material Shipments to Customers Shipments are processed with reference to the Sales Order control document. We have previously explained that shipments occur based on the shipping rules defined in the Sales Order. Manual shipments are processed when the Standard Order sales order document type is used. Processing a manual shipment (Generate Shipment from Order) is done through the Generate Shipments (manual) window: A shipment with lines linked to the Sales Order lines will be created for this customer. This shipment can then be printed as a delivery note: The default printed shipment document will look like the example shown in the following screenshot:
Read more
  • 0
  • 0
  • 1706

article-image-debugging-java-programs-using-jdb
Packt
23 Jun 2010
6 min read
Save for later

Debugging Java Programs using JDB

Packt
23 Jun 2010
6 min read
In this article by Nataraju Neeluru, we will learn how to debug a Java program using a simple command-line debugging tool called JDB. JDB is one of the several debuggers available for debugging Java programs. It comes as part of the Sun's JDK. JDB is used by a lot of people for debugging purposes, for the main reason that it is very simple to use, lightweight and being a command-line tool, is very fast. Those who are familiar with debugging C programs with gdb, will be more inclined to use JDB for debugging Java programs. We will cover most of the commonly used and needed JDB commands for debugging Java programs. Nothing much is assumed to read this article, other than some familiarity with Java programming and general concepts of debugging like breakpoint, stepping through the code, examining variables, etc. Beginners may learn quite a few things here, and experts may revise their knowledge. (For more resources on Java, see here.) Introduction JDB is a debugging tool that comes along with the Sun's JDK. The executable exists in JAVA_HOME/bin as 'jdb' on Linux and 'jdb.exe' on Windows (where JAVA_HOME is the root directory of the JDK installation). A few notes about the tools and notation used in this article: We will use 'jdb' on Linux for illustration throughout this article, though the JDB command set is more or less same on all platforms. All the tools (like jdb, java) used in this article are of JDK 5, though most of the material presented here holds true and works in other versions also. '$' is the command prompt on the Linux machine on which the illustration is carried out. We will use 'JDB' to denote the tool in general, and 'jdb' to denote the particular executable in JDK on Linux. JDB commands are explained in a particular sequence. If that sequence is changed, then the output obtained may be different from what is shown in this article. Throughout this article, we will use the following simple Java program for debugging: public class A{ private int x; private int y; public A(int a, int b) { x = a; y = b; } public static void main(String[] args) { System.out.println("Hi, I'm main.. and I'm going to call f1"); f1(); f2(3, 4); f3(4, 5); f4(); f5(); } public static void f1() { System.out.println("I'm f1..."); System.out.println("I'm still f1..."); System.out.println("I'm still f1..."); } public static int f2(int a, int b) { return a + b; } public static A f3(int a, int b) { A obj = new A(a, b); obj.reset(); return obj; } public static void f4() { System.out.println("I'm f4 "); } public static void f5() { A a = new A(5, 6); synchronized(a) { System.out.println("I'm f5, accessing a's fields " + a.x + " " + a.y); } } private void reset() { x = 0; y = 0; }} Let us put this code in a file called A.java in the current working directory, compile it using 'javac -g A.java' (note the '-g' option that makes the Java compiler generate some extra debugging information in the class file), and even run it once using 'java A' to see what the output is. Apparently, there is no bug in this program to debug it, but we will see, using JDB, how the control flows through this program. Recall that, this program being a Java program, runs on a Java Virtual Machine (JVM). Before we actually debug the Java program, we need to see that a connection is established between JDB and the JVM on which the Java program is running. Depending on the way JDB connects to the JVM, there are a few ways in which we can use JDB. No matter how the connection is established, once JDB is connected to the JVM, we can use the same set of commands for debugging. The JVM, on which the Java program to be debugged is running, is called the 'debuggee' here. Establishing the connection between JDB and the JVM In this section, we will see a few ways of establishing the connection between JDB and the JVM. JDB launching the JVM: In this option, we do not see two separate things as the debugger (JDB) and the debuggee(JVM), but rather we just invoke JDB by giving the initial class (i.e., the class that has the main() method) as an argument, and internally JDB 'launches' the JVM. $jdb AInitializing jdb ... At this point, the JVM is not yet started. We need to give 'run' command at the JDB prompt for the JVM to be started. JDB connecting to a running JVM: In this option, first start the JVM by using a command of the form: $java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=6000 AListening for transport dt_socket at address: 6000 It says that the JVM is listening at port 6000 for a connection. Now, start JDB (in another terminal) as: $jdb -attach 6000Set uncaught java.lang.ThrowableSet deferred uncaught java.lang.ThrowableInitializing jdb ...>VM Started: No frames on the current call stack main[1] At this point, JDB is connected to the JVM. It is possible to do remote debugging with JDB. If the JVM is running on machine M1, and we want to run JDB on M2, then we can start JDB on M2 as: $jdb -attach M1:6000 JDB listening for a JVM to connect: In this option, JDB is started first, with a command of the form: $jdb -listen 6000Listening at address: adc2180852:6000 This makes JDB listen at port 6000 for a connection from the JVM. Now, start the JVM (from another terminal) as: $java -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=6000 A Once the above command is run, we see the following in the JDB terminal: Set uncaught java.lang.ThrowableSet deferred uncaught java.lang.ThrowableInitializing jdb ...>VM Started: No frames on the current call stack main[1] At this point, JDB has accepted the connection from the JVM. Here also, we can make the JVM running on machine M1 connect to a remote JDB running on machine M2, by starting the JVM as: $java -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=M2:6000 A
Read more
  • 0
  • 0
  • 8244
Modal Close icon
Modal Close icon