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-ubuntu-910-how-upgrade
Packt
18 Nov 2009
5 min read
Save for later

Ubuntu 9.10: How To Upgrade

Packt
18 Nov 2009
5 min read
So the new Ubuntu is here and you’re just dying to upgrade and have a look at all the new features! With just a few simple steps you'll be up and running the new system in no time! Before you dive right in, there are a few things you should know, and a few ways to (hopefully) make your upgrade process more pleasant. This article is broken up into sections outlining the preparation, requirements and upgrade steps needed for each platform. It is important to follow the steps in order to ensure a full and painless upgrade. Also, please follow only one of the upgrade paths. In other words, there are different methods for a Desktop as compared to a Server. You only need to follow those steps applicable to you. A Note Regarding Upgrades vs Fresh Installations You may be wondering whether it is better to upgrade your current installation or do a fresh install from CD. There are benefits to doing a fresh installation to be sure, but there are also benefits to upgrading your system in place. I know people that swear by one method, and others that swear by another. In the end, both methods are supported and will give you the same Ubuntu experience. Fresh installations will require a complete wipe of your hard disk. This means that you'll need to backup any important documents, pictures or other files that you'll want to keep. Have you ever done a fresh installation before and realized only too late that you forgot to back something up? I have. It's easy to miss something. Using the in-place upgrade methods found in this article you won't need to worry about backups. With an in-place upgrade you can generally keep working on your machine while applications are upgraded in the background. This means you can continue to browse the web or send and receive email while the system is upgraded. Bottom line is that upgrades are thoroughly tested and just as well supported as fresh installations. Preparation When upgrading your system from one release to the next, there are certain requirements that you must meet in order to be successful. First of all, and most importantly in this instance, this upgrade path is only possible from Ubuntu 9.04 "Jaunty Jackalope" to Ubuntu 9.10 "Karmic Koala". If you are using a release previous to 9.04 (8.10 or earlier), stop now. This upgrade process will not work, is not supported and will likely cause problems. If you are unsure which version you have installed, you can run this command in your terminal to find out. (Applications > Accessories > Terminal) lsb_release -a If you find that you are on a release previous to Ubuntu 9.04, you will need to decide whether it is best to do a fresh installation or do an incremental upgrade leading up to 9.10. Incremental upgrades, as well as fresh installations are beyond the scope of this article, but there is detailed documentation on the matter found here: https://help.ubuntu.com/community/UpgradeNotes Updates Once you have verified that you are using Ubuntu 9.04 "Jaunty Jackalope" you will be able to begin the upgrade proccess. In order for the latest version to become available to you, you'll need to apply any pending updates to your current version. There are two ways to apply available updates pending a system upgrade. The first method applies to the graphical Desktop or Laptop platform. The second method applies to a server, or non-graphical installation. Remember, please only follow the steps applicable to you. Graphical Updates (Pre-Upgrade) If you are using the graphical environment you can check for and apply updates by way of the Update Manager tool. This can be found by navigating to: (System > Administration > Update Manager). This tool will automatically scan for and list any pending updates. Be sure to apply all available updates before moving to the next step. You can ensure that there are no more pending updates by clicking Check and verifying that it displays the message "Your system is up to date". Command Line Updates (Pre-Upgrade) For those more comfortable with the command line interface, or those running a non-graphical Server installation, you can run the following command to check for and apply any available system updates. sudo aptitude update && sudo aptitude safe-upgrade && sudo aptitude full-upgrade Apply any updates that are pending from the command above before you move to the next step. You can repeat this command until no more updates are offered to ensure you are ready. Now that you have applied the remainder of the updates for your current system, you can move to the next step. In the next step, Selecting a Mirror, you will learn how to use an alternate, often faster, package repository for your updates. This means that instead of using the default and often overwhelmed main Ubuntu servers for updates you can configure your system to use one closer to you. This often results in faster downloads and upgrades.
Read more
  • 0
  • 0
  • 13470

article-image-restful-java-web-services-design
Packt
18 Nov 2009
5 min read
Save for later

RESTful Java Web Services Design

Packt
18 Nov 2009
5 min read
We'll leave the RESTful implementation for a later article. Our sample application is a micro-blogging web service (similar to Twitter), where users create accounts and then post entries. Finally, while designing our application, we'll define a set of steps that can be applied to designing any software system that needs to be deployed as a RESTful web service. Designing a RESTful web service Designing RESTful web services is not different from designing traditional web applications. We still have business requirements, we still have users who want to do things with data, and we still have hardware constraints and software architectures to deal with. The main difference, however, is that we look at the requirements to tease out resources and forget about specific actions to be taken on these resources. We can think of RESTful web service design as being similar to Object Oriented Design (OOD). In OOD, we try to identify objects from the data we want to represent together with the actions that an object can have. But the similarities end at the data structure definition, because with RESTful web services we already have specific calls that are part of the protocol itself. The underlying RESTful web service design principles can be summarized in the following four steps: Requirements gathering—this step is similar to traditional software requirement gathering practices. Resource identification—this step is similar to OOD where we identify objects, but we don't worry about messaging between objects. Resource representation definition—because we exchange representation between clients and servers, we should define what kind of representation we need to use. Typically, we use XML, but JSON has gained popularity. That's not to say that we can't use any other form of resource representation—on the contrary, we could use XHTML or any other form of binary representation, though we let the requirements guide our choices. URI definition—with resources in place, we need to define the API, which consists of URIs for clients and servers to exchange resources' representations. This design process is not static. These are iterative steps that gravitate around   resources. Let's say that during the URI definition step we discover that one of the URI's responses is not covered in one of the resources we have identified. Then we go back to define a suitable resource. In most cases, however, we find that the resources that we already have cover most of our needs, and we just have to combine existing resources into a meta-resource to take care of the new requirement. Requirements of sample web service The RESTful web service we design in this article is a social networking web application similar to Twitter. We follow an OOD process mixed with an agile philosophy for designing and coding our applications. This means that we create just enough documentation to be useful, but not so much that we spend an inordinate amount of time deciphering it during our implementation phase. As with any application, we begin by listing the main business requirements, for which we have the following use cases (these are the main functions of our application): A web user creates an account with a username and a password (creating an account means that the user is now registered). Registered users post blog entries to their accounts. We limit messages to 140 characters. Registered and non-registered users view all blog entries. Registered and non-registered users view user profiles. Registered users update their user profiles, for example, users update their password. Registered and non-registered users search for terms in all blog entries. However simple this example may be, social networking sites work on these same principles: users sign up for accounts to post personal updates or information. Our intention here, though, is not to fully replicate Twitter or to fully create a social networking application. What we are trying to outline is a set of requirements that will test our understanding of RESTful web services design and implementation. The core value of social networking sites lies in the ability to connect to multiple users who connect with us, and the value is derived from what the connections mean within the community, because of the tendency of users following people with similar interests. For example, the connections between users create targeted distribution networks.The connections between users create random graphs in the graph theory sense, where nodes are users and edges are connections between users. This is what is referred to as the social graph. Resource identification Out of the use cases listed above, we now need to define the service's resources. From reading the requirements we see that we need users and messages. Users appear in two ways: a single user and a list of users. Additionally, users have the ability to post blog entries in the form of messages of no more than 140 characters. This means that we need resources for a single message and a list of messages. In sum, we identify the following resources: User List of users Message List of messages
Read more
  • 0
  • 0
  • 11057

article-image-restful-web-service-implementation-resteasy
Packt
18 Nov 2009
2 min read
Save for later

RESTful Web Service Implementation with RESTEasy

Packt
18 Nov 2009
2 min read
Getting the tools If you have already downloaded and installed Java's JDK and the Tomcat web server, you only need to download the JBoss's RESTEasy framework. Nevertheless, the complete list of the software needed for this article is as follows: Software Web Location Java JDK http://java.sun.com/ Apache Tomcat http://tomcat.apache.org/download-60.cgi Db4o http://developer.db4o.com/files/default.aspx RESTEasy Framework http://www.jboss.org/resteasy/ Install the latest Java JDK along with the latest version of Tomcat, if you haven't done so. Download and install Db4o and RESTEasy. Remember the location of the installs, as we'll need the libraries to deploy with the web application. RESTEasy — a JAX-RS implementation   RESTEasy is a full open source implementation of the JAX-RS specification. This framework works within any Java Servlet container, but because it's developed by JBoss, it offers extra features that are not part of the JAX-RS requirements. For example, RESTEasy offers out-of-the-box Atom support and also offers seamless integration with the EJB container portion of JBoss (none of these features are explored here). Web service architecture By now, you should be familiar with the coding pattern. Because we want to reuse a large portion of code already written, we have separate layers of abstraction. In this article, therefore, we only talk about the web layer and study in detail how to implement a full RESTful web service using RESTEasy. The full architecture of our web service looks as follows: In this diagram, we depict clients making HTTP requests to our web service. Each request comes to the web container, which then delegates the request to our RESTful layer that is composed of RESTEasy resource classes. The actual serialization of user and message records is delegated to our business layer, which in turns talks directly to our database layer (a Db4o database). Again, RESTEasy is a platform independent framework and works within any Servlet container. For this article we deploy our web service in Tomcat, as we've been working with it so far and are now familiar with deploying web applications to it, though we could as easily use the JBoss web container.
Read more
  • 0
  • 0
  • 3825

article-image-joomla-15-blogging-and-rss-feeds
Packt
18 Nov 2009
7 min read
Save for later

Joomla! 1.5 Blogging and RSS Feeds

Packt
18 Nov 2009
7 min read
  Blogging is a great way to get more traffic to your site and communicate with the community interested in the same topics as you. Search engines such as Yahoo! and Google love blogs because of the fact that articles written in blogs are mostly up-to-date and they get the information about the update of a blog really fast using RSS Feeds and Pings. Articles posted on a blog with these two options in place can get into the search engine indexes within hours, sometimes even minutes. How is blogging good for SEO? Using a blog has some advantages that fair really well if you want to have more visibility in the search engines. We will be looking at some of those advantages and how they can affect your search engine rankings. I am not saying blogging is easy, but it is very rewarding. Creating fresh content Creating short articles about your favorite topic and publishing them on a regular basis is the best way to get into the search engine results pages faster. The number one thing about blogging is that you can write long articles or short articles. The combination of the two different formats won't break the flow of your site, unlike a normal web site, where you mostly write articles that are built with a certain length. You can also state an opinion about things that are going on in your community and write news items. All that in one web site without worrying too much about how to structure all the information. A structure is needed for SEO and Joomla! will force you to use the structure you have chosen for your site. Using Joomla! as a blog will make it easier for you as you will be using the categories created in advance to hold that information for you. Google and blog indexing If you set up a blog and start using the sites and services we will be looking at, like FeedBurner and Technorati, you will notice that the major search engines also use these services to index blog sites and find new posts really fast. Now Google even owns FeedBurner! You will not only syndicate your articles using options such as RSS Feeds, but you will also push your articles through Technorati, the number one site to show your blog to bloggers. Google has a special tool with some basic categorization in place for searching blogs; you can find it at http://blogsearch.google.com. One good thing about this blog search tools is that it will show you how "old" a blog post is. For example, under the title you will see a statement such as 10 hours ago just to prove how fast you can get an article indexed from a blog. Setting up Joomla! as a blog Joomla! was not built to be a blog in its basic form, unlike WordPress. However, Joomla! has a built-in layout function called Blog layout that can be used for sections and categories. RSS Feeds are also built in, but we need to put an extra component in place to get a commenting system. First things first, let's set up the basic structure of your Joomla! based blog. How to structure your blog section The first thing you need to do is to come up with a section name for your blog. You already have an extended keywords list, so it should not be difficult to set up a blog. In my example site I have set up a Section called Garden Pools Blog and the Alias I want to use is garden-pools. This alias is going to be included in the SEF URL and contains some of the keywords I want to target with the blog. Once that is ready, you need to create the main categories, which of course will be the main topics of your blog section. Choosing your blog categories Again you need to find the right keywords to put into your category names. The best thing you can do now is to focus on the topic you want to blog about. It is really essential that you think about these categories and name them the right way, or you will get into trouble later on. Once you know about the SEF URLs, you might find yourself in trouble if you have the same category names as in the main site. In my category for this blog I have used the category name Water Gardens, depending on my choice of URL construction in the sh404SEF component. It is possible that I may not use the same category name for the main topics of my site. If I were to use the same category name they both would get the URL http://www.cblandscapegardening/water-gardens/, leaving one of the categories not reachable. One workaround would be to change the alias of one of the categories, but that would still leave a duplicate title on your site which you would need to change. Google would show it as a possible duplicate title in its webmaster content analysis. You can prevent this by choosing your categories wisely. Therefore, it is important to think about these URL structures, when you start naming and creating the blog categories. Stay focused and limit yourself If you start naming the categories make sure you stay on the same blog topic and keep the terms as relevant as possible. Don't create too many categories as you are going to create a separate menu for the blog. Too many categories will fill your menu with a long list of topics, and the visitors will not be able to choose from this long list. It is also not a pretty sight to have such a long list in your sidebar. Limiting yourself to a smaller section of categories, which you want to connect your articles to, will help you to stay more relevant to the topic of your choice. Creating a blog menu Once you have set up your categories, it's time to create your blog menu. Start with creating a new menu and call it whatever you want to, give it a title like The Garden Blog as in my example site. To set this feature go to your administrator panel and choose Menus | Main Menu from the menu bar at the top. After that choose New. Make it short and to the point so that it is really easy to find it on your site. Go to the Extensions menu, choose Module Manager, and Publish the module in the location you want it to show on your site. The first thing you should do is create a link to the section in which you are going to put your blog posts, and change the Parameters(Basic) to match the layout you want:   #Leading is set to 1, which means one full length article to start with   #Intro is set the 6, so you have the introduction text (that is the text before the "read more" link) from six articles, getting a total of seven on the blog page   Columns is set to 1 to get a complete overview of the articles in a listing that is not broken into two columns after the first Intro article   #Links this is the number of links with the title of older articles that don't show on the blog page anymore After setting the Parameters(Basic) you need to set the Parameters(Advanced) as well:   Change the Category Order to Order and the Primary Order to Most recent first.   Make sure you have the Show a Feed Link set to Yes—only for this menu item. This option is set so that we can get a full RSS Feed over all the blog categories For a blog, you need to change some of the settings in the Parameters(Component):     For a blog you need to Show the Author Name, the Created Date and Time, the Show Navigation, and the Read more... Link   The Article Rating/Voting depends on you, for me its set to off, as I don't like the dotted rating icons. The commenting system will give your visitors the ability to share their thoughts about your article, rather than just rate them, unlike the rating system. You will learn more about such a commenting system later in this article.
Read more
  • 0
  • 0
  • 1869

article-image-keeping-extensions-secure-joomla-15-part-2
Packt
18 Nov 2009
15 min read
Save for later

Keeping Extensions Secure with Joomla! 1.5: Part 2

Packt
18 Nov 2009
15 min read
Making a directory path safe When we poke around in the server filesystem, we want to make sure that we know what we are doing. If we are dealing with directories, Joomla! provides us with some easy ways to make sure that those directories are being safely referenced. Failure to properly sanitize directory paths can lead to major security vulnerabilities. For example, if we were attempting to remove a directory, a security vulnerability could allow the deletion of the completely wrong resource! For more information about external control of paths, refer to CWE-73. A directory path is a URL to a directory. A directory path does not include a file. To safely manage a path to a file, refer to the next recipe, Making a path safe. How to do it... The static JFolder class, which is a part of the joomla.filesystem library, provides us with all sorts of useful methods for working with folders. To use the class, we must import it. jimport('joomla.filesystem.folder'); This bit is nice and easy. We use the JFolder::makeSafe() method and pass the name of the folder we want to sanitize. This method returns a string that can be used to interact safely with a folder. // make the directory path safe$safeDirPath = JFolder::makeSafe($unsafeDirPath); The one downside of JFolder::makeSafe() is that it assumes that the directory separators are correctly defined in the original string. For example, while running on a *nix system, if the string contained Windows-style backslashes instead of *nix style forward slashes, those slashes would be stripped. We can use the static JPath class to overcome this, as follows: // import JPath and JFolderjimport('joomla.filesystem.path');jimport('joomla.filesystem.folder');// clean the path$cleanDirPath = JPath::clean($unsafeDirPath);// make the directory path safe$safeDirPath = JFolder::makeSafe($cleanDirPath); This time we have included the JPath::clean() method prior to making the path safe. For more information about JPath, refer to the next recipe, Making a path safe. Directory separators The correct way to add directory separators in Joomla! is to use the DS constant. For example, the path to bar from foo is expressed as 'foo' . DS . 'bar'. How it works... What exactly does the JFolder::makeSafe() method do to guarantee that the directory path is safe? It strips out any characters or character sequences that are seen as posing potential security risks. The following list describes the characters that are considered safe: Alphanumeric (a-z, A-Z, and 0-9) Colon Dash Directory separators—the exact character sequence will depend on the environment Space Underscore The following table shows some examples of input and output strings from the JFolder::makeSafe() and JPath::clean() methods running on a Windows system (DS == ''). This is intended to show why using the two together can be preferable. If we choose to use the two together, order of usage is important. We should always use the JPath::clean() method first and the JFolder::makeSafe() method next. Although, as the fourth example shows, sometimes it can be worth cleaning a second time, which means clean, make safe, and clean.   Original   Clean   Safe   Clean and safe   foobar   foobar   foobar   foobar   //foo/bar   foobar   foobar   foobar   foo bar   foo bar   foo20bar   foo20bar   foo bar/..   foo bar..   foo bar   foo bar   /foo"   foo"   foodel   foodel   del *.*   del *.*       See also For information about safely dealing with files, refer to the previous recipe, Making a filename safe. For information about dealing with paths, please refer to the next recipe, Making a path safe. Making a path safe This recipe is similar to the previous two recipes, Making a filename safe and Making a directory path safe. This recipe differs in that it is for a complete path, normally to a file. There is a whole raft of security issues associated with processing paths. The following list identifies some of the more common issues we need to be aware of: CWE-22: Path traversal CWE-73: External control of filename or path CWE-98: Insufficient control of filename for include/require statement in PHP program (aka 'PHP file inclusion') CWE-434: Unrestricted file upload All of these vulnerabilities can have serious consequences, which should not be overlooked. For example, a malicious user could upload a destructively tailored script file and then execute it. Luckily, Joomla! provides us with some easy ways to reduce the risks associated with these potential weaknesses. Getting ready Before we delve into some of the complex ways of safely dealing with paths, let's start small. If we browse a basic installation of Joomla!, we will discover a large number of empty index.html files. These files prevent directory listings. Most web servers automatically generate directory listings if we visit a directory in which there are no index files. We should always add a copy of the empty index.html file to every directory in our extension. The use of empty index.html files provides a form of security through obscurity. This is only intended to be a very basic safeguard and should never be relied on for complete protection. For more information, refer to CWE-656. The second thing we should do is ensure that all of our PHP files can only be executed if the _JEXEC constant has been defined. This is used to make sure that the file has been executed from within Joomla!, that is, make sure it is not being used as a standalone script or is included from a script other than Joomla! // Check file executed from within Joomla!defined('_JEXEC') or die('Restricted access'); How to do it... If we are retrieving a path value from a request variable, we can use the PATH type. This type is not entirely what it seems, as a PATH type cannot be an absolute path and cannot reference hidden files and folders. This means it cannot start with any form of directory separator, as it would in a *nix environment, or a drive identifier, as it would in a Windows environment. It also means that none of the folder names or the optional filename can start with a period (a *nix hidden file/folder). If a value does not reach these criteria, the return value will be null. Therefore, it is very important to consider the suitability of the PATH type before opting to use it. // get the value of myPath from the request$myPath = JRequest::getVar('myPath', 'default', 'REQUEST', 'PATH'); On its own, the PATH type does not really constitute a security measure. For example, it does not protect against the path traversal CWE-22. Once we have our path variable, it is time to clean it. Cleaning is done in Joomla! using the static JPath class. Cleaning resolves any issues with directory separators. The exact process depends on the filesystem directory separator, for example a back or forward slash. The point is that if the directory separators in the string are incorrect, they are corrected as necessary. // import the JPath classjimport('joomla.filesystem.path');// clean $myPath$myPath = JPath::clean($myPath); Like the PATH type, a cleaned path does not really constitute a security measure. For example, it too does not protect against path traversal CWE-22. OK, we've heard enough about not constituting a security measure. Now it's time to overcome that problem. The static JPath class includes the JPath::check() method, which checks for path traversal and also that the path is within the Joomla! installation. The only constraint is that the method can only deal with absolute paths. Remember the PATH type used in JRequest can only cope with relative paths. Therefore, if we use the PATH type, we must convert it to an absolute path before using the JPath::check() method. // check for path traversal and snoopingJPath::check($myPath); The odd thing about this method is that we don't really do anything with the result! There is a very good reason for this. If the check fails, Joomla! will exit and display a suitable error message. In some instances, this may not be appropriate. Unfortunately, there is nothing we can do to prevent this. Therefore, if we want to avoid this we will have to check the path ourselves. Generally speaking, if a path fails the check, it is likely that an attack has been attempted. For that reason, exiting Joomla! is probably the most suitable response. However, the JPath::check() method does have one serious limitation. It only checks for snooping outside of the Joomla! root directory. We can manually check that we are only looking in a specified area in the Joomla! installation. // create path which must be the root of the directory$safePath = JPATH_COMPONENT . DS . 'safeFolder' . DS;// check for snooping outside of $safePathif (strpos($myPath, $safePath) !== 0) { JError::raiseError(20, 'Snooping out of bounds'); jexit();}// check for file traversaljimport('joomla.filesystem.path');JPath::check($directory); Essentially, this only ensures that the start of the $myPath string is equivalent to $safePath. We deal with failures in the same way as the JPath::check() method. Notice that we still use the JPath::check() method because we can still effectively use this method to check for file traversal. See also The previous two recipes, Making a filename safe and Making a directory path safe, discuss how to work safely with filenames and paths. We can also use filesystem permissions to secure files and folders. Safely retrieving request data Almost 99% of the time, security vulnerabilities in PHP applications such as Joomla! are caused by inadequate input parsing and validation CWE-20. We access request data in Joomla! using the static JRequest class. Built into this class is the ability to cast values to specific types and to mask data. We cannot rely solely on JRequest to ensure that incoming data is safe. This is where validation comes into play. Input data always has definable constraints. For example, we might define an entity identifier as a positive integer no less than 1 and no greater than 4294967295 (the maximum value for an unsigned MySQL INT). If we can define the constraints, we can also check that the input adheres to the constraints. Validating strings tend to be more complex. This is because strings are highly versatile and can contain many different characters. One thing we should always bear in mind when dealing with string validation is the effect of different character encodings. Joomla! 1.5 is UTF-8 compliant. UTF-8 is a Unicode variable-size multibyte character encoding that enables the encoding of many different alphabets and symbols that would otherwise be unavailable. As PHP is not UTF-8 aware, we should always use the static JString methods instead of the PHP string functions when dealing with UTF-8 strings. Getting ready Prior to doing anything, it is worth defining and documenting the boundaries of all the input that we use in our extension. This may include value ranges and formats. This can be a lengthy task, but it will help to ensure that our extension is secure. How to do it... The most important thing we must do when accessing request data is to use JRequest. Even if we just want the raw values, JRequest forms an important part of the Joomla! framework. Even before we get a chance to execute any code in our extension, JRequest will have already performed vital security work in an attempt to prevent global variable injection, CWE-471. So where do we begin? We start with the simple JRequest::getVar() method. This method is used to safely get at the request data. There are five parameters, of which only the first is required. The following example shows how we use the first three of these parameters: // gets the value of name$value = JRequest::getVar('nameOfVar');// gets the value of name,// if name is not specified returns defaultValue$value = JRequest::getVar('nameOfVar', 'defaultValue');// gets the value of name,// if name is not specified returns defaultValue// name is retrieved from the GET request data$value = JRequest::getVar('nameOfVar', 'defaultValue', 'GET'); The third parameter can be any of the following values:   Value Description COOKIE HTTP Cookies ENV Environment variables FILES Uploaded file details GET HTTP GET variables POST HTTP POST variables REQUEST Combination of GET, POST, and COOKIE; this is the default SERVER Server and environment variables In most instances, REQUEST (the default) should be sufficient. The only time we need to use GET and POST explicitly is when we are expecting a request to use a specific HTTP method. For added security, we can restrict a request to a certain HTTP method using the static JRequest::getMethod() method, as shown in the following example: if (JRequest::getMethod() != 'GET') { jexit('UNEXPECTED REQUEST METHOD');} There's more... The following two subsections discuss the last two parameters, $type and $mask. It is in the last two parameters where the security benefits of JRequest become very apparent. Casting Strictly speaking, casting is not an accurate description of the fourth JRequest::getVar() parameter. The types that we can cast to are not the types that we would use to describe a variable. For example, WORD is not a PHP or Joomla! type, but it is an available option. The following example extracts an integer representation of the GET request value, nameOfVar: // gets the value of nameOfVar,// if nameOfVar is not specified returns 0// name is retrieved from the GET request data// casts the return value as an integer$int = JRequest::getVar('nameOfVar', 0, 'GET', 'INT'); Hey presto! We have a safe value that we know is an integer. Had we not included the parameter to cast the value, we would not have been able to guarantee that $int was in fact an integer. Of course, we could have used the PHP intval() function or cast the value ourselves using (int). Not all of the types we can cast to are as simple as an integer; for example, ALNUM is used to strip non-alphanumeric characters from a string value. JRequest also provides alias methods that allow us to achieve the same thing, but with less code. For example, we can quickly extract an integer. The following example is the same as the previous example: $int = JRequest::getInt('nameOfVar', 0); The following table describes all of the types we can cast to using JRequest. Note that only the most commonly used types have alias methods. Type   Description   Alias   DEFAULT   Aggressive cleaning occurs to remove all detected code elements     ALNUM   Alphanumeric string; strips all non-ASCII letters and numbers     ARRAY   Force array cast     BASE64   Base64 string; strips all non Base64 characters, which is useful for passing encoded data in a URL, for example a return URL     BOOL or BOOLEAN   Force Boolean cast   getBool()   CMD   Command; strips all non-alphanumeric, underscore, period, and dash characters, which is ideal for values such as task   getCmd()   FLOAT or DOUBLE   Floating point number   getFloat()   INT or INTEGER   Whole number   getInt()   PATH   Filesystem path; used to identify a resource in a filesystem, for example the path to an image to use as a logo (relative paths only)     STRING   String; often used with a mask to clean the data   getString()   USERNAME   Username; strips characters unsuitable for use in a username, including non-printing characters (for example a backspace), angled brackets, double and single quotation marks, percent signs, and ampersands     WORD   Word; strips all non-alpha and underscore characters   getWord()     By default, the most aggressive mask is applied. This will remove code, such as HTML and JavaScript, from the data. The next section describes how we use masks. Masking strings The fifth JRequest::getVar() parameter defines a mask. Masks are used in JRequest to define what is and isn't allowed in a string value. By default no masking is applied, which means that very aggressive security measures are taken to ensure that the incoming data is as safe as possible. While this is useful, it is not always appropriate. For example, the core component com_content allows users to enter HTML data in an article. Without a mask, this information would be stripped from the request data. There are three constants we can use to easily define the mask we want to apply. These are JREQUEST_NOTRIM, JREQUEST_ALLOWRAW, and JREQUEST_ALLOWHTML. The following example shows how we can use these: // using getVar$string = JRequest::getVar('nameOfVar', 'default', 'REQUEST', 'STRING', JREQUEST_ALLOWRAW);// using getString alias$string = JRequest::getString('nameOfVar', 'default', 'REQUEST', JREQUEST_ALLOWRAW); The following examples show how the output varies depending on the mask that we apply: # Original input value 1 <p>Paragraph <a onClick="alert('foobar');">link</a></p> 2 CSS <link type="text/css", href="http://somewhere/nasty.css" /> 3 space at front of input 4 &ltp&gtPara&lt/p&gt # Output value (No mask) 1 Paragraph link 2 CSS 3 space at front of input 4 &ltp&gtPara&lt/p&gt    
Read more
  • 0
  • 0
  • 1174

article-image-applying-special-effects-3d-game-development-microsoft-silverlight-3-part-1
Packt
18 Nov 2009
7 min read
Save for later

Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

Packt
18 Nov 2009
7 min read
  A 3D game must be attractive. It has to offer amazing effects for the main characters and in the background. A spaceship has to fly through a meteor shower. An asteroid belt has to draw waves while a UFO pursues a spaceship. A missile should make a plane explode. The real world shows us things moving everywhere. Most of these scenes, however, aren't repetitive sequences. Hence, we have to combine great designs, artificial intelligence (AI), and advanced physics to create special effects. Working with 3D characters in the background So far, we have added physics, collision detection capabilities, life, and action to our 3D scenes. We were able to simulate real-life effects for the collision of two 3D characters by adding some artificial intelligence. However, we need to combine this action with additional effects to create a realistic 3D world. Players want to move the camera while playing so that they can watch amazing effects. They want to be part of each 3D scene as if it were a real life situation. How can we create complex and realistic backgrounds capable of adding realistic behavior to the game? We can do this combining everything we have learned so far with a good object-oriented design. We have to create random situations combined with more advanced physics. We have to add more 3D characters with movement to the scenes. We must add complexity to the backgrounds. We can work with many independent physics engines to work with parallel worlds. In real-life, there are concurrent and parallel words. We have to reproduce this behavior in our 3D scenes. Time for action – adding a transition to start the game Your project manager does not want the game to start immediately. He wants you to add a butt on in order to allow the player to start the game by clicking on it. As you are using Balder, adding a butt on is not as simple as expected. We are going to add a butt on to the main page, and we are going to change Balder's default game initialization: Stay in the 3DInvadersSilverlight project. Expand App.xaml in the Solution Explorer and open App.xaml.cs––the C# code for App.xaml. Comment the following line of code (we are not going to use Balder's services in this class):  //using Balder.Silverlight.Services; Comment the following line of code in the event handler for the Application_Startup event, after the line this.RootVisual = new MainPage();: //TargetDevice.Initialize<InvadersGame>(); Open the XAML code for MainPage.xaml and add the following lines of code after the line (You will see a butt on with the ti tle Start the game.): <!-- A button to start the game --><Button x_Name="btnStartGame" Content="Start the game!" Canvas.Left="200" Canvas.Top="20" Width="200" Height="30" Click="btnStartGame_Click"></Button> Now, expand MainPage.xaml in the Solution Explorer and open MainPage.xaml.cs––the C# code for MainPage.xaml. Add the following line of code at the beginning (As we are going to use many of Balder's classes and interfaces.): using Balder.Silverlight.Services; Add the following lines of code to program the event handler for the button's Click event (this code will initialize the game using Balder's services): private void btnStartGame_Click(object sender, RoutedEventArgs e){ btnStartGame.Visibility = Visibility.Collapsed; TargetDevice.Initialize<InvadersGame>();} Build and run the solution. Click on the Start the game! butt on and the UFOs will begin their chase game. The butt on will make a transition to start the game, as shown in the following screenshots:   What just happened? You could use a Start the game! butt on to start a game using Balder's services. Now, you will be able to offer the player more control over some parameters before starting the game. We commented the code that started the game during the application start-up. Then, we added a button on the main page (MainPage). The code programmed in its Click event handler initializes the desired Balder.Core.Game subclass (InvadersGame) using just one line: TargetDevice.Initialize<InvadersGame>(); This initialization adds a new specific Canvas as another layout root's child, controlled by Balder to render the 3D scenes. Thus, we had to make some changes to add a simple butt on to control this initialization. Time for action – creating a low polygon count meteor model The 3D digital artists are creating models for many aliens. They do not have the time to create simple models. Hence, they teach you to use Blender and 3D Studio Max to create simple models with low polygon count. Your project manager wants you to add dozens of meteors, to the existing chase game. A gravitational force must attract these meteors and they have to appear in random initial positions in the 3D world. First, we are going to create a low polygon count meteor using 3D Studio Max. Then, we are going to add a texture based on a PNG image and export the 3D model to the ASE format, compatible with Balder. As previously explained, we have to do this in order to export the ASE format with a bitmap texture definition enveloping the meshes. We can also use Blender or any other 3D DCC tool to create this model. We have already learned how to export an ASE format from Blender. Thus, this time, we are going to learn the necessary steps to do it using 3D Studio Max. Start 3D Studio Max and create a new scene. Add a sphere with six segments. Locate the sphere in the scene's center. Use the Uniform Scale tool to resize the low polygon count sphere to 11.329 in the three axis, as shown in the following screenshot: Click on the Material Editor button. Click on the first material sphere, on the Material Editor window's upper-left corner. Click on the small square at the right side of the Diffuse color rectangle, as shown in the following screenshot: Select Bitmap from the list shown in the Material/Map Browser window that pops up and click on OK. Select the PNG file to be used as a texture to envelope the sphere. You can use Bricks.PNG, previously downloaded from http://www.freefoto.com/. You just need to add a reference to a bitmap file. Then, click on Open. The Material Editor preview panel will show a small sphere thumbnail enveloped by the selected bitmap, as shown in the following screenshot: Drag the new material and drop it on the sphere. If you are facing problems, remember that the 3D digital artist created a similar sphere a few days ago and he left the meteor.max file in the following folder (C:Silverlight3DInvaders3D3DModelsMETEOR). Save the file using the name meteor.max in the previously mentioned folder. Now, you have to export the model to the ASE format with the reference to the texture. Therefore, select File | Export and choose ASCII Scene Export (*.ASE) on the Type combo box. Select the aforementioned folder, enter the file name meteor.ase and click on Save. Check the following options in the ASCII Export dialog box. (They are unchecked by default): Mesh Normals Mapping Coordinates Vertex Colors The dialog box should be similar to the one shown in the following screenshot: Click on OK. Now, the model is available as an ASE 3D model with reference to the texture. You will have to change the absolute path for the bitmap that defines the texture in order to allow Balder to load the model in a Silverlight application.
Read more
  • 0
  • 0
  • 2844
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 $19.99/month. Cancel anytime
article-image-datagrid-api-ibm-websphere-extreme-scale-6-part-2
Packt
18 Nov 2009
21 min read
Save for later

The DataGrid API with IBM WebSphere eXtreme Scale 6: Part 2

Packt
18 Nov 2009
21 min read
Aggregate results One thing to be aware of with the MapGridAgent interface is its potential for a partition to send huge result maps to a client. This is the nature of the map function. Its output size can be proportional to its input size if we don't use a query to select    specific objects to work with or specify a key set. In this case, we need a specific result for every key, with the key set as narrow as we can make it. We then just need to deal with large maps once in a while. What if we need an aggregate result for a key set? Instead of an operation and result for each element, we need an operation over all elements with just one result. Simple examples include the highest or lowest number in a set, and the earliest or total payroll expenses in a management hierarchy. In these examples, we need data from a set of elements in a partition, but we don't need a result for each. We only want one result for the entire set of objects. Going back to our functional programming reference, this is where the reduce function shines. Like the map function, reduce has a corresponding grid agent interface. The reduce function takes a collection of input keys and only produces one result for the entire collection. The result is typically an aggregate result: a sum, product, max, min, average, or any other aggregate function. Classes that implement ReduceGridAgent are used as parameters to the AgentManager#callReduceAgent(ReduceGridAgent agent, Collection keys) and AgentManager#callReduceAgent(agent) methods. The implementation itself is similar to the MapGridAgent pattern. The reduce grid agent we write operates on a collection of known keys or an unknown key set. If we have a known key set, then we will run the agent with AgentManager#callReduceAgent(agent, keys). If the key set is not known, and if we need a query to find the interesting objects, then we will call the AgentManager#callReduceAgent(agent). Let's write a ReduceGridAgent that finds the largest integer in a set. We'll start with a naïve implementation for finding the largest integer in an array: public int findLargestInteger(Integer[] ints) {int largestInt = ints[0];for (int i = 0; i < ints.length; i++) {if (ints[i] > largestInt) {largestInt = ints[i];}}return largestInt;} Implementing ReduceGridAgent requires three methods. Two of those methods look like the process methods in MapGridAgent. We have ReduceGridAgent#reduce(session, map, keys) and ReduceGridAgent#reduce(session, map). Like its MapGridAgent counterparts, the reduce method that accepts keys in the signature works with keys or Entity objects. The reduce method without keys in the signature should use a Query to find the objects most interesting to our business logic. public class LargestIntReduceAgent implements ReduceGridAgent,EntityAgentMixin {public Object reduce(Session session, ObjectMap map,Collection keys) {MyInteger largestInt = null;Iterator iter = keys.iterator();while (iter.hasNext()) {(MyInteger)myInt = (MyInteger)iter.next();if (myInt.greaterThan(largestInt)) {largestInt = myInt;}}return largestInt;}public Object reduce(Session session,ObjectMap map) {// Nothing to do for now!}public Object reduceResults(Collection results) {// Nothing to do for now!}public Class getClassForEntity() {return MyInteger.class;}} The first reduce method is similar in signature to the MapGridAgent#process(session, map, key) method. The difference here is that the third argument in ReduceGridAgent#reduce(session, map, keys) is a collection of keys rather than one key. This immediately illustrates the difference between the two. A Map operation takes place on only one element. Reduce operates on the entire collection. With a known key set, the ReduceGridAgent#reduce(session, map, keys) method is called. Without a key set passed to the AgentManager#callReduceAgent(agent) method, the GridReduceAgent#reduce(session, map) method is called. This method should use a Query to ?  nd the objects we want to use in our business logic. The keys or entity objects can then be passed to the ReduceGridAgent#reduce(session, map, keys) method for the actual business logic. We submit this agent to the grid in almost the same way as we submit a MapGridAgent to the grid. AgentManager has two callReduceAgent methods. The first takes a collection of keys as an argument, while the second does not. Submitting this agent to the grid looks like this: Collection numbers = new ArrayList();for(int i = 0; i < 10000; i++) {numbers.add(i);}ReduceGridAgent agent = new LargestIntReduceAgent();AgentManager am = session.getMap("MyInteger").getAgentManager();am.callReduceAgent(agent, numbers); This looks so similar to submitting a MapGridAgent to the grid and you may miss the method change to am.callReduceAgent(agent, keys). The programming models are so similar you may ask why there isn't just one generic callAgent method. Take a look at the ReduceGridAgent, particularly the ReduceGridAgent#reduceResults(results)  method. This method is called on the client side after all instances of the agent return their results. At this point, we have a collection of results for each partition. It is acceptable for the AgentManager#callMapAgent(agent, keys) to return the merged results here. AgentManager#callReduceAgent(agent, keys) must return one result for the entire operation. The ReduceGridAgent#reduceResults(results) method aggregates each partition's aggregate results: public class LargestIntReduceAgent implements ReduceGridAgent,EntityAgentMixin {public Object reduce(Session session, ObjectMap map,Collection keys) {return findLargestInt(keys);}public Object reduce(Session session,ObjectMap map) {// Nothing to do for now!}public Object reduceResults(Collection results) {findLargestInt(results);}public Class getClassForEntity() {return MyInteger.class;}private MyInteger findLargestInt(Collection keys) {MyInteger largestInt = null;Iterator iter = keys.iterator();while (iter.hasNext()) {(MyInteger)myInt = (MyInteger)iter.next();if (myInt.greaterThan(largestInt)) {largestInt = myInt;}}return largestInt;}} ReduceGridAgent#reduceResults(keys) is responsible for producing the final result passed back to the AgentManager#callReduceAgent(agent, keys) caller. Sometimes, the reduce operation performed in this final aggregation is the same as the operation performed in the ReduceGridAgent#reduce(session, map, keys) method. Sometimes, the operation is different. In our case, it is the same, and we refactor the reduce operation into a private method. Finishing off the ReduceGridAgent, we come to ReduceGridAgent#reduce(session, map). The method signature is similar to MapGridAgent#processAllEntries(session, map) and should be a hint that they have a similar purpose. The ReduceGridAgent#reduce(session, map) is called when a key list is not provided to AgentManager#callReduceAgent(agent). ReduceGridAgent#reduce(session, map) should limit the number of objects used in the reduce operation. Like MapGridAgent#processAllEntries(session, map), we typically use a Query. While the reduce agent does not send large results back to the client, we still care about finding objects that meet our criteria to use in the reduce operation: public Object reduce(Session session,ObjectMap map) {EntityManager em = session.getEntityManager();Query q = em.createQuery("select m from MyInteger m " +"where m.integer > 0 " +"and m.integer < 10000");Iterator iter = q.getResultIterator();Collection<MyInteger> keys = new ArrayList<MyInteger)();while (iter.hasNext()) {MyInteger mi = (MyInteger)iter.next();keys.add(mi);}return reduce(session, map, keys);} Though these are not strict rules, this method usually follows a pattern like MapGridAgent#processAllEntries(session, map). Run a query to limit the number of objects used in the reduce operation. Create a collection of keys used by the reduce operation. We're using entities here. Rather than duplicating the reduce operation in this method, we use put entities from the Query in the key collection. ReduceGridAgent#reduce(session, map, keys), when using Entities, expects a collection of MyInteger objects. Call ReduceGridAgent#reduce(session, map, keys) using the key collection we just created. There is no rule against re-implementing the reduce operation in each method but we'll be good software engineers and keep it DRY. If we can massage the query results into arguments, the reduce method accepts, and then we have enough reason to reuse it. At this point, we can submit this agent to the grid with or without a set of known keys and get the largest MyInteger back. In both, the MapGridAgent and ReduceGridAgent, we used a Query to limit the number of objects used in each operation: Query q = em.createQuery("select m from MyInteger m " +"where m.integer > 0 " +"and m.integer < 10000");Iterator iter = q.getResultIterator(); Obviously, this query is limited in what it can do. The criteria is hardcoded into the query. This query can only find MyIntegers with values between 0 and 10,000. Initially, we hardcoded these values because the agent runs on a partition in a container. Fortunately, we can pass additional data along with our agent.   Using ephemeral objects in agents In the previous examples, we hard coded the query criteria in the process and reduce methods. We should let the client-side program set those parameters instead of dictating what range of numbers the queries operate on. Right now, our queries are limited to exactly what is coded. A grid agent is just a POJO. It can have fields, getter and setter methods, and any other methods outside of the implemented grid agent interface. It's probably best to limit functionality to grid agent functionality but that doesn't mean that we can't have fields or other objects on the implementing class. Classes that implement the agent interfaces are POJOs. We'll send additional data to the grid by adding fields to the implementing class: public class LargestIntReduceAgent implements ReduceGridAgent,EntityAgentMixin {private Integer minValue;private Integer maxValue;// Reduce methods omitted for brevitypublic void setMinValue(Integer min) {this.minValue = min;}public void setMaxValue(Integer max) {this.maxValue = max;}} The only requirement for sending these additional fields to the grid is that they must each be serializable. Sending these objects to the grid is probably a one-way trip. Unless they're passed back as part of a map result, we cannot use them to communicate the state between client and grid. The grid agent instance used on the client side does not get a copy of the state of grid agent variables when the agents finish execution in the grid. Including grid state objects in the result set is bad practice and unnecessary. Before we pass the agent to AgentManager#callReduceAgent(agent), we set the fields used in the partition-side query: ReduceGridAgent agent = new LargestIntReduceAgent();agent.setMinValue(500);agent.setMaxValue(5000);AgentManager am = session.getMap("MyInteger").getAgentManager();am.callReduceAgent(agent); The ReduceGridAgent#reduce(session, map) method requires a small change to use our new query parameters: public Object reduce(Session session,ObjectMap map) {EntityManager em = session.getEntityManager();Query q = em.createQuery("select m from MyInteger m " +"where m.integer > ?1 " +"and m.integer < ?2");query.setParameter(1, minValue);query.setParameter(2, maxValue);Iterator iter = q.getResultIterator();Collection<MyInteger> keys = new ArrayList<MyInteger)();while (iter.hasNext()) {MyInteger mi = (MyInteger)iter.next();keys.add(mi);}return reduce(session, map, keys);} It's almost the same as before. We've just parameterized the query. It now uses the two values we sent into the grid with the agent. We can send more than query parameters along with an agent. We can send additional, complex business logic. If we obey the principles of object-oriented design, then we favor composition over inheritance. This allows the composition of agents with complex map or reduce operations, without cluttering the agent implementation class with business logic. To demonstrate, we'll refactor the findLargestInt(collection) method out of the LargestIntReduceAgent class: public interface MyHelper {public MyInteger call(Collection keys);}public class AgentHelper implements MyHelper, Serializeable {public MyInteger call(Collection keys) {MyInteger largestInt = null;Iterator iter = keys.iterator();while (iter.hasNext()) {(MyInteger)myInt = (MyInteger)iter.next();if (myInt.greaterThan(largestInt)) {largestInt = myInt;}}return largestInt;}} This is just a class that encapsulates the method formerly known as findLargestInt(collection). The name changed to conform to an imaginary calling convention is used by our agents. The ReduceGridAgent changes a bit to accommodate this calling convention: public class LargestIntReduceAgent implements ReduceGridAgent,EntityAgentMixin {private Integer minValue;private Integer maxValue;private MyHelper helper;public Object reduce(Session session, ObjectMap map,Collection keys) {return helper.call(keys);}public Object reduce(Session session,ObjectMap map) {EntityManager em = session.getEntityManager();Query q = em.createQuery("select m from MyInteger m " +"where m.integer > ?1 " +"and m.integer < ?2");query.setParameter(1, minValue);query.setParameter(2, maxValue);Iterator iter = q.getResultIterator();Collection<MyInteger> keys = new ArrayList<MyInteger)();while (iter.hasNext()) {MyInteger mi = (MyInteger)iter.next();keys.add(mi);}return reduce(session, map, keys);}public Object reduceResults(Collection results) {helper.call(results);}public getClassForEntity() {return MyInteger.class;}public void setMinValue(Integer min) {this.minValue = min;}public void setMaxValue(Integer max) {this.maxValue = max;}public void setHelper(MyHelper helper) {this.helper = helper;}} LargestIntReduceAgent's concern is interacting with the grid. Refactoring the findLargestInt method into different classes keeps our code clean and more easily testable. It also allows algorithm replacement. If we come up with a better map or a reduce method, then the GridAgent implementation doesn't change. LargestIntReduceAgent calls the helper.call(collection) method. The AgentHelper class is serialized with the agent and sent to each partition the agent is sent to. Once on the grid, the AgentHelper#call(collection) method is available to the agent. The normal Java serialization process handles agent serialization. Anything serializable in that processes is sent to the grid. Serializing these objects, and sending them to the grid requires that the appropriate class files be on the classpath of each ObjectGrid container process before the agent is sent to the grid. Updates with agents The agents we've seen so far are idempotent. They do not change any objects in the grid. They create new objects as a result of their operation but the objects queried by the agents remained unchanged. There is no rule against updating objects in an agent. Any operation valid inside an ObjectGrid transaction can also be performed in an agent, including inserts, updates, and deletes. In this way, an agent doesn't necessarily need to perform a map or reduce operation. It acts as a code transport between the client and server. We should be cautious with this relaxed approach to agents because there is a lot of potential for abuse. Used with caution, running agents on the grid for inserts, updates, and deletes creates a powerful application controlled by submitting agents to the grid. Building an application around agents reduces the need for running large numbers of client processes. Let's go back to our payment processor example to look at updates using a GridAgent. Specifically, we'll update a batch of deposit payments with a status of BatchStatus.SENT_TO_NETWORK after we receive the payments from the merchant and check for duplicates. We need to make a choice between using a MapGridAgent and a ReduceGridAgent. The choice depends on the behavior our application needs with the result of the operation. If we want to do more work with each payment after it is sent to the network, then we choose a MapGridAgent. Because we only care that the payments are updated, we'll choose the ReduceGridAgent. ReduceGridAgent gives one result for the entire operation, which in this case is the status of the operation, either success or failure. We don't have a particular known key set for all of the payments in a batch. A large batch has payments spread across nearly all partitions. We call our PaymentStatusReduceAgent with the AgentManager#callReduceAgent(agent) method: PaymentStatusReduceAgent agent = new PaymentStatusReduceAgent();agent.setBatch(batch);agent.setFromStatus(PaymentStatus.WAITING);agent.setToStatus(PaymentStatus.SENT_TO_NETWORK);AgentManager am = session.getMap("Payment").getAgentManager();am.callReduceAgent(agent); We use the AgentManager#callReduceAgent(agent) method because we want all partitions in the grid to participate in the reduce operation. The reduce operation begins by finding all payments that match a certain criteria. We want all payments for a batch that have a status of WAITING. We set these properties on the agent so that the AgentManager serializes them and sends them to the grid along with the agent. They are used as query parameters in the ReduceGridAgent#reduce(session, map) method: public Object reduce(Session session,ObjectMap map) {EntityManager em = session.getEntityManager();Query q = em.createQuery("select p from Payment p " +"where p.batch = ?1 " +"and p.status = ?2");query.setParameter(1, batch);query.setParameter(2, fromStatus);Iterator iter = q.getResultIterator();Collection<MyInteger> keys = new ArrayList<MyInteger)();while (iter.hasNext()) {Payment payment = (Payment)iter.next();keys.add(payment);}return reduce(session, map, keys);} We create a collection of payments to pass to the ReduceGridAgent#reduce(session, map, keys) method. In there, we perform the update payment status operations. Instead of an aggregate result based on calculations of objects in the grid, it is based on the success or failure of the update operations to each object. The ReduceGridAgent#reduce(session, map, keys) method returns a  Boolean value if the update succeeds, and throws an exception if it does not: public Object reduce(Session session, ObjectMap map,Collection keys) {try{Session s = session.getObjectGrid().getSession();EntityManager em = s.getEntityManager();Iterator iter = keys.iterator();while (iter.hasNext()) {Payment payment = (Payment)iter.next();payment.setStatus(toStatus);em.merge(payment);}return Boolean.TRUE;} catch(ObjectGridException e) {throw new ObjectGridRuntimeException(e);}} Throwing an exception doesn't exactly follow the spirit of the reduce operation. If the update operation fails, then the exception is thrown up the call stack and across the network to AgentManager#callReduceAgent(agent). If the update operation fails, then we have bigger problems to worry about than the exception uncovered by the update operation. We throw the exception here because the situation is unrecoverable by the reduce operation. A call to ReduceGridAgent#reduceResults(results) is meaningless when there is an exception. Absent from this code are explicit transaction demarcations. When the MapGridAgent and ReduceGridAgent methods are called, they are under an already-active transaction on the session passed in to them. Should the grid agent methods throw an exception, the transaction is rolled back. This transaction is independent of the client transaction and any other active agent transactions. If one of the agent transactions rolls back, then the client transaction rolls back too. We see a few interesting things from the payment update implemented as a reduce operation. In the happy-path case, each agent will return Boolean.TRUE. We only return Boolean.TRUE to conform to the method signature. A collection of values of Boolean.TRUE is passed to the ReduceGridAgent#reduceResults(Collection results) method. There is nothing more to do in the reduce operation. The values in the results collection do not play any part in the update operation. The update was successful. We know this because an exception wasn't thrown in any of the reduce methods. These two things let us implement a very simple ReduceGridAgent#reduceResults(Collection results) method: public Object reduceResults(Collection results) {return null;} Either the update succeeds and we don't need to do any more, or we know the update failed by getting an exception thrown out of the AgentManager#callReduceAgent(agent) method. It may seem strange that we don't  confirm the update is successful. Do we always explicitly check that JDBC updates were successful? No. We assume that because there was no thrown exception, the update happened. The same goes for our update in the ReduceGridAgent. For clarity, let's look at the PaymentStatusReduceAgent in its entirety: public class PaymentStatusReduceAgent implements ReduceGridAgent,EntityAgentMixin {private Batch batch;private PaymentStatus fromStatus;private PaymentStatus toStatus;public Object reduce(Session session, ObjectMap map,Collection keys) {try{Session s = session.getObjectGrid().getSession();EntityManager em = s.getEntityManager();Iterator iter = keys.iterator();em.getTransaction().begin();while (iter.hasNext()) {Payment payment = (Payment)iter.next();payment.setStatus(toStatus);em.merge(payment);}em.getTransaction().commit();return Boolean.TRUE;} catch(ObjectGridException e) {throw new ObjectGridRuntimeException(e);}}public Object reduce(Session session,ObjectMap map) {EntityManager em = session.getEntityManager();Query q = em.createQuery("select p from Payment p " +"where p.batch = ?1 " +"and p.status = ?2");query.setParameter(1, batch);query.setParameter(2, fromStatus);Iterator iter = q.getResultIterator();Collection<MyInteger> keys = new ArrayList<MyInteger)();while (iter.hasNext()) {Payment payment = (Payment)iter.next();keys.add(payment);}return reduce(session, map, keys);}public Object reduceResults(Collection results) {return null;}public getClassForEntity() {return Payment.class;}public void setBatch(Batch b) {this.batch = b;}public void setFromStatus(PaymentStatus status) {this.fromStatus = status;}public void setToStatus(PaymentStatus status) {this.toStatus = status;}} Scheduling agents The AgentManager methods are blocking methods. A method call on any method in AgentManager remains at that point in execution, while the data grid runs the agent instances against its primary partitions. The thread that calls the AgentManager method must wait for a return from the call before it proceeds. In case blocking is unacceptable, we should schedule the call to the AgentManager methods using the java.util.concurrent API. There are two cases to consider when thinking about scheduling agents. The first is with the AgentManager#callReduceAgent(agent) and AgentManager#callMapAgent(agent) methods. These methods do not pass any keys to the agents. In this case, the agent is executed on all primary partitions. It may be okay for a client application to block here while it waits for the result from the grid. Obviously, scheduling insert, update, and delete operations provides some performance improvement, if we work at the client-side in the future, that does not depend on those objects being in the grid (or not, as the case may be). A read operation where the client depends on the result before proceeding probably shouldn't schedule the agent. One case where scheduling read operations is important is when we have multiple sets of keys passed to agents of the same type. Given a large object set, where the objects partition many different primaries, we don't want to pass the entire key set to an agent. For a sufficiently large key set, an agent will spend most of its time processing (ignoring) keys that do not belong to its partition. Instead, we can pre-sort the keys into collections of objects where all belong to the same partition. We then send the smaller, pre-sorted collections to the grid. We determine an object's partition with a PartitionManager. Each BackingMap has a PartitionManager associated with it, which is obtained with the BackingMap#getPartitionManager() method. PartitionManager#getPartition(Object key) returns the 0-based partition number, which is the partition the PartitionManager puts the object in. This is easy when working with the ObjectMap API. Let's assume: MyInteger mi = (MyInteger)myIntMap.get(35);BackingMap map = session.getObjectGrid().getMap("MyInteger");int partitionId = map.getPartitionManager().getPartition(35); We don't need the first line. It only shows that we have a MyInteger with a key of 35. We obtain the ObjectGrid reference, and then the BackingMap for the MyInteger map from the session.  We then call the getPartition(key) method for that same key. The result of this call is the ID of the partition that holds the MyInteger object with the key 35. Now, we can use object and entity keys to sort objects based on partitions. After sorting the objects into smaller collections, we pass them to AgentManager#callMapAgent(agent, keys) and AgentManager#callReduceAgent(agent, keys). These calls should now be scheduled in different threads, rather than making each call in a loop. If we then make these method calls in a loop, we then effectively turn the data grid into an expensive client program. The client program blocks during each call to the AgentManager methods. If we have 20 key collections that map to 20 different partitions, we will send only one request at a time to the grid if we send the agents in a loop. Instead, we want them to execute in parallel. We can do this by sending each instance of grid agent to the grid using a java.util.concurrent.ExecutorService. Summary We covered a lot of ground again in this article. Working with objects where they live produces much higher throughput than dragging objects to a client and pushing them back to the grid when we're done. Co-locating logic and data is easy to do with the DataGrid API. DataGrid gives us a few patterns to follow when writing agents. It also makes us think in terms of map operations and reduce operations. Though these two methods seem limiting at first, they are useful when operating on very large data sets. The    map operation gives us a way to perform an algorithm on each object in a set. The reduce operation lets us create aggregate results from a set. We aren't limited to only sending logic to the grid with an agent. Thanks to Java serialization, we send any serializable object referenced by our agent to the grid along with it. This gives us flexibility in running queries in an agent, and in passing helper logic. We also looked at pre-sorting objects into maps based on their partition ID. This reduces the size of the bytes sent from the client to a partition, and lets the agent run only for keys known to be in the partition the agent runs on. With a little imagination, we can put more work on the grid. This gives us much higher throughput and scales horizontally with the resources given to our grid. Appropriately partitioned, a grid can scale out and return results at a predictable rate, no matter how many objects it stores.
Read more
  • 0
  • 0
  • 1303

article-image-build-advanced-contact-manager-using-jboss-richfaces-33-part-1
Packt
18 Nov 2009
11 min read
Save for later

Build an Advanced Contact Manager using JBoss RichFaces 3.3: Part 1

Packt
18 Nov 2009
11 min read
The main layout Let's start preparing the space for the core features of the application. We want a three-column layout for groups, contacts list, and contact detail. Let's open the home.xhtml file and add a three-column panel grid inside the body: <h:panelGrid columns="3" width="100%" columnClasses="main-group-column, main-contacts-list-column,  main-contact-detail-column"></h:panelGrid> We are using three new CSS classes (one for every column). Let's open the /view/stylesheet/theme.css file and add the following code: .main-group-column { width: 20%; vertical-align: top;}.main-contacts-list-column { width: 40%; vertical-align: top;}.main-contact-detail-column { width: 40%; vertical-align: top;} The main columns are ready; now we want to split the content of every column in a separate file (so we don't have a large and difficult file to read) by using the Facelets templating capabilities—let's create a new folder inside the/view folder called main, and let's create the following empty files inside it: contactsGroups.xhtml contactsList.xhtml contactEdit.xhtml contactView.xhtml Now let's open them and put the standard code for an empty (included) file: <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><ui:composition ><!-- my code here --></ui:composition> Now, we have all of the pieces ready to be included into the home.xhtml file, let's open it and start adding the first column inside h:panelGrid: <a:outputPanel id="contactsGroups"> <ui:include src="main/contactsGroups.xhtml"/></a:outputPanel> As you can see, we surrounded the include with an a:outputPanel that will be used as a placeholder for the re-rendering purpose. Include a Facelets tag (ui:include) into the a:outputPanel that we used in order to include the page at that point. Ajax placeholders A very important concept to keep in mind while developing is that the Ajax framework can't add or delete, but can only replace existing elements in the page.For this reason, if you want to append some code, you need to use a placeholder. RichFaces has a component that can be used as a placeholder—a4j:outputPanel. Inside a4j:outputPanel, you can put other components that use the "rendered" attribute in order to decide if they are visible or not. When you want to re-render all the included components, just re-render the outputPanel, and all will work without any problem. Here is a non-working code snippet: <h:form> <h:inputText value="#{aBean.myText}"> <a4j:support event="onkeyup" reRender="out1" /> </h:inputText></h:form><h:outputText id="out1" value="#{aBean.myText}" rendered="#{not empty aBean.myText}"/> This code seems the same as that of the a4j:support example, but it won't work. The problem is that we added the rendered attribute to outputText, so initially, out1 will not be rendered (because the text property is initially empty and rendered will be equal to false). After the Ajax response, the JavaScript Engine will not find the out1 element (it is not in the page because of rendered="false"), and it will not be able to update it (remember that you can't add or delete elements, only replace them). It is very simple to make the code work: <h:form> <h:inputText value="#{aBean.myText}"> <a4j:support event="onkeyup" reRender="out2" /> </h:inputText></h:form><a4j:outputPanel id="out2"> <h:outputText id="out1" rendered="#{not empty aBean.myText}" value="#{aBean.myText}" /></a4j:outputPanel> As you can see, you just have to put the out1 component inside a4j:outputPanel (called out2) and tell a4j:support to re-render out2 instead of out1. Initially, out2 will be rendered but empty (because out1 will not be rendered). After the Ajax response, the empty out2 will be replaced with markup elements that also contain the out1 component (that is now visible, because the myText property is not empty after the Ajax update and the rendered property is true). A very important concept to keep in mind while developing is that the Ajax framework can't add or delete, but can only replace existing elements of the page. For this reason, if you want to append some code, you need to use a placeholder. The groups box This box will contain all the contacts groups, so the user will be able to organize contacts in different groups in a better way. We will not implement the group box features in this article. Therefore, by now the group column is just a rich:panel with a link to refresh the contact list. Let's open the contactsGroups.xhtml file and insert the following code: <h:form> <rich:panel> <f:facet name="header"> <h:outputText value="#{messages['groups']}" /> </f:facet> <h:panelGrid columns="1"> <a:commandLink value="#{messages['allContacts']}" ajaxSingle="true" reRender="contactsList"> <f:setPropertyActionListener value="#{null}" target="#{homeContactsListHelper.contactsList}" /> </a:commandLink> </h:panelGrid> </rich:panel></h:form> As you can see, we've put a three-column h:panelGrid (to be used in the future) and a:commandLink, which just sets the contactsList property of the homeContactListHelper bean (that we will see in the next section) to null, in order to make the list be read again. At the end of the Ajax interaction, it will re-render the contactsList column in order to show the new data. Also, notice that we are still supporting i18n for every text using the messages property; the task to fill the messages_XX.properties file is left as an exercise for the user. The contacts list The second column inside h:panelGrid of home.xhtml looks like: <a:outputPanel id="contactsList"> <ui:include src="main/contactsList.xhtml"/></a:outputPanel> As for groups, we used a placeholder surrounding the ui:include tag. Now let's focus on creating the data table—open the /view/main/contactsList.xhtml file and add the first snippet of code for dataTable: <h:form> <rich:dataTable id="contactsTable" reRender="contactsTableDS" rows="20" value="#{homeContactsListHelper.contactsList}" var="contact"> <rich:column width="45%"> <h:outputText value="#{contact.name}"/> </rich:column> <rich:column width="45%"> <h:outputText value="#{contact.surname}"/> </rich:column> <f:facet name="footer"> <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"/> </f:facet> </rich:dataTable> <h:outputText value="#{messages['noContactsInList']}" rendered="#{homeContactsListHelper.contactsList.size()==0}"/></h:form> We just added the rich:dataTable component with some columns and an Ajax data scroller at the end. Differences between h:dataTable and rich:dataTable RichFaces provides its own version of h:dataTable, which contains more features and is better integrated with the RichFaces framework. The first important additional feature, in fact, is the skinnability support following the RichFaces standards. Other features are row and column spans support (we will discuss it in the Columns and column groups section), out-of-the-box filter and sorting (discussed in the Filtering and sorting section), more JavaScript event handlers (such as onRowClick, onRowContextMenu, onRowDblClick, and so on) and the reRender attribute. Like other data iteration components of the RichFaces framework, it also supports the partial-row update. Data pagination Implementing Ajax data pagination using RichFaces is really simple—just decide how many rows must be shown in every page by setting the rows attribute of dataTable (in our case, we've chosen 20 rows per page), and then "attach" the rich:datascroller component to it by filling the for attribute with the dataTable id: <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"/> Here you can see another very useful attribute (renderIfSinglePage) that makes the component hidden when there is just a single page in the list (it means the list contains a number of items that is less than or equal to the value of the rows attribute). A thing to keep in mind is that the rich:datascroller component must stay inside a form component (h:form or a:form) in order to work. Customizing rich:datascroller is possible not only by using CSS classes (as usual), but also by personalizing our own parts using the following facets: pages controlsSeparator first, first_disabled last, last_disabled next, next_disabled previous, previous_disabled fastforward, fastforward_disabled fastrewind, fastrewinf_disabled Here is an example with some customized facets (using strings): <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"> <f:facet name="first"> <h:outputText value="First" /> </f:facet> <f:facet name="last"> <h:outputText value="Last" /> </f:facet></rich:datascroller> Here is the result: You can use an image (or another component) instead of text, in order to create your own customized scroller. Another interesting example is: <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"> <f:facet name="first"> <h:outputText value="First"/> </f:facet> <f:facet name="last"> <h:outputText value="Last"/> </f:facet> <f:attribute name="pageIndexVar" value="pageIndexVar"/> <f:attribute name="pagesVar" value="pagesVar"/> <f:facet name="pages"> <h:panelGroup> <h:outputText value="Page #{pageIndexVar} / #{pagesVar}"/> </h:panelGroup> </f:facet></rich:datascroller> The result is: By setting the pageIndexVar and pagesVar attributes, we are able to use them in an outputText component, as we've done in the example. A useful attribute of the component is maxPages that sets the maximum number of page links (the numbers in the middle), which the scroller shows—therefore, we can control the size of it. The page attribute could be bound to a property of a bean, in order to switch to a page giving the number—a simple use-case could be using an inputText and a commandButton, in order to let the client insert the page number that he/she wants to go to. Here is the code that shows how to implement it: <rich:datascroller for="contactsList" maxPages="20" fastControls="hide" page="#{customDataScrollerExampleHelper.scrollerPage}" pagesVar="pages" id="ds"> <f:facet name="first"> <h:outputText value="First" /> </f:facet> <f:facet name="first_disabled"> <h:outputText value="First" /> </f:facet> <f:facet name="last"> <h:outputText value="Last" /> </f:facet> <f:facet name="last_disabled"> <h:outputText value="Last" /> </f:facet> <f:facet name="previous"> <h:outputText value="Previous" /> </f:facet> <f:facet name="previous_disabled"> <h:outputText value="Previous" /> </f:facet> <f:facet name="next"> <h:outputText value="Next" /> </f:facet> <f:facet name="next_disabled"> <h:outputText value="Next" /> </f:facet> <f:facet name="pages"> <h:panelGroup> <h:outputText value="Page "/> <h:inputText value="#{customDataScrollerExampleHelper. scrollerPage}" size="4"> <f:validateLongRange minimum="0" /> <a:support event="onkeyup" timeout="500" oncomplete="#{rich:component('ds')}. switchToPage(this.value)" /> </h:inputText> <h:outputText value=" of #{pages}"/> </h:panelGroup> </f:facet></rich:datascroller> As you can see, besides customizing the text of the First, Last, Previous, and Next sections, we defined a pages facet by inserting h:inputText connected with an integer value inside a backing bean. We also added the a:support tag, in order to trim the page change after the keyup event is completed. We've also set the timeout attribute, in order to call the server every 500 ms and not every time the user types. You can see a screenshot of the feature here:
Read more
  • 0
  • 0
  • 1601

article-image-formatting-and-enhancing-your-moodle-materials-part-2
Packt
18 Nov 2009
8 min read
Save for later

Formatting and Enhancing Your Moodle Materials: Part 2

Packt
18 Nov 2009
8 min read
Images If you've taken digital images, or scanned images onto your computer, it's likely that they'll be high resolution images, ready for printing. We don't need high resolution images on our computer screens for two good reasons: screen resolutions can't show so much detail and they take up a lot of storage space. There's a process called optimization which you can use to make your images more usable for your language learning activities. You can either use a program like Photoshop Elements (commercial), or Google's Picasa, which is free from http://picasa.google.com. These will enable you to edit your pictures and get the best quality with the smallest storage size. Let's look at a few things you can do to enhance your images using Picasa. Cropping Imagine we've taken this picture, but we're only interested in using the picture of the mug for a vocabulary exercise. Open up Picasa. Click on the photo we want to edit. Click on Basic Fixes and then on Crop. Click on Manual in the drop-down menu, then select the bit of the image we want to crop (cut out). Then click on Apply. The result will be: Color balance As it stands, the picture is too dark. There is too little contrast. Picasa will also allow us to create a stronger contrast, just by clicking on Tuning and Fill light and then moving the button across to brighten up the picture. The final picture looks like this: It's smaller and brighter than the original and more appropriate for our Moodle page. Optimization and image size The picture above is 340 kb in storage size, which is pretty big. The reason it's so big in storage size is that its real size is 837 px in width and 960 px in height. In case you're new to image measurement, px stands for pixels, which are the dots on your screen. So we have an unnecessarily large image. We can reduce the image size when we insert an image, but it's a much better idea to reduce the dimensions to what we actually need before we import the image into Moodle. That will reduce the storage size at the same time. Another reason for resizing images is that if you're using several photos on the same page, you'll achieve a much greater sense of balance and therefore effectiveness if all your images are the same size. If we reduce the mug to 100 px in width, the final version is only 92 kb in size. We can resize images in Picasa by exporting, emailing, or uploading our photos to Picasa Web Albums. When we select File | Export, we can select what size we want. Videos One exciting way of enhancing your web pages in Moodle is to use video. You can either upload videos to your own Moodle site or upload them to a site like YouTube, or TeacherTube. Mashable at http://mashable.com/category/video is an excellent source of ideas and resources for editing, uploading, and sharing your videos. If you decide to upload your videos onto your Moodle site, you'll need to check their size and the upload limits on your Moodle site. The default limits are usually quite low, but you can get your administrator to change them. You can also get round this problem by uploading your videos direct to the server using an FTP program. You will need to ask your Moodle administrator for help with that. Embedding videos will save your server's storage space and traffic. Adding subtitles to your videos One way of making video content more accessible for language learners is to add same-language subtitles. This would work well as an extension to the read and listen activity. Alternatively, you could get students to produce the subtitles, a rather glamorous type of dictation. If you want to add subtitles to your own videos, this is quite straightforward in free programs like Movie Maker (for Windows) or iMovie (for Macs). Look up "subtitles" in the help files. If you want to add subtitles to a YouTube video, http://www.overstream.net/ allows you to do just that. You can then embed the final product in your website. Here's what a video with added subtitles could look like: Sound If you're not happy with the quality of sound, there are various things you can do to improve it. The six examples below are created with the audio program called Audacity, but most audio editing programs will offer the same tools. The first four edits are in the Effect menu. Remove noise Effect | Noise removal If there is an unwelcome background noise on your recording, Audacity has a tool for reducing it. Open Audacity. Open your recording. Select the whole sound track or part of the track that has too much noise by highlighting it with your mouse cursor. Select click on Effect | Noise removal to get to the noise removal tool. On-screen instructions will guide you through the rest of the process. Be careful not to reduce the noise too much, as this sometimes creates distortion. Fade in and fade out Effect | Fade in/out If you want the sound to fade in and out, use your mouse to select the part of the sound track where you want the effect. Then select Effect | Fade in/out to create the effect. This could be useful for a presentation to avoid having a burst of sound at the beginning of the recording. Change tempo without changing pitch Effect | Change tempo This can be very useful, particularly for lower-level learners. It's useful to create two versions of your recordings: one fast and one slow. You can upload both and give students the choice of which one they listen to. The great thing about this tool is that the pitch doesn't change. Change pitch without changing tempo Effect | Change pitch Sometimes you might want to lower or raise the pitch of a voice to make it more audible. This tool lets you do that without the speed changing. It can even be used to simulate a dialog, with you speaking both parts, keeping one at your normal pitch and the other one at a higher or lower pitch. You'll find the next two settings in the Preferences menu. Sample rate This helps determine the quality of your recording. You can think of it as the number of times per second you capture a snapshot of sound while you're recording. Higher sample rates give you more detail. In other words, it's a fuller sound. 8 KHz is the lowest sampling rate you should select for voice recordings. 16 KHz is more likely to produce an acceptable sound. If you have music as well, you'll need a higher sample rate, like 44 KHz. Bit rate This is the number of bits (digital 1s and 0s) that are used each second to represent the sound signal. The bit-rate for digital audio is represented in thousands of bits per second (kbps). The higher the bit-rate is, the larger the file size and the better the sound quality. Lower bit rates result in smaller files but poorer sound quality. A good bit rate for recording in Audacity is 32. Audacity offers many more possibilities, and it's well worth exploring it in detail. Go to http://audacity.sourceforge.net/help/ for more help. Navigation Most of the navigation work—that is, menus and links—is done for you in Moodle. However, there are things you can do to improve it. Here's a list of tips: Font size and color Make consistent use of font size and color with headings so that users recognize the relative importance of different sections. For example, make topics big and bold so that they stand out. Remember that the default font and color is the same as for all other text. You have to make the difference yourself. For example: User control Allow users to move ahead if necessary, so that they feel in control. You can do this by providing explicit headings in your course topics. Don't call an activity "activity". Give it a more specific name, like "Second prepositions grammar exercise". Here are some options for navigation maps: Use the Topics view on your course pages Use Book to organize a syllabus. There's an example of this in the introduction to this article. Use a flowchart program to create a plan. Then import it into your Moodle web page. For example:   Many flowchart programs allow you to include hyperlinks to the actual activities. To do that, first copy and paste the target web page address from the address bar. Then paste that address into the hyperlink in your flowchart program. Here's an example using gliffy: Create a web page with a menu on it, as in the following screenshots. To make your new web page appear with blocks to the left and right, click on Show the course blocks on the set-up page—it's at the bottom of the next screenshot. The final page would look like this. Students will see all the other navigation blocks in the left and right-hand columns.
Read more
  • 0
  • 0
  • 1545

article-image-unity-game-development-interactions-part-1
Packt
18 Nov 2009
8 min read
Save for later

Unity Game Development: Interactions (Part 1)

Packt
18 Nov 2009
8 min read
To detect physical interactions between game objects, the most common method is to use a Collider component—an invisible net that surrounds an object's shape and is in charge of detecting collisions with other objects. The act of detecting and retrieving information from these collisions is known as collision detection. Not only can we detect when two colliders interact, but we can also pre-empt a collision and perform many other useful tasks by utilizing a technique called Ray Casting, which draws a Ray—put simply, an invisible (non-rendered) vector line between two points in 3D space—which can also be used to detect an intersection with a game object's collider. Ray casting can also be used to retrieve lots of other useful information such as the length of the ray (therefore—distance), and the point of impact of the end of the line. In the given example, a ray facing the forward direction from our character is demonstrated. In addition to the direction, a ray can also be given a specific length, or allowed to cast until it finds an object. Over the course of the article, we will work with the outpost model. Because this asset has been animated for us, the animation of the outpost's door opening and closing is ready to be triggered—once the model is placed into our scene. This can be done with either collision detection or ray casting, and we will explore what you will need to do to implement either approach. Let's begin by looking at collision detection and when it may be appropriate to use ray casting instead of, or in complement to, collision detection. Exploring collisions When objects collide in any game engine, information about the collision event becomes available. By recording a variety of information upon the moment of impact, the game engine can respond in a realistic manner. For example, in a game involving physics, if an object falls to the ground from a height, then the engine needs to know which part of the object hit the ground first. With that information, it can correctly and realistically control the object's reaction to the impact. Of course, Unity handles these kinds of collisions and stores the information on your behalf, and you only have to retrieve it in order to do something with it. In the example of opening a door, we would need to detect collisions between the player character's collider and a collider on or near the door. It would make little sense to detect collisions elsewhere, as we would likely need to trigger the animation of the door when the player is near enough to walk through it, or to expect it to open for them. As a result, we would check for collisions between the player character's collider and the door's collider. However, we would need to extend the depth of the door's collider so that the player character's collider did not need to be pressed up against the door in order to trigger a collision, as shown in the following illustration. However, the problem with extending the depth of the collider is that the game interaction with it becomes unrealistic. In the example of our door, the extended collider protruding from the visual surface of the door would mean that we would bump into an invisible surface which would cause our character to stop in their tracks, and although we would use this collision to trigger the opening of the door through animation, the initial bump into the extended collider would seem unnatural to the player and thus detract from their immersion in the game. So while collision detection will work perfectly well between the player character collider and the door collider, there are drawbacks that call for us as creative game developers to look for a more intuitive approach, and this is where ray casting comes in. Ray casting While we can detect collisions between the player character's collider and a collider that fits the door object, a more appropriate method may be to check for when the player character is facing the door we are expecting to open and is within a certain distance of this door. This can be done by casting a ray forward from the player's forward direction and restricting its length. This means that when approaching the door, the player needn't walk right up to it—or bump into an extended collider—in order for it to be detected. It also ensures that the player cannot walk up to the door facing away from it and still open it—with ray casting they must be facing the door in order to use it, which makes sense. In common usage, ray casting is done where collision detection is simply too imprecise to respond correctly. For example, reactions that need to occur with a frame-by-frame level of detail may occur too quickly for a collision to take place. In this instance, we need to preemptively detect whether a collision is likely to occur rather than the collision itself. Let's look at a practical example of this problem. The frame miss In the example of a gun in a 3D shooter game, ray casting is used to predict the impact of a gunshot when a gun is fired. Because of the speed of an actual bullet, simulating the flight path of a bullet heading toward a target is very difficult to visually represent in a way that would satisfy and make sense to the player. This is down to the frame-based nature of the way in which games are rendered. If you consider that when a real gun is fired, it takes a tiny amount of time to reach its target—and as far as an observer is concerned it could be said to happen instantly—we can assume that even when rendering over 25 frames of our game per second, the bullet would need to have reached its target within only a few frames. In the example above, a bullet is fired from a gun. In order to make the bullet realistic, it will have to move at a speed of 500 feet per second. If the frame rate is 25 frames per second, then the bullet moves at 20 feet per frame. The problem with this is a person is about 2 feet in diameter, which means that the bullet will very likely miss the enemies shown at 5 and 25 feet away that would be hit. This is where prediction comes into play. Predictive collision detection Instead of checking for a collision with an actual bullet object, we find out whether a fired bullet will hit its target. By casting a ray forward from the gun object (thus using its forward direction) on the same frame that the player presses the fire button, we can immediately check which objects intersect the ray. We can do this because rays are drawn immediately. Think of them like a laser pointer—when you switch on the laser, we do not see the light moving forward because it travels at the speed of light—to us it simply appears. Rays work in the same way, so that whenever the player in a ray-based shooting game presses fire, they draw a ray in the direction that they are aiming. With this ray, they can retrieve information on the collider that is hit. Moreover, by identifying the collider, the game object itself can be addressed and scripted to behave accordingly. Even detailed information, such as the point of impact, can be returned and used to affect the resultant reaction, for example, causing the enemy to recoil in a particular direction. In our shooting game example, we would likely invoke scripting to kill or physically repel the enemy whose collider the ray hits, and as a result of the immediacy of rays, we can do this on the frame after the ray collides with, or intersects the enemy collider. This gives the effect of a real gunshot because the reaction is registered immediately. It is also worth noting that shooting games often use the otherwise invisible rays to render brief visible lines to help with aim and give the player visual feedback, but do not confuse these lines with ray casts because the rays are simply used as a path for line rendering. Adding the outpost Before we begin to use both collision detection and ray casting to open the door of our outpost, we'll need to introduce it to the scene. To begin, drag the outpost model from the Project panel to the Scene view and drop it anywhere—bear in mind you cannot position it when you drag-and-drop; this is done once you have dropped the model (that is, let go off the mouse). Once the outpost is in the Scene, you'll notice its name has also appeared in the Hierarchy panel and that it has automatically become selected. Now you're ready to position and scale it!  
Read more
  • 0
  • 0
  • 3522
article-image-keeping-extensions-secure-joomla-15-part-1
Packt
18 Nov 2009
7 min read
Save for later

Keeping Extensions Secure with Joomla! 1.5: Part 1

Packt
18 Nov 2009
7 min read
Introduction There's no such thing as a completely secure system. No matter how many precautions we take and how many times we verify our design and implementation, we will never be able to guarantee that we have created a truly secure Joomla! extension. Why not? This is because it is not possible to be prepared for every potential vulnerability. Common Weakness Enumeration (CWE) is a project dedicated to generating a formal categorization and identification system of security vulnerabilities. CWE published a list of the top 25 security weaknesses, which were selected on the basis of their frequency and consequences. This list includes some of the most publicized security weaknesses, such as code injection (CWE-94) and XSS (CWE-79). When considering the security of our extensions, this list can prove useful. For information about common programming mistakes that lead to security vulnerabilities, refer to http://cwe.mitre.org/top25/. This article includes references to the CWE weaknesses. These references are in the form of CWE IDs, that is, CWE-n. For information about a weakness, simply Search By ID on the CWE web site. These references are intended to help us better understand the weaknesses, the risks associated with the weaknesses, how the risks can be reduced using the Joomla! framework, and the suggested CWE mitigations. Something we should consider is the ramifications of security flaws. Whichever way we look at this, the answer always involves financial loss. This is true even of non-profit organizations. If a web site is attacked and the attacker managed to completely obliterate all the data held on that web site, it will cost the owner's time to restore a backup or replace the data. OK, it may not seem like a financial loss because it's non profit. It is a wastage of time if the web site owner spends two hours to restore his or her data, as those two hours could have been used elsewhere. For commercial web sites, the potential for financial loss is far more obvious. If we use a bank as an example, a security flaw could enable an attacker to transfer money from the bank to his or her own (probably untraceable) account. In 2004, the Internet bank Cahoot suffered a security flaw enabling any existing customer access to other customers' accounts. Cahoot did not suffer any obvious financial loss from the security flaw and they claimed there was no risk of financial loss. However, the customers' confidence in Cahoot was inevitably lost. This loss of confidence and bad press will certainly have affected Cahoot in some way. For example, some potential customers may have decided to open an account with a rival bank because of concerns over how secure their savings would, or would not, be with Cahoot. For more information, refer to http://news.bbc.co.uk/1/hi/business/3984845.stm. From the perspective of an extension developer, we should reflect on our moral duty and our liability. Disclaimers, especially for commercial software, do not relinquish us of legal responsibility. We should always try to avoid any form of litigation, and I'm not suggesting that we run to Mexico or our closest safe haven. We should take a holistic approach to security. We need a complete view of how the system works and of the various elements that need to be secure. Security should be built into our extension from the requirements gathering stage through to the ongoing system maintenance. How we do that depends on how we are managing our project and what the security implications of our extension are. For example, a shopping cart component with credit card processing facilities will require far greater attention to security than a content plugin that converts the occurrences of :) to smiley face images. Irrespective of the way we choose to manage the risks of weaknesses, we should always document how we are circumventing security threats. Doing so will make it easier to maintain our extension without introducing vulnerabilities. Documentation also provides us with proof of prudent risk management, which can be useful should we ever be accused of failing to adequately manage the security risks associated with our software. This is all starting to sound like a lot of work! This brings us back to the ramifications of vulnerabilities. If on the one hand, it costs us one extra month of development time to produce a piece of near-secure software. And on the other hand, it costs us two months to patch a non-secure piece of software and an incalculable amount of damage to our reputation. It is clear which route we should favor! Packt Publishing offers a book that deals specifically with Joomla! security. For more information, refer to http://www.packtpub.com/joomla-web-security-guide/. Writing SQL safe queries SQL injection is probably the most high profile of all malicious web attacks. The effects of an SQL injection attack can be devastating and wide ranging. Whereas some of the more strategic attacks may simply be aimed at gaining access, others may intend on bringing about total disruption and even destruction. Some of the most prestigious organizations in the world have found themselves dealing with the effects of SQL injection attacks. For example, in August 2007 the United Nations web site was defaced as a result of an SQL injection vulnerability. More information can be found at http://news.bbc.co.uk/1/hi/technology/6943385.stm. Dealing with the effects of an SQL injection attack is one thing, but preventing them is quite another. This recipe explains how we can ensure that our queries are safe from attack by utilizing the Joomla! framework. For more information about SQL injection, refer to CWE-89. Getting ready The first thing we need is the database handler. There is nothing special here, just the usual Joomla! code as follows: $db =& JFactory::getDBO(); How to do it... There are two aspects of a query that require special attention: Identifiers and names Literal values The JDatabase::nameQuote() method is used to safely represent identifiers and names. We will start with an easy example, a name that consists of a single identifier. $name = $db->nameQuote('columnIdentifier'); We must take care when dealing with multiple-part names (that is, names that include more than one identifier separated by a period). If we attempt to do the same thing with the name tableIdentifier.columnIdentifier, we won't get the expected result! Instead, we would have to do the following: // prepare identifiers$tableIdentifier = $db->nameQuote('tableIdentifier');$columnIdentifier = $db->nameQuote('columnIdentifier');// create name$name = "$tableIdentifier.$columnIdentifier"; Avoid hardcoding encapsulation Instead of using the JDatabase::nameQuote() method, it can be tempting to do this: $sql = 'SELECT * FROM `#__foobar_groups` AS `group`'. This is OK as it works. But the query is now tightly coupled with the database system, making it difficult to employ an alternative database system. Now we will take a look at how to deal with literal values. Let's start with strings. In MySQL, strings are encapsulated in double or single quotes. This makes the process of dealing with strings seem extremely simple. Unfortunately, this would be an oversight. Strings can contain any character, including the type of quotes we use to encapsulate them. Therefore, it is also necessary to escape strings. We do all of this using the JDatabase::Quote() method as follows: $tableIdentifier = $db->nameQuote('tableIdentifier');$columnIdentifier = $db->nameQuote('columnIdentifier');$sql = "SELECT * FROM $tableIdentifier " . "WHERE $columnIdentifier " . ' = ' . $db->Quote("How's the recipebook going?"); The JDatabase::Quote() method essentially does the following. The exact output will depend on the database handler. However, most databases escape and encapsulate strings in pretty much the same way.   Original Quoted How's the recipebook going? 'How's the recipebook going?'
Read more
  • 0
  • 0
  • 1451

article-image-event-delivery-network-oracle-soa-suite-11g-r1
Packt
18 Nov 2009
2 min read
Save for later

Event Delivery Network with Oracle SOA Suite 11g R1

Packt
18 Nov 2009
2 min read
Creating truly decoupled composite SOA applications requires a complete separation of the service consumer and the service provider.This is typically achieved through the use of asynchronous messaging.In an asynchronous messaging pattern, applications can perform in a"fire and forget" mode. This removes the need of an application to know details of the application on the other side. Additionally, it also improves resource utilization as applications are not holding onto resources until the interaction is complete. On the other hand, this introduces complexities of creating and managing message queues and topics. It requires that both the publisher of the message and the consumer use the same messaging technology. Each messaging system also has its own constraints on the types of programming languages and environments that can use the service. In a service-oriented world, this tight coupling to the implementation of the underlying messaging system is at odds with the fundamental requirement of implementation independence. What's needed is a level of abstraction that allows applications to generate an event using business terms and associate a business object in an implementation‑independent form. Oracle SOA Suite 11g addresses this with the introduction of anew feature in the form of the Event Delivery Network. Introducing events The Event Delivery Network (EDN) in Oracle SOA Suite 11g provides a declarative way to use a publish/subscribe model to generate and consume business events without worrying about the underlying message infrastructure. Developers only need to produce or consume events without having to deal with any particular messaging API like JMS, AQ, and MQ, and so on. Consuming an event means expressing an interest in the occurrence of a specific situation,while producing an event means advertising this occurrence. Using the same concepts that are used in Web Service Definition Language (WSDL), EDN uses an XML-based Event Definition Language, which allows you to define the event and its associated,strongly typed data. This definition is then registered with the SOA Infrastructure and is available to all composites to publish or subscribe.   SERVICES MESSAGING EDN WSDL:Standard service interface model JMS API:Application Programming Interface EDL:Event Definition Language XSD:Strong typing Handful of raw types XSD Business-oriented Developer-oriented Business-oriented Wealth of tools Mostly coding tools Fully declarative  
Read more
  • 0
  • 0
  • 2804

article-image-customizing-document-joomla-15-part-2
Packt
18 Nov 2009
3 min read
Save for later

Customizing the Document with Joomla! 1.5: Part 2

Packt
18 Nov 2009
3 min read
Creating a PDF in a component This recipe explains how to create a PDF view in a Joomla! MVC component. Adding PDF views is a relatively quick process, and it significantly improves the functionality of a component. Getting ready Like any other view format, we must create a new JView subclass to create a PDF view. This should be located in the corresponding view's folder and the file should be named view.pdf.php. For example, for the myview view in the mycomponent component, we create the components/com_mycomponent/views/myview/view.pdf.php file, in which we place the MycomponentViewMyview class, which extends JView. How to do it... The first thing we do is override the display() method in order to change the PDF document. We modify the document using the mutator methods. The first method changes the document title, this is the title normally shown in the title bar of the PDF viewer. $document->setTitle($title); The next method changes the filename. This is especially useful if the user is likely to save the file, as this will be the default name the user is prompted to save the file as. $document->setName($filename); The next method sets the document description, sometimes referred to as the subject. This should only be a very brief description of the document. $document->setDescription($description); The next method sets the document metadata. Currently, only keywords are supported. It is possible to set other metadata, but it will not be used in the document. $document->setMetaData('keywords', $keywords); So far, all of the methods do not print anything to the body of the PDF itself. The next method adds a common header to every page. Note that the header text itself is not formatted. $document->setHeader("My PDF Document TitlenMy Subtitle"); Lastly, we can add content to the main body of the PDF document. We achieve this in the normal way by simply outputting the content. echo 'This is my PDF! '; The outputted data can be formatted using some basic HTML tags. The following tags are supported: Type Tags Format <b>, <u>, <i>, <strong>, <em>, <sup>, <sub>, <small>, <font> Heading <h1>, <h2>, <h3>, <h4>, <h5>, <h6> Indentation <blockquote> Linked <a>, <img> List <ol>, <ul>, <li> Spacing <p>, <br>, <hr> Table <table>, <tr>, <td>, <th>
Read more
  • 0
  • 0
  • 1548
article-image-quality-assurance-asterisk-16
Packt
18 Nov 2009
10 min read
Save for later

Quality Assurance in Asterisk 1.6

Packt
18 Nov 2009
10 min read
The world has changed quite a bit in the last 150 years. Over this time, the telephone system has been invented, improved, and automated. Telephone switches no longer refer to people sitting in a large room connecting wires between the appropriate jacks. Flexible and powerful telephone service has moved from a dream to an expectation in large businesses, and for most of us it is a necessity. Today, telephone systems are the lifeblood of business. They are how we take orders, acquire supplies, and even call for emergency assistance. With the increase in prominence of telephones, the expectations of telephone users have increased proportionally. Not only have the technological expectations for telephone systems increased dramatically, but consumers are expecting more and more out of the businesses they call. Customers expect to be helped quickly and professionally. They want to know everything in a matter of minutes. Roads do not hold the only rage our society is facing today. As a business we have a variety of questions relating to our telephone system such as: How are our personnel handling angry callers? Are our employees answering the calls in a reasonable amount of time? Do we have any workers using the phone system for personal calls when they should be doing their job? We will never be able to make sure everybody does what they are supposed to do all of the time. What we will be able to do at the end of this article is perform spot-checks on how we are doing on customer service, and make sure our phone service isn't being used for unauthorized purposes. Ultimately, it comes down to a matter of trust; however, some people do not know better because they haven't been fully trained. Most will always act honorably; however, some just cannot and should not be trusted. We will try to find out who is who. Call Detail Records When we talk about security, what images come to mind? May be a big, burly guard? Perhaps a bunch of guys in green, carrying machine guns? Do we imagine a person with a metal-detecting wand? Or do we think of thick glass window panes? All of these are security features. It is just that some are a little more intrusive than others. Each time we increase security, we become a little bit less friendly. We all have to decide how far we are willing (and able) to go. In the continuum of security, Call Detail Records are the least intrusive. No special usernames or passwords have to be remembered. No fear of big brother breathing down your customers' and users' necks need be felt. We are simply doing the same thing telephone companies do—tracking what calls were made, when they were made, how long they lasted, where they came from, and a few other bits of information. This information is then available for us to review at our leisure. Asterisk gives us a few options on how we track this information. The two major choices are flat-file logging and database logging. Flat-file CDR logging By default, Asterisk includes a module called cdr_csv. Right out of the box, Asterisk logs all calls coming in and going out. The information for these calls is placed in a Comma Separated Value (CSV) file. This CSV file is located in var/log/asterisk/cdr-csv. All information is available in Master.csv, and some channels can be configured to send some information to other files as well. The benefit of using a CSV file is the simplicity. Right after compiling and installing Asterisk, this method will work. No additional configuration is required. Also, no additional network traffic is generated, and no additional services have to be installed on our server. When using the CSV form of CDR, we will see lists and lists of values. They are not very easy to parse, so here is the format, in the order in which they appear: account code: As determined by the channel (for DAHDI) or the user (for IAX and SIP) source: The source of the call destination: The destination of the call destination context caller ID channel: The channel of the source destination channel: If applicable last application: The last application run on the channel last application argument: The last argument to the last application on the channel start time: The time the call commenced answer time: The time the call was answered end time: The time the call ended duration: The difference between start time and end time billable seconds: The difference between answer time and end time, which must be less than the duration disposition: Either ANSWERED, NO ANSWER, or BUSY amaflags: As set for the channel or user, like account code uniqueid: A unique call identifier userfield: A user field set by the SetCDRUserField command We see that there are many items of information logged for each and every call. We can compare the billable seconds with our phone bill at the end of the month to make sure they're close. We can look at the destination and figure out if the calls were authorized. This gives us enough information to answer most questions we may have about a phone call. While we have enough information to answer questions, finding that answer is not very easy. We would have to scan through the entire file to try to find anything. If we are going to use an accounting package or reporting software, CSV may be exactly what we need. However, if we wish to use it in a more ad hoc sort of way, it is not very readable. Database CDR logging If we wish to read our CDR logs, it is most easily accomplished when the records are sortable. The easiest way to do this is to store our CDR records in a database. Even in this, Asterisk gives us choices. Included with Asterisk is support for PostgreSQL databases. In order to be able to install this, we must first have the postgresql-devel package installed on our system. If you have to install this package, you'll need to reinstall Asterisk. The automake system will automatically detect that we have the capability to use PostgreSQL and compile that module for us. Aside from the development packages we have installed, we will also need a PostgreSQL server somewhere in our network. It can be the same machine as the Asterisk server, but it doesn't necessarily need to be. In fact, it probably makes sense to have only one such database server on our network, and we don't want to tie up too much of our PBX's resources with database maintenance and storage. There is a script in /usr/src/asterisk/contrib/scripts/ called postgres_cdr.sql, which creates the correct table structure for us. This script should be run from the database server. If we get an error message while rebuilding that says something like "cannot find-lz", then we need to install zlib-devel. Now that we have set up our database and installed the CDR module, we must configure Asterisk to use the correct database. In order to do this, we need to edit /etc/asterisk/cdr_pgsql.conf. All of the configuration variables are in the global section. Our file should look like the following: [global]hostname=dbserver.mydomain.tldport=5432dbname=asteriskpassword=supersecretuser=asteriskuser Once we have these variables set, the next time we restart Asterisk, all CDR records will be logged in the database. If PostgreSQL is not our database of choice, we can use MySQL. This is not a part of the normal distribution of Asterisk. But as we have already installed asterisk-addons, we should already have the ability to use MySQL for CDR logging. Before we compile, we need to make sure that we have mysql-devel installed. First, we need to decide which version we're going to use. Because of some license quibbles, MySQL version 4.0 and later is not in the automatic package distribution chain. Instead, if we do need to download it, we will have to get it directly from www.mysql.com. However, the older version (3.x) will work with Asterisk and hence, you may wish to take a look at the differences between what version 3 offered and what later versions give us. Other than the development package mentioned, we will also need a MySQL server somewhere in our network. Just as with PostgreSQL, we can choose to have it on the same server as Asterisk, but for the same reasons, we probably shouldn't. Next, on the database server, we need to create the database with a user and a table for the CDR data. We do this by running the following code: # mysqladmin create database asteriskcdrdb # mysqlmysql> GRANT ALL PRIVILEGES   -> ON asteriskcdrdb.*   -> TO asteriskcdruser   -> IDENTIFIED BY 'changethis2yourpassword';mysql> USE asteriskcdrdb;mysql> CREATE TABLE cdr (   -> uniqueid varchar(32) NOT NULL default '',   -> userfield varchar(255) NOT NULL default '',   -> accountcode varchar(20) NOT NULL default '',   -> src varchar(80) NOT NULL default '',   -> dst varchar(80) NOT NULL default '',   -> dcontext varchar(80) NOT NULL default '',   -> clid varchar(80) NOT NULL default '',   -> channel varchar(80) NOT NULL default '',   -> dstchannel varchar(80) NOT NULL default '',   -> lastapp varchar(80) NOT NULL default '',   -> lastdata varchar(80) NOT NULL default '',   -> calldate datetime NOT NULL default '0000-00-00 00:00:00',   -> duration int(11) NOT NULL default '0',   -> billsec int(11) NOT NULL default '0',   -> disposition varchar(45) NOT NULL default '',   -> amaflags int(11) NOT NULL default '0'-> ); That's all there is to it! We only have to do this once, so it's really not so bad. Next, we have to modify the /etc/asterisk/cdr_mysql.conf file to correctly reflect our choices. [global]hostname=ourdbserver.ourdomain.tlddbname=asteriskcdrdbpassword=changethis2yourpassworduser=asteriskcdruserport=3306userfield=1 The next time we restart Asterisk, our CDR information will be stored in the MySQL database. What does that give us? We now have the ability to use a number of very powerful tools to search our CDR records to find trends and patterns.
Read more
  • 0
  • 0
  • 1680

article-image-plotting-geographical-data-using-basemap
Packt
18 Nov 2009
3 min read
Save for later

Plotting Geographical Data using Basemap

Packt
18 Nov 2009
3 min read
Basemap is a Matplotlib toolkit, a collection of application-specific functions that extends Matplotlib functionalities, and its complete documentation is available at http://matplotlib.sourceforge.net/basemap/doc/html/index.html. Toolkits are not present in the default Matplotlib installation (in fact, they also have a different namespace, mpl_toolkits), so we have to install Basemap separately. We can download it from http://sourceforge.net/projects/matplotlib/, under the matplotlib-toolkits menu of the download section, and then install it following the instructions in the documentation link mentioned previously. Basemap is useful for scientists such as oceanographers and meteorologists, but other users may also find it interesting. For example, we could parse the Apache log and draw a point on a map using GeoIP localization for each connection. We use the 0.99.3 version of Basemap for our examples. First example Let's start playing with the library. It contains a lot of things that are very specific, so we're going to just give an introduction to the basic functions of Basemap. # pyplot module importimport matplotlib.pyplot as plt# basemap importfrom mpl_toolkits.basemap import Basemap# Numpy importimport numpy as np These are the usual imports along with the basemap module. # Lambert Conformal map of USA lower 48 statesm = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64, urcrnrlat=49, projection='lcc', lat_1=33, lat_2=45, lon_0=-95, resolution='h', area_thresh=10000) Here, we initialize a Basemap object, and we can see it has several parameters depending upon the projection chosen. Let's see what a projection is: In order to represent the curved surface of the Earth on a two-dimensional map, a map projection is needed. This conversion cannot be done without distortion. Therefore, there are many map projections available in Basemap, each with its own advantages and disadvantages. Specifically, a projection can be: equal-area (the area of features is preserved) conformal (the shape of features is preserved) No projection can be both (equal-area and conformal) at the same time. In this example, we have used a Lambert Conformal map. This projection requires additional parameters to work with. In this case, they are lat_1, lat_2, and lon_0. Along with the projection, we have to provide the information about the portion of the Earth surface that the map projection will describe. This is done with the help of the following arguments: Argument Description llcrnrlon Longitude of lower-left corner of the desired map domain llcrnrlat Latitude of lower-left corner of the desired map domain urcrnrlon Longitude of upper-right corner of the desired map domain urcrnrlat Latitude of upper-right corner of the desired map domain     The last two arguments are:   Argument Description resolution Specifies what the resolution is of the features added to the map (such as coast lines, borders, and so on), here we have chosen high resolution (h), but crude, low, and intermediate are also available. area_thresh Specifies what the minimum size is for a feature to be plotted. In this case, only features bigger than 10,000 square kilometer
Read more
  • 0
  • 0
  • 6072
Modal Close icon
Modal Close icon