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
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Server-Side Web Development

404 Articles
article-image-interacting-students-using-moodle-19-part-2
Packt
22 Oct 2009
10 min read
Save for later

Interacting with the Students using Moodle 1.9 (part 2)

Packt
22 Oct 2009
10 min read
We'll add a competitive element to the project and—just as we have seen on TV—let the children vote for the winner. The tasks we set will involve the students researching, collaborating, and reflecting. They will be working hard, but we'll have a much easier time now, as all of their responses will be on Moodle for us to view and mark at our convenience—no more carrying heavy books around. Giving our class a chance to vote Moodle has an activity, known as Choice, which allows you to present students with a number of options that they can choose from. We're actually going to use it twice in our project, for two different purposes. Let's us try and set it up. Time for action-giving students a chance to choose a winner The students have posted their suggestions, comments, and views on Moodle. A choice is to be made of the best suggestion. Who better, than the students themselves to choose and vote for the best? With editing turned on, click on Add an Activity and then select Choice. In the Name field, enter an appropriate descriptive text—in our case, this is Vote for the best design here. In the Choice Text field, ask the question based on which you want the students to cast a vote. Leave the Limit field as it is if you don't mind any number of students casting a vote for any option available. Change it to enable, if you only want a certain number of people to vote for a particular choice. We shall leave the Limit block as it is, but we shall inform the students that they can't vote for themselves. In the Choice block, type in the options (a minimum of two) you want the students to be able to cast their vote for. Clicking on Add more fields will provide you with more choice boxes. We will need one field for each member of the class, for this activity. Use the Restrict answering to this time period option to decide when to open and close your Choice—or have it always available. Miscellaneous settings: For our activity, we need to set Display Mode to Vertical set and Publish Results to Do Not Publish. The following table explains what the settings mean, so you can use them on other occasions. Setting What it is Why use it Display Mode Lets you have your buttons go across or down the screen Use Vertically if you have many options to avoid stretching your screen Publish Results Decide if and when you want students to see what others have put Choose Do not publish if you want them to tell you their progress privately; if you're doing a class survey, choose, for example, Always show results Privacy of Results Lets you choose whether to show names or not Are the results more important than who voted for what? Some students might be wary of responding if they think their names will be shown Allow choice to be updated Lets them change their mind-but they can still vote only once. Useful, if you are using this to assess progress over a period of time. Show column for unanswered Sets up a column showing those who haven't yet responded A clear visual way of knowing who hasn't done the task For now, you can ignore the Common Module Settings option, and just click on Save and return to course. What just happened? We've set up an area, on our course page, where the students can choose their favorite designs from a number of options, by clicking on the desired option button. On the screen, you will be able to see an icon (usually, a question mark) and some text next to it. If you click on the text next to the icon, the following information will appear: The students will click on the option button placed next to their choice—in our case, the name of the classmate whose design they prefer. Finding out the students' choice Access the Choice option and click on the words View *** responses on the upper right of the screen. The *** will be the number of students who have voted already. You will get a chart displaying the choices of the students. In my Moodle course, as shown in the following screenshot, nobody has voted yet—so they need a gentle nudge! Remember that we have set up this activity so that our students cannot see the results, in order to avoid peer pressure or bullying. However, we can see the results. Thus, if Mickey votes for himself (even after having been told not to) we will spot it and can reprimand him. Have a go hero-getting the class to give us feedback After we've gone through all of the effort to set up our project on Moodle, it would be nice to know how well it was received. Why not go off now and set up another Choice option, where the question asks how much did you enjoy planning and designing the campsite? You could give them three simple responses (displayed horizontally) as: A lot It was OK Not very much. Or you could be more specific, focusing on the individual activities and asking how much they feel they have benefited from, say, the wiki or the forum. Make sure it is set up, so that the students don't see the results—that way they're more likely to be truthful. Why use Choice? Here are a few other thoughts on Choice, based on my own experiences: It is a fast and simple method of gathering data for a class research project. I used this with a class of 13 year olds who had just returned from the summer break. I asked them to choose where they had been on vacation, giving them choices of our own country, several nearby countries in Europe, the United States of America, and a few more. I set up the choice, so that they could all see the answers when the time was up. I also set it up in such a way that the results were anonymous, to avoid any kind of uneasiness felt by those students who had stayed at home. The class then compared and contrasted the class results with Tourist Office statistics on the most popular tourist destinations. It offers a private way for students to evaluate and inform the teacher about their progress. Students might be too shy to tell you in person if they are struggling; they might be wary of being honest in the open voting methods that some teachers use (such as red, amber, or green traffic lights). However, if the students are aware of the fact that their classmates will not see their response, they are more likely to be honest with you. It acts as a way to involve the class in deciding the path that their learning will take. I first introduced my class of 11 year olds to rivers in Europe, South America, Africa, and Asia. Then, I offered the class, the chance to vote for the river that they wanted study in greater depth as part of their project. The majority opted for the Amazon—so the Amazon it was! Announcing the winner Well, you could give out the results in the classroom, of course! Alternatively, can encourage them to use Moodle by using the Compose a Webpage resource that we met in the previous article on Adding Worksheets and Resources with Moodle, and adding the information there. Writing creatively in Moodle Once a winner has been found, the next task for everyone is to create a cleverly-worded advertisement for this campsite, for which, you could use one of the names suggested in the glossary. This too can be done on Moodle. Why use Moodle and not their exercise books? The first reason is that it will save paper, the second reason is that the students enjoy working on the computer, and the third and final reason is that we can work at our leisure in school, at home, or in any room where there is an Internet connection. We're not tied to carrying around a pile of heavy books. We don't even need to manually hand-write the grades into our grade book. Moodle will put the grades that we give our students, into its grade book automatically and alphabetically. Moodle can also send our pupils an email telling them that we've graded their task, so that they can check their grades. This might be a different way of working from the one that you are used to, but do give it a try. It will take the pressure off your back and shoulders, if nothing else. Time for action-setting up an online creative writing exercise For our advert, we'll use an Online text assignment. With editing turned on, select online text option, within Assignments. In the Assignment name field, enter something descriptive—our students will click here to get to the task. In the Description field, enter the instructions. Our screen will then appear as shown in the following screenshot: If you need more space to type in, click on the icon on the far right of the bottom line of the HTML editor. This will enlarge the text box for you. Click it again when you're done, to return to the editing area. In the Grade field, enter the total marks out of which you will score the students (for now, we're sticking to a maximum of 100, but you can change this). Set a start and end date between which the students can send the work assigned to them, if you want. Leave the Prevent Late Submissions option as it is, unless you need to set a deadline by which the students must submit the assigned work. Set the Allow Resubmitting option to YES, if you want to let students redraft their work. Set the Email Alerts to teachers option to NO (unless you want 30 emails in your inbox!). Change the Comment inline option to YES, so that we can post a comment on the students work. Click on Save and return to course. What just happened? We've just explained to our class what we want them to do, and have also provided them with space in Moodle to do it. We used an Online Text assignment. If we go up to the top of our course, where the editing button is, you'll be able to see a very useful feature called Switch role to…. If we choose the Student option, it will allow us to see the tasks as the pupils will see them: In this case, there's a rather unfriendly command at the bottom of our assignment. Do you think that your students will know that they need to click here to get to their text box? Why not ask your Moodle administrator to look at the Language editing settings and change these words to something more child-friendly—such as Click here to type your answer?
Read more
  • 0
  • 0
  • 1062

article-image-resource-oriented-clients-rest-principles
Packt
22 Oct 2009
8 min read
Save for later

Resource-Oriented Clients with REST Principles

Packt
22 Oct 2009
8 min read
Designing Clients While designing the library service, the ultimate outcome was the mapping of business operations to URIs and HTTP verbs. The client design is governed by this mapping. Prior to service design, the problem statement was analyzed. For consuming the service and invoking the business operations of the service using clients, there needs to be some understanding of how the service intends to solve the problem. In other words, the service, by design, has already solved the problem. However, the semantics of the solution provided by the service needs to be understood by the developers implementing the clients. The semantics of the service is usually documented in terms of business operations and the relationships between those operations. And sometimes, the semantics are obvious. As an example, in the library system, a member returning a book must have already borrowed that book. Theborrow book operation precedes the return book operation. Client design must take these semantics into account. Resource Design Following is the URI and HTTP verb mapping for business operations of the library system: URI HTTP Method Collection Operation Business Operation /book GET books retrieve Get books /book POST books create Add book(s) /book/{book_id} GET books retrieve Get book data /member GET members retrieve Get members /member POST members create Add member(s) /member/{member_id} GET members retrieve Get member data /member/{member_id}/books GET members retrieve Get member borrowings /member/{member_id}/books/{book_id} POST members create Borrow book /member/{member_id}/books/{book_id} DELETE members delete Return book   When it comes to client design, the resource design is given, and is an input to the client design. When it comes to implementing clients, we have to adhere to the design given to us by the service designer. In this example, we designed the API given in the above table, so we are already familiar with the API. Sometimes, you may have to use an API designed by someone else, hence you would have to ensure that you have access to information such as: Resource URI formats HTTP methods involved with each resource URI The resource collection that is associated with the URI The nature of the operation to be executed combining the URI and the HTTP verb The business operation that maps the resource operation to the real world context Looking into the above resource design table, we can identify two resources, book and member. And we could understand some of the semantics associated with the business operations of the resources. Create, retrieve books Create, retrieve members Borrow book, list borrowed books and return book Book ID and member ID could be used to invoke operations specific to a particular book or member instance System Implementation In this section, we will use the techniques on client programming to consume the library service. These techniques include: Building requests using XML Sending requests with correct HTTP verbs using an HTTP client library like CURL Receiving XML responses and processing the received responses to extract information that we require from the response Retrieving Resource Information Here is the PHP source code to retrieve book information. <?php$url = 'http://localhost/rest/04/library/book.php';$client = curl_init($url);curl_setopt($client, CURLOPT_RETURNTRANSFER, 1);$response = curl_exec($client);curl_close($client);$xml = simplexml_load_string($response);foreach ($xml->book as $book) { echo "$book->id, $book->name, $book->author, $book->isbn <br/>n";}?> The output generated is shown below As per the service design, all that is required is to send a GET request to the URL of the book resource. And as per the service semantics, we are expecting the response to be something similar to: <books> <book> <id>1</id> <name>Book1</name> <author>Auth1</author> <isbn>ISBN0001</isbn> </book> <book> <id>2</id> <name>Book2</name> <author>Auth2</author> <isbn>ISBN0002</isbn> </book></books> So in the client, we convert the response to an XML tree. $xml = simplexml_load_string($response); And generate the output that we desire from the client. In this case we print all the books. foreach ($xml->book as $book) { echo "$book->id, $book->name, $book->author, $book->isbn <br/>n";} The output is: 1, Book1, Auth1, ISBN0001 2, Book2, Auth2, ISBN0002 Similarly, we could retrieve all the members with the following PHP script. <?php$url = 'http://localhost/rest/04/library/member.php';$client = curl_init($url);curl_setopt($client, CURLOPT_RETURNTRANSFER, 1);$response = curl_exec($client);curl_close($client);$xml = simplexml_load_string($response);foreach ($xml->member as $member) { echo "$member->id, $member->first_name, $member->last_name <br/>n";}?> Next, retrieving books borrowed by a member. <?php$url = 'http://localhost/rest/04/library/member.php/1/books';$client = curl_init($url);curl_setopt($client, CURLOPT_RETURNTRANSFER, 1);$response = curl_exec($client);curl_close($client);$xml = simplexml_load_string($response);foreach ($xml->book as $book) { echo "$book->id, $book->name, $book->author, $book->isbn <br/>n";}?> Here we are retrieving the books borrowed by member with ID 1. Only the URL differs, the rest of the logic is the same. Creating Resources Books, members, and borrowings could be created using POST operations, as per the service design. The following PHP script creates new book. <?php$url = 'http://localhost/rest/04/library/book.php';$data = <<<XML<books> <book><name>Book3</name><author>Auth3</author><isbn>ISBN0003</isbn></book> <book><name>Book4</name><author>Auth4</author><isbn>ISBN0004</isbn></book></books>XML;$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $data);$response = curl_exec($ch);curl_close($ch);echo $response;?> When data is sent with POST verb to the URI of the book resource, the posted data would be used to create resource instances. Note that, in order to figure out the format of the XML message to be used, you have to look into the service operation documentation. This is where the knowledge on service semantics comes into play. Next is the PHP script to create members. <?php$url = 'http://localhost/rest/04/library/member.php';$data = <<<XML<members><member><first_name>Sam</first_name><last_name>Noel</last_name></member></members>XML;$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $data);$response = curl_exec($ch);curl_close($ch);echo $response;?> This script is very similar to the script that creates books. Only differences are the endpoint address and the XML payload used. The endpoint address refers to the location where the service is located. In the above script the endpoint address of the service is: $url = 'http://localhost/rest/04/library/member.php'; Next, borrowing a book can be done by posting to the member URI with the ID of the member borrowing the book, and the ID of the book being borrowed. <?php$url = 'http://localhost/rest/04/library/member.php/1/books/2';$data = <<<XMLXML;$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $data);$response = curl_exec($ch);curl_close($ch);echo $response;?> Note that, in the above sample, we are not posting any data to the URI. Hence the XML payload is empty: $data = <<<XMLXML; As per the REST architectural principles, we just send a POST request with all resource information on the URI itself. In this example, member with ID 1 is borrowing the book with ID 2. $url = 'http://localhost/rest/04/library/member.php/1/books/2'; One of the things to be noted in the client scripts is that we have used hard coded URLs and parameter values. When you are using these scripts with an application that uses a Web-based user interface, those hard coded values need to be parameterized. And we send a POST request to this URL: curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $data); Note that, even though the XML payload that we are sending to the service is empty, we still have to set the CURLOPT_POSTFIELDS option for CURL. This is because we have set CURLOPT_POST to true and the CRUL library mandates setting POST field option even when it is empty. This script would cause a book borrowing to be created on the server side. When the member.php script receives a request with the from /{member_id}/books/{book_id} with HTTP verb POST, it maps the request to borrow book business operation. So, the URL $url = 'http://localhost/rest/04/library/member.php/1/books/2'; means that member with ID 1 is borrowing the book with ID 2.
Read more
  • 0
  • 0
  • 2729

article-image-languages-and-language-settings-moodle
Packt
22 Oct 2009
7 min read
Save for later

Languages and Language Settings in Moodle

Packt
22 Oct 2009
7 min read
Language The default Moodle installation includes many Language packs. A language pack is a set of translations for the Moodle interface. Language packs translate the Moodle interface, and not the course content. Here's the Front Page of a site when the user selects Spanish from the language menu: Note that every aspect of the interface is being presented in Spanish: menu names, menu items, section names, buttons, and system messages. Now, let's take a look at the same Front Page when the user selects Romanian from the language menu: Note that much of the interface has not been translated. For example, the Site Administration menu and section name for Site news are still in English. When a part of Moodle's interface is not translated into the selected language, Moodle uses the English version. Language Files When you install an additional language, Moodle places the language pack in its data directory under the subdirectory /lang. It creates a subdirectory for each language files. The following screenshot shows the results of installing the International Spanish and Romanian languages: For example, the subdirectory, /lang/en_us, holds files for the U.S. English translation, and /lang/es_es holds the files for traditional Spanish (Espanol / Espana). The name of the subdirectory is the 'language code'. Knowing this code will come in handy later. In the previous example, es_utf8 tells us that the language code for International Spanish is es. Inside a language pack's directory, we see a list of files that contain the translations: For example, the /lang/es_utf8/forum.php file holds text used on the forum pages. Let us suppose that we are creating a course for students. This file would include the text that is displayed to the course creator while creating the forum, and the text that is displayed to the students when they use the forum. Here are the first few lines from the English version of that file: $string['addanewdiscussion'] = 'Add a new discussion topic';$string['addanewtopic'] = 'Add a new topic';$string['advancedsearch'] = 'Advanced search'; And here are the same first three lines from the Spanish version of that file: $string['addanewdiscussion'] = 'Colocar un nuevo tema de discusión aquí';$string['addanewtopic'] = 'Agregar un nuevo tema';$string['advancedsearch'] = 'Búsqueda avanzada'; The biggest task in localizing Moodle consists of translating these language files into the appropriate languages. Some translations are surprisingly complete. For example, most of the interface has been translated to Irish Gaelic, even though this language is used by only about 350,000 people everyday. The Romanian interface remains mostly untranslated although Romania has a population of over 23 million. This means that if a Moodle user chooses the Romanian language (ro), most of the interface will still default to English. Language Settings You access the Language settings page from the Site Administration menu. Default Language and Display Language Menu The Default language setting specifies the language that users will see when they first encounter your site. If you also select Display language menu, users can change the language. Selecting this displays a language menu on your Front Page. Languages on Language Menu and Cache Language Menu The setting Languages on language menu enables you to specify the languages that users can pick from the language menu. There are directions for you to enter the 'language codes'. These codes are the names of the directories which hold the Language packs. In the subsection on Language Files on the previous page, you saw that the directory es_utf8 holds the language files for International Spanish. If you wanted to enter that language in the list, it would look like this: Leaving this field blank will enable your students to pick from all available languages. Entering the names of languages in this field limits the list to only those entered. Sitewide Locale Enter a language code into this field, and the system displays dates in the format appropriate to that language. Excel Encoding Most of the reports that Moodle generates can be downloaded as Excel files. User logs and grades are two examples. This setting lets you choose the encoding for those Excel files. Your choices are Unicode and Latin. The default is Unicode, because this character set includes many more characters other than Latin. In many cases, Latin encoding doesn't offer enough characters to completely represent a non-English language. Offering Courses in Multiple Languages The settings on the Language settings page are also applicable for translating the Moodle interface. However, they are not applicable for translating course content. If you want to offer course content in multiple languages, you have several choices. First, you could put all the different languages into each course. That is, each document would appear in a course in several languages. For example, if you offered a botany course in English and Spanish, you might have a document defining the different types of plants in both English and Spanish, side by side in the same course–Types of Plants or Tipos de Plantaras. While taking the course, students would select the documents in their language. Course names would appear in only one language. Second, you could create separate courses for each language, and offer them on the same site. Course names would appear in each language. In this case, students would select the course in English or Spanish– Basic Botany or Botánica Básica. Third, you could create a separate Moodle site for each language, for example, http://moodle.williamrice.com/english and http://moodle.williamrice.com/spanish. At the Home Page of your site, students would select their language and would be directed to the correct Moodle installation. In this case, the entire Moodle site would appear in the students' language: the site name, the menus, the course names, and the course content. These are things you should consider before installing Moodle. Installing Additional Languages To install additional languages, you must be connected to the Internet. Then, from the Site Administration menu, select Language | Language packs. The page displays a list of all available Language packs: This list is taken from Moodle's /install/lang directory. In that directory, you will find a folder for each language pack that can be installed. The folder contains a file called install.php. That file retrieves the most recent version of the language pack from the Web and installs it. This is why Moodle must be connected to the Web to use this feature. If Moodle is not connected, you will need to download the language pack and copy it into the /lang directory yourself. If you don't see the language you want on the list of Available language packs, either it's not available in the official Moodle site, or your list of available languages is out of date. Click to update this list. If the language doesn't appear, it's not available from official sources. Summary In this article, we have seen how Moodle website supports different languages and how to configure these different languages. This feature can be particularly useful while designing courses for students who come from different ethnic backgrounds. Language support can not only make the website more friendlier but also makes it more easy to browse.
Read more
  • 0
  • 0
  • 4867
Banner background image

article-image-using-object-oriented-approach-implementing-php-classes-interact-oracle
Packt
22 Oct 2009
8 min read
Save for later

Using An Object Oriented Approach for Implementing PHP Classes to Interact with Oracle

Packt
22 Oct 2009
8 min read
Before you start developing object-oriented solutions with PHP 5, it is important to understand that its object model provides more features than PHP 4's object model. Like most object-oriented languages, PHP 5 allows the developer to take advantage of interfaces, abstract classes, private/public/protected access modifiers, static members and methods, exception handling, and other features that were not available in PHP 4. But perhaps the most important thing to note about the object-oriented improvements of PHP 5 is that objects are now referenced byhandle, and not by value. Building Blocks of Applications As you no doubt know, the fundamental building block in any object-oriented language is a structure called a class. A class is a template for an object. It describes the data and behavior of its instances (objects). During run time, an application can create as many instances of a single class as necessary. The following diagram conceptually depicts the structure of a class. You might find it handy to think of an object-oriented application as a building made of blocks, where classes are those blocks. However, it is important to note that all blocks in this case are exchangeable. What this means is that if you are not satisfied with the implementation of a certain class, you can use a relevant class that has the same Application Programming Interface (API) but a different implementation instead. This allows you to increase the reusability and maintainability of your application, without increasing the complexity. The intent of the example discussed in this section is to illustrate how you can rewrite the implementation of a class so that this doesn't require a change in the existing code that employs this class. In particular, you'll see how a custom PHP 4 class designed to interact with Oracle can be rewritten to use the new object-oriented features available in PHP 5. Creating a Custom PHP Class from Scratch To proceed with the example, you first need to create a PHP 4 class interacting with Oracle. Consider the following dbConn4 class: <?php //File: dbConn4.php class dbConn4 { var $user; var $pswd; var $db; var $conn; var $query; var $row; var $exec_mode; function dbConn4($user, $pswd, $db, $exec_mode= OCI_COMMIT_ON_SUCCESS) { $this->user = $user; $this->pswd = $pswd; $this->db = $db; $this->exec_mode = $exec_mode; $this->GetConn (); } function GetConn() { if(!$this->conn = OCILogon($this->user, $this->pswd, $this->db)) { $err = OCIError(); trigger_error('Failed to establish a connection: ' . $err['message']); } } function query($sql) { if(!$this->query = OCIParse($this->conn, $sql)) { $err = OCIError($this->conn); trigger_error('Failed to parse SQL query: ' . $err['message']); return false; } else if(!OCIExecute($this->query, $this->exec_mode)) { $err = OCIError($this->query); trigger_error('Failed to execute SQL query: ' . $err['message']); return false; } return true; } function fetch() { if(!OCIFetchInto($this->query, $this->row, OCI_ASSOC)) { return false; } return $this->row; } } ?> In the above script, to define a class, you use the class keyword followed by the class name. Then, within curly braces, you define class properties and methods. Since this class is designed to work under both PHP 4 and PHP 5, all the class properties are defined with the var keyword. Declaring a property with var makes it publicly readable and writable. In PHP 5, you would use the public keyword instead. In PHP 4, you define the class constructor as a function with the same name as the class itself. This still works in PHP 5 for backward compatibility. However, in PHP 5, it's recommended that you use __construct as the constructor name. In the above example, the class constructor is used to set the member variables of a class instance to the values passed to the constructor as parameters. Note the use of the self-referencing variable $this that is used here to access the member variables of the current class instance. Within class methods, you can use $this, the special variable that points to the current instance of a class. This variable is created automatically during the execution of any object's method and can be used to access both member variables of the current instance and its methods. Then, you call the GetConn method from within the constructor to obtain a connection to the database. You reference the method using the $this variable. In this example, the GetConn method is supposed to be called from within the constructor only. In PHP 5, you would declare this method as private. To obtain a connection to the database in this example, you use the OCILogon function. In PHP 5, you would use the oci_connect function instead. The query method defined here takes an SQL string as the parameter and then parses and executes the query. It returns true on success or false on failure. This method is supposed to be called from outside an object. So, in PHP 5, you would declare it as public. Finally, you define the fetch method. You will call this method to fetch the results retrieved by a SELECT statement that has been executed with the query method. Testing the Newly Created Class Once written, the dbConn4 class discussed in the preceding section can be used in applications in order to establish a connection to an Oracle database and then issue queries against it as needed. To see this class in action, you might use the following PHP script. Assuming that you have saved the dbConn4 class as the dbConn4.php file, save the following script as select.php: <?php //File: select.php require_once 'dbConn4.php'; require_once 'hrCred.php'; $db = new dbConn4($user, $pswd, $conn); $sql="SELECT FIRST_NAME, LAST_NAME FROM employees"; if($db->query($sql)){ print 'Employee Names: ' . '<br />'; while ($row = $db->fetch()) { print $row['FIRST_NAME'] . '&nbsp;'; print $row['LAST_NAME'] . '<br />'; } } ?> The above select.php script employs the employees table from the hr/hr demonstration schema. So, before you can execute this script, you must create the hrCred.php file that contains all the information required to establish a connection to your Oracle database using the HR account. The hrCred.php file should look as shown below (note that the connection string may vary depending on your configuration): <?php //File: hrCred.php $user="hr"; $pswd="hr"; $conn="(DESCRIPTION= (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)) ) (CONNECT_DATA=(SID=orcl)(SERVER=DEDICATED)) )"; ?> Once you have created the hrCred.php script, you can execute the select.php script. As a result, it should output the names of employees from the employees table in the hr/hr demonstration schema. Taking Advantage of PHP 5's Object-Oriented Features Turning back to the dbConn4 class, you may have noticed that it was written for PHP 4. Of course, it still can be used in new applications written for PHP 5. However, to take advantage of the new object-oriented features available in PHP 5, you might want to rewrite this class as follows: <?php //File: dbConn5.php class dbConn5 { private $user; private $pswd; private $db; private $conn; private $query; private $row; private $exec_mode; public function __construct($user, $pswd, $db, $exec_mode= OCI_COMMIT_ON_SUCCESS) { $this->user = $user; $this->pswd = $pswd; $this->db = $db; $this->exec_mode = $exec_mode; $this->GetConn(); } private function GetConn() { if(!$this->conn = oci_connect($this->user, $this->pswd, $this->db)) { $err = oci_error(); trigger_error('Failed to establish a connection: ' . $err['message']); } } public function query($sql) { if(!$this->query = oci_parse($this->conn, $sql)) { $err = oci_error($this->conn); trigger_error('Failed to execute SQL query: ' . $err['message']); return false; } else if(!oci_execute($this->query, $this->exec_mode)) { $err = oci_error($this->query); trigger_error('Failed to execute SQL query: ' . $err['message']); return false; } return true; } public function fetch() { if($this->row=oci_fetch_assoc($this->query)){ return $this->row; } else { return false; } } } ?> As you can see, the implementation of the class has been improved to conform to the new standards of PHP 5. For instance, the above class takes advantage of encapsulation that is accomplished in PHP 5—like most other object-oriented languages—by means of access modifiers, namely public, protected, and private. The idea behind encapsulation is to enable the developer to design the classes that reveal only the important members and methods and hide the internals. For instance, the GetConn method in the dbConn5 class is declared with the private modifier because this method is supposed to be called only from inside the constructor when a new instance of the class is initialized; therefore, there is no need to allow client code to access this method directly. Since the implementation of the newly created dbConn5 class is different from the one used in dbConn4, you may be asking yourself: "Does that mean we need to rewrite the client code that uses the dbConn4 class as well?" The answer is obvious: you don't need to rewrite client code that uses the dbConn4 class since you have neither changed the Application Programming Interface (API) of the class nor,more importantly, its functionality. Thus, all you need to do in order to make the select.php script work with dbConn5 is simply replace all the references to dbConn4 with references to dbConn5 throughout the script.
Read more
  • 0
  • 0
  • 2875

article-image-digitally-signing-and-verifying-messages-web-services-part-1
Packt
22 Oct 2009
8 min read
Save for later

Digitally Signing and Verifying Messages in Web Services ( part 1 )

Packt
22 Oct 2009
8 min read
Confidentiality and integrity are two critical components of web services. While confidentiality can be ensured by means of encryption, the encrypted data can still be overwritten and the integrity of the message can be compromised. So it becomes is equally important to protect the integrity of the message; digital signatures helps us in doing just that. Overview of Digital Signatures In the web services scenario, XML messages are exchanged between the client application and the web services. Certain messages contain critical business information, and therefore the integrity of the message should be ensured. Ensuring the integrity of the message is not a new concept, it has been there for a long time. The concept is to make sure that the data was not tampered while in transit between the sender and the receiver. Consider, for example, that Alice and Bob are exchanging emails that are critical to business. Alice wants to make sure that Bob receives the correct email that she sent and no one else tampered with or modified the email in between. In order to ensure the integrity of the message, Alice digitally signs the message using her private key, and when Bob receives the message, he will check to make sure that the signature is still valid before he can trust or read the email. What is this digital signature? And how does it prove that no one else tampered with the data? When a message is digitally signed, it basically follows these steps: Create a digest value of the message(a unique string value for the message using a SHA1 or MD5 algorithm). Encrypt the digest value using the private key—known only to the sender. Exchange the message along with the encrypted digest value. MD5 and SHA1 are message digest algorithms to calculate the digest value. The digest or hash value is nothing but a non-reversible unique string for any given data, i.e. the digest value will change even if a space is added or removed. SHA1 produces a 160 bit digest value, while MD5 produces a 128 bit value. When Bob receives the message, his first task is to validate the signature. Validation of signature goes through a sequence of steps: Create a digest value of the message again using the same algorithm. Encrypt the digest value using the public key of Alice(obtained out of band or part of message, etc.) Validate to make sure that the digest value encrypted using the public key matches the one that was sent by Alice. Since the public key is known or exchanged along with the message, Bob can check the validity of the certificate itself. Digital certificates are issued by a trusted party such as Verisign. When a certificate is compromised, you can cancel the certificate, which will invalidate the public key. Once the signature is verified, Bob can trust that the message was not tampered with by anyone else. He can also validate the certificate to make sure that it is not expired or revoked, and also to ensure that no one actually tampered with the private key  of Alice. Digital Signatures in Web Services In the last section, we learnt about digital signatures. Since web services are all about interoperability, digital-signature-related information is represented in an industry standard format called XML Signature (standardized by W3C). The following are the key data elements that are represented in an interoperable manner by XML Signature: What data (what part of SOAP message) is digitally signed? What hash algorithm (MD5 or SHA1) is used to create the digest value? What signature algorithm is used? Information about the certificate or key. In the next section, we will describe how the Oracle Web Services Manager can help generate and verify signatures in web services. Signature Generation Using Oracle WSM Oracle Web Services Manager can centrally manage the security policy, including digital signature generation. One of the greatest advantages in using Oracle WSM to digitally sign messages is that the policy information and the digital certificate information are centrally stored and managed. An organization can have many web services, and some of them might exchange certain business critical information and require that the messages be digitally signed. Oracle WSM will play a key role when different web services have different requirements to sign the message, or when it is required to take certain actions before or after signing the message. Oracle WSM can be used to configure the signature at each web service level and that reduces the burden of deploying certificates across multiple systems. In this section, we will discuss more about how to digitally sign the response message of the web service using Oracle WSM. Sign Message Policy Step As a quick refresher, in Oracle WSM, each web service is registered within a gateway or an agent and a policy is attached to each web service. The policy steps are divided mainly into request pipeline template and response pipeline template, where different policies can be applied for request or response message processing. In this section, I will describe how to configure the policy for a response pipeline template to digitally sign the response message. It is assumed that the web service is registered within a gateway and a detailed example will be described later in this article . In the response pipeline, we can add a policy step called Sign Message to digitally sign the message. In order to digitally sign a message, the key components that are required are: Private key store Private key password The part of SOAP message that is being signed The signature algorithm being used The following screenshot describes the Sign Message policy step with certain values populated.   In the previous screenshot, the values that are populated are: Keystore location—The location where the private key file is located. Keystore type—Whether or not it is PKCS12 or JKS. Keystore password—The password to the keystore. Signer's private-key alias—The alias to gain access to the private key from the keystore. Signer's private-key password—The password to access the private key. Signed Content—Whether the BODY or envelope of the SOAP message should be signed. The above information is a part of a policy that is attached to the time service which will sign the response message. As per the information that is shown in the screenshot, the BODY of the SOAP message response will be digitally signed us in the SHA1 as the digest algorithm, and PKCS12 key store. Once the message is signed, the SOAP message will look like: <?xml version="1.0" encoding="UTF-8"?><soap:Envelope soap_encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" > <soap:Header> <wsse:Security soap_mustUnderstand="1"> <wsse:BinarySecurityToken ValueType="http://docs. oasis-open.org/wss/2004/01/oasis-200401-wss- x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open. org/wss/2004/01/oasis-200401-wss-soap-message- security-1.0#Base64Binary" wsu_Id="_ VLL9yEsi09I9f5ihwae2lQ22" >SecurityTOkenoKE2ZA==< /wsse:BinarySecurityToken> <dsig:Signature > <dsig:SignedInfo> <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/ xml-exc-c14n#"/> <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/ xmldsig#rsa-sha1"/> <dsig:Reference URI="#ishUwYWW2AAthrx hlpv1CA22"> <dsig:Transforms> <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <dsig:DigestValue>ynuqANuYM3qzdTnGOLT7SMxWHY=</dsig:DigestValue> </dsig:Reference> <dsig:Reference URI="#UljvWiL8yjedImz 6zy0pHQ22"> <dsig:Transforms> <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <dsig:DigestValue>9ZebvrbVYLiPv1BaVLDaLJVhwo=</dsig:DigestValue> </dsig:Reference> </dsig:SignedInfo> <dsig:SignatureValue>QqmUUZDLNeLpAEFXndiBLk</dsig:SignatureValue> <dsig:KeyInfo> <wsse:SecurityTokenReference wsu_Id="_7vjdWs1ABULkiLeE7Y4lAg22" > <wsse:Reference URI="#_VLL9yEsi09I9f5ihwae2lQ22"/> </wsse:SecurityTokenReference> </dsig:KeyInfo> </dsig:Signature> <wsu:Timestamp wsu_Id="UljvWiL8yjedImz6zy0pHQ22"> <wsu:Created>2007-11-16T15:13:48Z</wsu:Created> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body wsu_Id="ishUwYWW2AAthrxhlpv1CA22" > <n:getTimeResponse > <Result xsi_type="xsd:string">10:13 AM</Result> </n:getTimeResponse> </soap:Body></soap:Envelope>
Read more
  • 0
  • 0
  • 3802

article-image-handler-and-phase-apache-axis2
Packt
21 Oct 2009
5 min read
Save for later

Handler and Phase in Apache Axis2

Packt
21 Oct 2009
5 min read
(For more resources on Axis2, see here.) Handler In any messaging system, the interceptor has its factual meaning in the context of messaging, where it intercepts the flow of messaging and does whatever task it is assigned to do. In fact, an interceptor is the smallest execution unit in a messaging system, and an Axis2 handler is also an interceptor. Handlers in Axis are stateless, that is, they do not keep their pass execution states in the memory. A handler can be considered as a logic invoker with the input for the logic evaluation taken from the MessageContext. A Handler has both read and write access permissions to MessageContext (MC) or to an incoming SOAP message. We can consider MessageContext as a property bag that keeps incoming or outgoing messages (maybe both) and other required parameters. It may also include properties to carry the message through the execution chain. On the other hand, we can access the whole system including the system runtime, global parameters, and property service operations via the MC. In most cases, a handler only touches the header block part of the SOAP message, which will either read a header (or headers), add a header(s), or remove a header(s). (This does not mean that the handler cannot touch the SOAP body, nor does it mean that it is not going to touch the SOAP body.) During reading, if a header is targeted to a handler and is not executing properly (the message might be faulty), then it should throw an exception, and the next driver in the chain (in Axis2, it is the Axis engine) would take the necessary action. A typical SOAP message with few headers is shown in the figure given below: Any handler in Axis2 has the capability to pause the message execution, which means that the handler can terminate the message flow if it cannot continue. Reliable messaging (RM) is a good example or use case for that scenario, when it needs to pause the flow depending on some of the preconditions and the postconditions as well and it works on a message sequence. If a service invocation consists of more than one message, and if the second message comes before the first one, then the RM handler will stop (or rather pause) the execution of the message invocation corresponding to the second message until it gets the first one. And when it gets, the first message is invoked, and thereafter it invokes or resumes the second message. Writing a Simple Handler Just learning the concepts will not help us in remembering what we have discussed. For that, we need to write a handler and see how it works. Writing a handler in Axis2 is very simple. If you want to write a handler, you either have to extend the AbstractHandler class or implement the Handler interface. A simple handler that extends the AbstractHandler class will appear as follows: public class SimpleHandler extends AbstractHandler{ public SimpleHandler() { }public InvocationResponse invoke(MessageContext msgContext) throws AxisFault { //Write the processing logic here // DO something return InvocationResponse.CONTINUE; }} Note the return value of the invoke method. We can have the following three values as the return value of the invoke method: Continue: The handler thinks that the message is ready to go forward. Suspend: The handler thinks that the message cannot be sent forward since some conditions are not satisfied; so the execution is suspended. Abort: The handler thinks that there is something wrong with the message, and cannot therefore allow the message to go forward. In most cases, handlers will return InvocationResponse.CONTINUE as the return value. When a message is received by the Axis engine, it calls the invoke method of each of the handlers by passing the argument to the corresponding MessageContext. As a result of this, we can implement all the processing logic inside that method. A handler author has full access to the SOAP message, and also has the required properties to process the message via the MessageContext. In addition, if the handler is not satisfied with the invocation of some precondition, the invocation can be paused as we have discussed earlier (Suspend). If some handler suspends the execution, then it is its responsibility to store the message context, and to forward the message when the conditions are satisfied. For example, the RM handler performs in a similar manner. Phase The concept of phase is introduced by Axis2, mainly to support the dynamic ordering of handlers. A phase can be defined in a number of ways: It can be considered a logical collection of handlers. It can be considered a specific time interval in the message execution. It can be considered a bucket into which to put a handler. One can consider a phase as a handler too. A flow or an execution chain can be considered as a collection of phases. Even though it was mentioned earlier that an Axis engine calls the invoke method of a handler, that is not totally correct. In fact, what the engine really does is call the invoke method of each phase in a given flow, and then the phase will sequentially invoke all the handlers in it (refer to the following figure). As we know, we can extend AbstractHandler and create a new handler; in the same way one can extend the Phase class and then create a new phase. But remember that we need not always extend the Phase class to create a new phase. We can do it by just adding an entry into axis2.xml (All the configuration that requires starting axis2 is obtained from axis2.xml). A phase has two important methods—precondition checking and postcondition checking. Therefore, if we are writing a custom phase, we need to consider the methods that have been mentioned. However, writing a phase is not a common case; you need to know how to write a handler.
Read more
  • 0
  • 0
  • 4276
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 €14.99/month. Cancel anytime
article-image-multimedia-and-assessments-moodle-19-part-1
Packt
21 Oct 2009
7 min read
Save for later

Multimedia and Assessments with Moodle 1.9 (part 1)

Packt
21 Oct 2009
7 min read
Adding multimedia to multiple choice answers in Moodle quizzes and lessons Sometimes it can be useful to insert multimedia elements into the answers of a multiple choice question in a Moodle lesson or quiz. This can apply to situations where students are required to: Recognize audio excerpts corresponding to text, images, or videos (for example, in music or language courses students have to identify a melody from a music sheet excerpt, or the correct pronunciation of a given text) Recognize video scenes (for example, corresponding to a certain dialogue, gestural conversation, and so on) Adding multimedia to the question body is fairly easy because we can use the HTML editor and just link to a multimedia file, and the Moodle filter will do the rest. But adding questions for which the answer choices are multimedia files is a different story, as there is no HTML editor, just a simple text form. However, this is not complicated with the help of the correct HTML code. For example, in the course, Module 1 - Music Evolves—students have to post excerpts of songs from different moments of a musical genre to a forum topic as attachments. In the same module, we will create a quiz (Mini-quiz – history of music) that will use the excerpts posted by our students in its questions, as an incentive for other students to have a look at their colleagues' work. So, after creating a new quiz and adding a new multiple choice question to it (for example, "Which of the following excerpts refers to medieval music?") we can add links to the MP3 files submitted by students as choices. We can get these links by right-clicking (CTRL+click for Mac users) on the linked MP3 file in the forum post and then clicking on the Copy Link Location option, as shown in the following screenshot: Next, while editing the multiple choice question, we can paste the link location in the answer form, for example, for Choice 1. This is the easy way, as Moodle, with its multimedia filter, will do the rest: As a result, we'll get something like this: However, note that the entire link to the file shows up, which is not very aesthetically-pleasing (and can give clues to the correct answer to students in the filename). We can solve this by using a simple HREF HTML tag in the answer forms, so that we obtain something cleaner, such as this: In this case, we can use the following code: <a href="pasted link location"> link text </a> with a SPACE in the link text: The same concept applies for videos and music from online services (TeacherTube, YouTube, Imeem, and so on) as we can paste the embed code in the answer form. In this case, there is no need to use any extra HTML code. So adding the embed code in the following manner: will result in the following screenshot: When using this process, we should keep in mind a couple of things: The multimedia files that are linked in the choice options MUST be available to the students in the course. If we copy the link location from the files area but the file is not available to the students, we'll have problems. The same applies to attachments in forum posts, with separate groups. Consider the situation where the files linked to in the answer options are those of an attachment in a forum post on the course. Suppose the question is shared and the quiz is restored in another course or exported to another Moodle installation. In this case, there will be problems with the file access as the hyperlink will point to the original source in a particular course, which is not currently available. In the case of videos or audio from online services, embedding may be disabled by request, so these can later become unavailable in the course. Too many links to MP3 files on the same quiz page, and/or MP3 files of considerable size can slow down the page loading. As a possible solution to the first three issues, we can have the multimedia files in a public folder on our server. In this way, files can be accessed from different courses and domains. We could, for example, download a YouTube video and make it available on our server, if this service is blocked in our school or institution. Another option is to upload these files to the course files area (but in this case, the files must be made available to students in the course, by using the Display a directory resource, or they will not have permissions to listen to or see them). There is a trick that can be used to make content available in a course without showing it in the course topics. To do this, we can go to the course settings and add an extra topic, creating the resources and activities that we don't want to show to our students (however, everything for now should be visible, so no "eyes closed" icons!). After we're done, we should go again to the course settings and remove the extra topic. In this way, the content is there, is "visible" from a permissions point of view, but at the same doesn't show in the course. This can be a way of having the files available for quizzes and other activities. As a possible solution to the last problem, we can use page breaks, or have one question per page in the quiz, so that students can only load one question at a time. Another solution is to reduce the file sizes, either by slicing or encoding the files in other formats. In the case of a MP3, reducing the bitrate could be an option. Adding multimedia to quizzes, lessons, and assignments Remember that multimedia can be used in interesting ways in not only multiple choice answers but also in question bodies and lesson content and assignments. We can create lessons in a tutorial style, with videos followed by some questions on the video's content, leading to different lesson branches according to the answers, or assignments can be presented as quick briefing videos. And don't forget that if we want to receive multimedia assignments, we should set this activity to allow students' file uploads. Creating exercises with Hot Potatoes Hot Potatoes (http://hotpot.uvic.ca) from Half Baked Software allows us to create interactive web games and puzzles in a simple way. One of the advantages of Hot Potatoes over Moodle's quiz engine is that Hot Potatoes makes it easier to create exercises, and some of these are very different from the ones available in Moodle, for example crosswords, and finding pairs via drag and drop. The license for this software is a peculiar one, as it allows free use by individuals working for state-funded educational institutions that are non-profit making, on the condition that the material produced using the application is freely available to anyone via the Web (this means that a Moodle course without access to guests, without a key wouldn't probably qualify). Other uses require a license, so we should keep this in mind. We need to register the software at http://hotpot.uvic.ca/reg/register.htm. A key will be sent to our email inbox and we can then register it going to Help | Register and filling in the details. There are six different types of exercises that we can create with this software: JQuiz - question-based exercises JCloze - fill in the gaps exercises JMatch - matching exercises JMix - jumble exercises JCross - crosswords The Masher - linked exercises of the different types mentioned above We will only take a look at the JCross and JMix exercises, as the other formats can be achieved with the question types that Moodle provides in quizzes and lessons. However, you should try them and see for yourself how easy it can be!
Read more
  • 0
  • 0
  • 1248

article-image-radrails-views
Packt
21 Oct 2009
6 min read
Save for later

RadRails Views

Packt
21 Oct 2009
6 min read
Opening the RadRails Views Some of the views that we will go through in this article are available as part of the Rails default perspective, which means you don't need to do anything special to open them; they will appear as tabbed views in a pane at the bottom of your workbench. Just look for the tab name of the view you want to see and click on it to make it visible. However, there are some views that are not opened by default, or maybe you closed them at some point accidentally, or maybe you changed to the Debug perspective and you want to display some of the RadRails views there. When you need to open a view whose tab is not displaying, you can go to the Window menu, and select the Show View option. If you are in the Rails perspective, all the available views will be displayed in that menu, as you can see in the screenshot above. When opening this menu from a different perspective, you will not see the RadRails views here, but you can select Other.... If this is the case, in the Show View dialog, most of the views will appear under the Ruby category, except for the Generators, Rails API, and Rake Tasks views, which are located under Rails. Documentation Views As happens with any modern programming language, Ruby has an extensive API. There are lots of libraries and classes and even with Ruby being an intuitive language with a neat consistent API, often we need to read the documentation. As you probably know, Ruby provides a standard documentation format called RDoc, which uses the comments in the source code to generate documentation. We can access this RDoc documentation in different ways, mainly in HTML format through a browser or by using the command-line tool RI. This produces a plain-text output directly at the command shell, in a similar way to the man command in a UNIX system. RadRails doesn't add any new functionality to the built-in documentation, but provides some convenient views so we can explore it without losing the context of our project's source. Ruby Interactive (RI) View This view provides a fast and comfortable way of browsing the local documentation in the same way as you would use RI from the command line. You can look either for a class or a method name. Just start typing at the input box at the top left corner of the view and the list below will display the matching entries. That's a nice improvement over the command line interface, since you can see the results as you type instead of having to run a complete search every time. If you know the name of both the class and the method you are looking for, then you can write them using the hash (pound) sign as a separator. For example, to get the documentation for the sum method of the class Enumerable you would write Enumerable#sum. The documentation will display in the right pane, with a convenient highlighting of the referenced methods and classes. Even if the search results of RI don't look very attractive compared to the output of the HTML-based documentation views, RI has the advantage of searching locally on your computer, so you can use it even when working off-line. Ruby Core, Ruby Standard Library, and Rails API There are three more views related to documentation in RadRails: Ruby Core API, Ruby Standard Library API, and Rails API. Unlike the RI view, these ones look for the information over the Internet, so you will not be able to use them unless you are on-line. On the other hand, the information is displayed in a more attractive way than with RI, and it provides links to the source code of the consulted methods, so if the documentation is not enough, you can always take a look at the inner details of the implementation. The Ruby Core API view displays the documentation of the classes included in Ruby's core. These are the classes you can directly use without a previous require statement. The documentation rendered is that at http://www.ruby-doc.org/core/. You are probably familiar with this type of layout, since it's the default RDoc output. The upper pane displays the navigation links, and the lower pane shows the detail of the documentation. The navigation is divided into three frames. The one to the left shows the files in which the source code is, the one in the middle shows the Classes and Modules, and in the third one you can find all the methods in the API. The Ruby Standard Library API is composed of all the classes and modules that are not a part of Ruby's core, but are typically distributed as a part of the Ruby installation. You can directly use these classes after a require statement in your code. The Ruby Standard Library API View displays the information from http://www.ruby-doc.org/stdlib. In this case, the navigation is the same as in Ruby Core, but with an additional area to the left, in which you can see all the available packages (the ones you would require for using the classes within your code). When you select a package link, you will see the files, classes, and methods for that single package. The last of the documentation views displays information about the Rails API. It includes the documentation of ActiveRecord, the ActionPack, ActiveSupport, and the rest of the Rails components. The information is obtained from http://api.rubyonrails.org. In this case the layout is slightly different because the information about the files, classes, and methods is displayed to the left instead at the top of the view. Apart from that, the behavior is identical to that of the Ruby Core API view. Since some of the API descriptions are fairly long, it can be convenient to maximize the documentation views when you are using them. Remember you can maximize any of the views by double-clicking its tab or by using the maximize icon on the view's toolbar. Double-clicking again will restore the view to the original size and position.
Read more
  • 0
  • 0
  • 1230

article-image-setting-plone-development-environment
Packt
21 Oct 2009
13 min read
Save for later

Setting up the Plone Development Environment

Packt
21 Oct 2009
13 min read
(For more resources on Plone, see here.) Prerequisites Pre-built packages for Zope and Plone are available for many operating systems. These can be tempting, but as developers it is normally better to configure the environment ourselves, in order to fully understand and control it. During development, we need write access to the Python code and configuration files. We may also need to run different versions of Zope and Plone in parallel. We will assume that you have at least the following as part of your regular development environment:   Python 2.4. We will assume that Python 2.4 gets invoked when you run python on the command line. Unfortunately, Zope, at version 2.10, does not yet support Python 2.5. Note that many Linux distributions have two packages for Python—one containing the binaries, and one containing header files (typically called python-dev or something similar). You will need both in order to compile Zope. PIL, the Python Imaging Library (http://www.pythonware.com/products/pil), should be installed for this Python interpreter. elementtree, an XML processing library, is required for Plone to start up. Most operating systems have packages for this. It can also be downloaded from http://effbot.org/zone/element-index.htm. A programmer's text editor. Preferably one with Python, XML/HTML and CSS syntax highlighting. You should set up your editor so that a tab/indent is output as four spaces. This makes Python development a lot more predictable. A shell. Most examples in this book will show a Bash interpreter shell, though we will cover Windows syntax when it differs significantly. Bear in mind that path separators on Windows are backslashes (), while other environments use forward slashes (/). Also, environment variables on Windows are referred to as %NAME%, while in most Unix shells, including Bash, variables are dereferenced with $NAME. A Subversion client. We will show the command line client syntax, but you can use a graphical client if you are more comfortable with that. Subversion can be obtained from http://subversion.tigris.org. A C compiler. You will need this to compile Zope. The venerable gcc is fine on UNIX-like systems. On Windows you probably want mingw32 (http://www.mingw.org). Alternatively, you can use a Zope Windows installer to get a binary Zope distribution.   Quick Start Understanding your development environment is an important step in becoming a productive developer. If you need to get up and running quickly, however, and you have the prerequisites outlined above in order, here are the key steps. We will assume you have Python 2.4 as your main Python interpreter. First download easy_install if you do not have it already, and use it to install ZopeSkel:   $ wget http://peak.telecommunity.com/dist/ez_setup.py   $ python ez_setup.py   $ easy_install ZopeSkel Note: If you do not have wget (e.g. because you are using Windows), you can just as easily download the ez_setup.py script using a web browser. When you run this script, it will install the easy_install binary to a directory that may not already be in your system PATH. Watch the ez_setup.py output to identify this directory. If it is not in your PATH, you should add it, allowing you to run easy_install as shown. Then, use paster, which was installed as a dependency of ZopeSkel, to create a new buildout. This folder holds our source code and dependencies, including the Zope application server:   $ paster create -t plone3_buildout myproject You can accept the defaults for all the questions, except for the password, which you must enter. Then, build the environment like so:   $ cd myproject   $ python bootstrap.py   $ ./bin/buildout Note: If you are using Windows, be sure to read the README.txt file that is generated in the myproject directory before running the buildout command. This last step may take some time, and you will need a live Internet connection.When it is complete, you can start Zope with:   $ ./bin/instance fg Go to http://localhost:8080/manage and you should see the Zope Management Interface. Use the drop-down box to add a Plone Site. If you call this mysite, it will beaccessible from http://localhost:8080/mysite. Glossary Let us now take a step back and consider our development environment in more detail. The table below summarizes the various terms and technologies that you will encounter in this chapter. It pays to be familiar with these names, because you will find them again not only throughout this book, but also in other Plone documentation. Term Definition Zope installation Zope consists of Python code, C extensions, configuration files, documentation, scripts, and utilities. Collectively, these are known as the Zope installation. Software home The part of the Zope installation that contains the main Zope runtime. This is found in the lib/python directory of the Zope installation. The full path is assigned to the $SOFTWARE_HOME environment variable when Zope is run. Zope instance The same Zope installation can be used to power multiple Zope servers, possibly running concurrently on different ports. Each instance has a directory containing a configuration file, instance-specific software components (e.g. an installation of Plone), and the local Zope database storage. Instance home When a Zope instance is running, the $INSTANCE_HOME environment variable refers to the directory where the instance is set up. Package A generic term for a distributable bundle of Python modules and supporting files. Product The traditional way to redistribute software for Zope 2 is in a "Product", which we will sometimes refer to as an "old-style Product". Products are placed in a special directory (Products/) and automatically discovered by Zope. The term "product" is also used more generally to refer to add-on components that extend Plone, even if they are not actually packaged as old-style Products. Egg A more generic and flexible alternative to products. Eggs are not specifi c to Zope, and Zope has only recently been made egg-aware. In addition to code, eggs contain metadata such as version, dependencies, and license information. Egg management tools can use this information to manage concurrent versions or automatically fetch dependencies, for example. $PYTHONPATH The $PYTHONPATH environment variable lists the directories containing Python packages that should be available at run time. It can also reference specific eggs. You should not have to set this manually. setuptools A Python library, which extends Python's built-in distutils package to support extended egg metadata and offers enhanced functionality when using software packaged as eggs. The Cheese Shop Also known as PyPI (Python Package Index). An online repository of Python eggs. Anyone can upload a package here. Egg-aware tools can use the Cheese Shop to locate dependencies and download them automatically when installing other eggs. easy_install A command-line tool, which searches the Cheese Shop for a given package, and downloads and installs it. Note that, by default, easy_install puts packages in the global site-packages folder for the Python interpreter that was used to install easy_install itself. Normally, we want our Plone packages to be local to a specific Zope instance, necessitating different tools. paster (Paste Script) paster, part of the Python Paste package, is a command runner. The paster create command invokes Paste Script templates, which are used to create skeleton packages based on command-line options and questions. ZopeSkel A collection of Paste Script templates for Zope and Plone development. We will use this to create new egg-ready packages, as well as the buildout that manages our development environment. Buildout (zc.buildout) A "buildout", using the zc.buildout toolset, is a self-contained environment that is controlled through a single configuration file (buildout.cfg). We will use it to download, install, and configure Zope, Plone, and other dependencies. Buildouts are "repeatable", meaning that they can be used to replicate a particular setup across multiple servers or developers' machines.     Understanding Eggs and Setuptools Python eggs are not specific to Zope or Plone. However, since Zope has only recently become egg-aware, they are new to many developers. Traditionally, almost all Zope add-on products, including Plone, have been distributed as Zope products. These are fairly easy to manage—you typically copy or symlink them into $INSTANCE_HOME/Products. Zope will scan this directory on startup, taking care of any product initialization and registration. However, code inside products is nearly impossible to re-use outside Zope because Zope does magic things with the Products.* namespace. Further, the namespace quickly becomes crowded, which deters developers from breaking up functionality into smaller, more re-usable and better-isolated packages. The Zope 3 philosophy is to be as close to "plain Python" as possible, and that means distributing code as such small packages. So long as its dependencies are in order, any package should be able to run in any environment. For example, the zope.interface package is used by the Twisted project, which is not otherwise dependent on Zope. This design goal has made it much easier to adopt Zope 3 packages in Zope2 and Plone. Starting with Plone 3, the Plone community has also embraced "plain Python" packages and uses them wherever possible. A number of packages, such as plone.memoize and plone.portlets are generic enough to work without any dependencies on the rest of Plone. Others are more specific to Plone and live in the plone.app namespace, such as plone.app.layout and plone.app.portlets, thelatter containing Plone-centric extensions to the generic plone.portlets package. All that is needed to use these packages is a sensible $PYTHONPATH. Thus, we can copy or link packages into $INSTANCE_HOME/lib/python/plone/memoize, lib/python/plone/portlets, lib/python/plone/app/portlets, and so forth for Zope to find them. This works, but it is pretty tedious when there are many packages, and it can become outright confusing when there are nested namespaces being used bymultiple packages. Luckily, other Python programmers have solved these problems, first creating distutils, then its successor setuptools and with setuptools, Python eggs. Note: For the setuptools documentation, see http://peak.telecommunity.com/DevCenter/setuptools. Installing Eggs When using setuptools, each project or package lives in a directory that has a toplevel setup.py file. This contains metadata about the package itself, and declares its current version as well as any dependencies. Dependencies can be specifieddown to particular versions (e.g. ">=0.2,<1.0" means "later than version 0.2 but before version 1.0"). When a package is installed, setuptools will attempt to fulfilldependencies by downloading and installing them if necessary. If you have a setuptools-enabled package, you can use setup.py to install it globally, by running:   $ python setup.py install This will copy the source code to the system-wide Python site-packages directory. Having to re-run this command each time you make a change can make development a little awkward, so while you are working on a particular package,you can install a development egg. This is essentially a link to the package's source code that ensures it is added to the $PYTHONPATH. To install a development egg, run:   $ python setup.py develop New packages can be released as binary eggs for distribution, which are just ZIP files of the package with some additional metadata. You can build an egg from within apackage by running:   $ python setup.py bdist_egg The new egg will be placed in the dist sub-directory, which will be created if necessary. Eggs can be uploaded to the Cheese Shop, also known as PyPI (the PythonPackage Index). This central repository makes it easy to fi nd packages. You canbrowse packages at http://cheeseshop.python.org/pypi. New packages can beuploaded via this website, or directly from the command line:   $ python setup.py egg_info -RDb "" sdist bdist_egg register upload You will be asked to specify or create a Cheese Shop account if this is the first time you run this command. A script called easy_install lets you search the Cheese Shop (or a similar index, if you specify a URL) for packages that it can download and install into the global Python environment. Dependencies will be included automatically. This is great for simple libraries and end-user applications, but less great when you are working on multiple Zope projects that may have different version requirements. This is why we tend to manage our eggs inside $INSTANCE_HOME or, as you will see in the next section, as part of a controlled buildout. Note: A tool called workingenv.py can create a mini-environment where global commands are restricted to a particular directory. We will not cover workingenv in this book, but you can download and read more about it at http://cheeseshop.python.org/pypi/workingenv.py. When eggs are activated (either explicitly, or implicitly by being unambiguouslyfound in the $PYTHONPATH), they can be discovered by other packages listening for plug-ins, using a mechanism called entry points (see http://peak.telecommunity.com/DevCenter/setuptools#dynamic-discovery-of-services-and-plugins). Zope does not yet directly use entry points, so we will not be covering them inany detail here. However, entry points are a very powerful system, and there areproposals to let Zope's discovery of packages use entry points instead of scanningmagic directories. With eggs, we therefore have the tools to manage multiple packages, from differentdevelopers and repositories, possibly across multiple versions. By using the packagemanagement tools that the rest of the Python community employs, we also make iteasier to re-use other libraries and share our own code with outside developers. Automating the Build Process with zc.buildout Creating a Zope instance and copying or linking packages into $INSTANCE_HOME/lib/python as is done in the manual process is not too difficult, but this approach has a few limitations. The process is manual and cumbersome to repeat across multiple environments. Multiple developers working on the same project may share the code in eggs and products by using a version control system such as Subversion. However, each developer would be responsible for setting up their development environment, and subtle differences may cause problems that are difficult to debug. Packages are installed manually, and so cannot benefit from setuptools' ability to manage dependencies and updates. Complex deployments that include other libraries, non-python code, or specific configurations will also need to be taken care of manually. Luckily, there are tools to make deployment easier. zc.buildout is one such tool, written largely by Zope founder Jim Fulton at Zope Corporation. It makes heavyuse of eggs and setuptools and is very flexible in supporting a wide range of deployment scenarios. Central to a buildout (i.e. what zc.buildout is managing for us) is a file called buildout.cfg. This specifies various options, including a list of parts, which will be executed when the buildout is run. Each part is associated with a recipe—a named egg, which will be called upon to parse the options provided, and perform a particular task, such as building a Zope instance or downloading Plone. A project-specific buildout directory can be checked into a version control system and shared among developers. It can also be used to replicate a particular environment across different servers with a high degree of predictability. By writing custom recipes, you can make zc.buildout do almost anything. Writing a recipe is not particularly hard, and there are plenty of examples and generic solutions available. However, we will not cover creating new recipes in this book, because all the recipes we need already exist.
Read more
  • 0
  • 0
  • 1302

article-image-debugging-rest-web-services
Packt
20 Oct 2009
13 min read
Save for later

Debugging REST Web Services

Packt
20 Oct 2009
13 min read
(For more resources on this subject, see here.) Message tracing The first symptom that you will notice when you are running into problems is that the client would not behave the way you want it to behave. As an example, there would be no output, or the wrong output. Since the outcome of running a REST client depends on the request that you send over the wire and the response that you receive over the wire, one of the first things is to capture the messages and verify that those are in the correct expected format. REST Services and clients interact using messages, usually in pairs of request and response. So if there are problems, they are caused by errors in the messages being exchanged. Sometimes the user only has control over a REST client and does not have access to the implementation details of the service. Sometimes the user will implement the REST service for others to consume the service. Sometimes the Web browser can act as a client. Sometimes a PHP application on a server can act as a REST client. Irrespective of where the client is and where the service is, you can use message capturing tools to capture messages and try to figure out the problem. Thanks to the fact that the service and client use messages to interact with each other, we can always use a message capturing tool in the middle to capture messages. It is not that we must run the message capturing tool on the same machine where the client is running or the service is running; the message capturing tool can be run on either machine, or it can be run on a third machine. The following figure illustrates how the message interaction would look with a message capturing tool in place. If the REST client is a Web browser and we want to capture the request and response involved in a message interaction, we would have to point the Web browser to message capturing tool and let the tool send the request to the service on behalf of the Web browser. Then, since it is the tool that sent the request to the service, the service would respond to the tool. The message capturing tool in turn would send the response it received from the service to the Web browser. In this scenario, the tool in the middle would gain access to both the request and response. Hence it can reveal those messages for us to have a look. When you are not seeing the client to work, here is the list of things that you might need to look for: If the client sends a message If you are able to receive a response from a service If the request message sent by the client is in the correct format, including HTTP headers If the response sent by the server is in the correct format, including the HTTP headers In order to check for the above, you would require a message-capturing tool to trace the messages. There are multiple tools that you can use to capture the messages that are sent from the client to the service and vice versa. Wireshark (http://www.wireshark.org/) is one such tool that can be used to capture any network traffic. It is an open-source tool and is available under the GNU General Public License version 2. However this tool can be a bit complicated if you are looking for a simple tool. Apache TCPMon (http://ws.apache.org/commons/tcpmon/) is another tool that is designed to trace web services messages. This is a Java based tool that can be used with web services to capture the messages. Because TCPMon is a message capturing tool, it can be used to intercept messages sent between client and service, and as explained earlier, can be run on the client machine, the server machine or on a third independent machine. The only catch is that you need Java installed in your system to run this tool. You can also find a C-based implementation of a similar tool with Apache Axis2/C (http://ws.apache.org/axis2/c). However, that tool does not have a graphical user interface. There is a set of steps that you need to follow, which are more or less the same across all of these tools, in order to prepare the tool for capturing messages. Define the target host name Define the target port number Define the listen port number Target host name is the name of the host machine on which the service is running. As an example, if we want to debug the request sent to the Yahoo spelling suggestion service, hosted at http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion, the host name would be search.yahooapis.com. We can either use the name of the host or we can use the IP address of the host because the tools are capable of dealing with both formats in place of the host name. As an example, if the service is hosted on the local machine, we could either use localhost or 127.0.0.1 in place of the host name. Target port number is the port number on which the service hosting web server is listening; usually this is 80. As an example, for the Yahoo spelling suggestion service, hosted at http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion, the target port number is 80. Note that, when the service URL does not mention any number, we can always use the default number. If it was running on a port other than port 80, we can find the port number followed by the host name and preceded with character ':'. As an example, if we have our web server running on port 8080 on the local machine, we would have service URL similar to http://localhost:8080/rest/04/library/book.php. Here, the host name is localhost and the target port is 8080. Listen port is the port on which the tool will be listening to capture the messages from the client before sending it to the service. For an example, say that we want to use port 9090 as our listen port to capture the messages while using the Yahoo spelling suggestion service. Under normal circumstances, we will be using a URL similar to the following with the web browser to send the request to the service. http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&query=apocalipto When we want to send this request through the message capturing tool and since we decided to make the tools listen port to be 9090 with the tool in the middle and assuming that the tool is running on the local machine, we would now use the following URL with the web browser in place of the original URL. http://localhost:9090/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&query=apocalipto Note that we are not sending this request directly to search.yahooapis.com, but rather to the tool listening on port 9090 on local host. Once the tool receives the request, it will capture the request, forward that to the target host, receive the response and forward that response to the web browser. The following figure shows the Apache TCPMon tool. You can see localhost being used as the target host, 80 being the target port number and 9090 being the listening port number. Once you fill in these fields you can see a new tab being added in the tool showing the messages being captured. Once you click on the Add button, you will see a new pane as shown in the next figure where it will show the messages and pass the messages to and from the client and service. Before you can capture the messages, there is one more step. That is to change the client code to point to the port number 9090, since our monitoring tool is now listening on that port. Originally, we were using port 80 $url = 'http://localhost:80/rest/04/library/book.php'; or just $url = 'http://localhost/rest/04/library/book.php'; because the default port number used by a web server is port 80, and the client was directly talking to the service. However, with the tool in place, we are going to make the client talk to the tool listening on port 9090. The tool in turn will talk to the service. Note that in this sample we have all three parties, the client, the service, and the tool running on the same machine. So we will keep using localhost as our host name. Now we are going to change the service endpoint address used by the client to contain port 9090. This will make sure that the client will be talking to the tool. $url = 'http://localhost:9090/rest/04/library/book.php'; As you can see, the tool has captured the request and the response. The request appears at the top and the response at the bottom. The request is a GET request to the resource located at /rest/04/library/book.php. The response is a success response, with HTTP 200 OK code. And after the HTTP headers, the response body, which is in XML follows. As mentioned earlier, the first step in debugging is to verify if the client has sent a request and if the service responded. In the above example, we have both the request and response in place. If both were missing then we need to check what is wrong on either side. If the client request was missing, you can check for the following in the code. Are you using the correct URL in client Have you written the request to the wire in the client? Usually this is done by the function curl_exec when using Curl If the response was missing, you can check for the following. Are you connected to the network? Because your service can be hosted on a remote machine Have you written a response from the service? That is, basically, have you returned the correct string value from the service? In PHP wire, using the echo function to write the required response to the wire usually does this. If you are using a PHP framework, you may have to use the framework specific mechanisms to do this. As an example, if you are using the Zend_Rest_Server class, you have to use handle() method to make sure that the response is sent to the client. Here is a sample error scenario. As you can see, the response is 404 not found. And if you look at the request, you see that there is a typo in the request. We have missed 'k' from our resource URL, hence we have sent the request to /rest/04/library/boo.php, which does not exist, whereas the correct resource URL is /rest/04/library/book.php. Next let us look at the Yahoo search example that was discussed earlier to identify some advanced concepts. We want to capture the request sent by the web browser and the response sent by the server for the request. http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&ampquery=apocalipto. As discussed earlier, the target host name is search.yahooapis.com. The target port number is 80. Let's use 9091 as the listen. Let us use the web browser to send the request through the tool so that we can capture the request and response. Since the tool is listening on port 9091, we would use the following URL with the web browser. http://localhost:9091/WebSearchService/V1/spellingSuggestion?appid=YahooDemo&ampquery=apocalipto When you use the above URL with the web browser, the web browser would send the request to the tool and the tool will get the response from the service and forward that to the web browser. We can see that the web browser gets the response. However, if we have a look at the TCPMon tool's captured messages, we see that the service has sent some binary data instead of XML data even though the Web browser is displaying the response in XML format. So what went wrong? In fact, nothing is wrong. The service sent the data in binary format because the web browser requested that format. If you look closely at the request sent you will see the following. GET /WebSearchService/V1/spellingSuggestion?appid=YahooDemo&query=apocalipto HTTP/1.1Host: search.yahooapis.com:9091User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5Accept-Language: en-us,en;q=0.7,zh-cn;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Connection: keep-alive In the request, the web browser has used the HTTP header. Accept-Encoding: gzip,deflate This tells the service that the web browser can handle data that comes in gzip compressed format. Hence the service sends the data compressed to the web browser. Obviously, it is not possible to look into the XML messages and debug them if the response is compressed. Hence we should ideally capture the messages in XML format. To do this, we can modify the request message on the TCPMon pane itself and resend the message. First remove the line Accept-Encoding: gzip,deflate Then click on the Resend button. Once we click on the Resend button, we will get the response in XML format. Errors in building XML While forming XML as request payload or response payload, we can run into errors through simple mistakes. Some would be easy to spot but some are not. Most of the XML errors could be avoided by following a simple rule of thumb-each opening XML tag should have an equivalent closing tag. That is the common mistake that can happen while building XML payloads. In the above diagram, if you look carefully in the circle, the ending tag for the book element is missing. A new starting tag for a new book is started before the first book is closed. This would cause the XML parsing on the client side to fail. In this case I am using the Library system sample and here is the PHP source code causing the problem. echo "<books>";while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { echo "<book>"; foreach ($line as $key => $col_value) { echo "<$key>$col_value</$key>"; } //echo "</book>";}echo "</books>"; Here I have intentionally commented out printing the closing tag to demonstrate the error scenario. However, while writing this code, I could have missed that as well, causing the system to be buggy. While looking for XML related errors, you can use the manual technique that we just used. Look for missing tags. If the process looks complicated and you cannot seem to find any XML errors in the response or request that you are trying to debug, you can copy the XML captured with the tool and run it through an XML validator tool. For example, you can use an online tool such as http://www.w3schools.com/XML/xml_validator.asp. You can also check if the XML file is well formed using an XML parser
Read more
  • 0
  • 0
  • 4511
article-image-themes-and-templates-apache-struts-2
Packt
20 Oct 2009
10 min read
Save for later

Themes and Templates with Apache Struts 2

Packt
20 Oct 2009
10 min read
Extracting the templates The first step to modifying an existing theme or creating our own is to extract the templates from the Struts 2 distribution. This actually has the advantageous performance side effect of keeping the templates in the file system (as opposed to in the library file), which allows FreeMarker to cache the templates properly. Caching the templates provides a performance boost and involves no work other than extracting the templates. The issue with caching templates contained in library files, however, will be fixed. If we examine the Struts 2 core JAR file, we'll see a /template folder. We just need to put that in our application's classpath. The best way to do this depends on your build and deploy environment. For example, if we're using Eclipse, the easiest thing to do is put the /template folder in our source folder; Eclipse should deploy them automatically. A maze of twisty little passages Right now, consider a form having only text fields and a submit button. We'll start by looking at the template for the text field tag. For the most part, Struts 2 custom tags are named similarly to the template file that defines it. As we're using the "xhtml" theme, we'll look in our newly-created /template/xhtml folder. Templates are found in a folder with the same name as the theme. We find the <s:textfield> template in /template/xhtml/text.ftl file. However, when we open it, we are disappointed to find it implemented by the following files—controlheader.ftl file retrieved from the current theme's folder, text.ftl from the simple theme, and controlfooter.ftl file from "xhtml" theme. This is curious, but satisfactory for now. We'll assume what we need is in the controlheader.ftl file. However, upon opening that, we discover we actually need to look in controlheader-core.ftl file. Opening that file shows us the table rows that we're looking for. Going walkabout through source code, both Java and FreeMarker, can be frustrating, but ultimately educational. Developing the habit of looking at framework source can lead to a greater mastery of that framework. It can be frustrating at times, but is a critical skill. Even without a strong understanding of the FreeMarker template language, we can get a pretty good idea of what needs to be done by looking at the controlheader-core.ftl file. We notice that the template sets a convenience variable (hasFieldErrors) when the field being rendered has an error. We'll use that variable to control the style of the table row and cells of our text fields. This is how the class of the text field label is being set. Creating our theme To keep the template clean for the purpose of education, we'll go ahead and create a new theme. (Most of the things will be the same, but we'll strip out some unused code in the templates we modify.) While we have the possibility of extending an existing theme (see the Struts 2 documentation for details), we'll just create a new theme called s2wad by copying the xhtml templates into a folder called s2wad. We can now use the new theme by setting the theme in our <s:form> tag by specifying a theme attribute: <s:form theme="s2wad" ... etc ...> Subsequent form tags will now use our new s2wad theme. Because we decided not to extend the existing "xhtml" theme, as we have a lot of tags with the "xhtml" string hard coded inside. In theory, it probably wasn't necessary to hard code the theme into the templates. However, we're going to modify only a few tags for the time being, while the remaining tags will remain hard coded (although incorrectly). In an actual project, we'd either extend an existing theme or spend more time cleaning up the theme we've created (along with the "xhtml" theme, and provide corrective patches back to the Struts 2 project). First, we'll modify controlheader.ftl to use the theme parameter to load the appropriate controlheader-core.ftl file. Arguably, this is how the template should be implemented anyway, even though we could hard code in the new s2wad theme. Next, we'll start on controlheader-core.ftl. As our site will never use the top label position, we'll remove that. Doing this isn't necessary, but will keep it cleaner for our use. The controlheader-core.ftl template creates a table row for each field error for the field being rendered, and creates the table row containing the field label and input field itself. We want to add a class to both the table row and table cells containing the field label and input field. By adding a class to both, the row itself and each of the two table cells, we maximize our ability to apply CSS styles. Even if we end up styling only one or the other, it's convenient to have the option. We'll also strip out the FreeMarker code that puts the required indicator to the left of the label, once again, largely to keep things clean. Projects will normally have a unified look and feel. It's reasonable to remove unused functionality, and if we're already going through the trouble to create a new theme, then we might as well do that. We're also going to clean up the template a little bit by consolidating how we handle the presence of field errors. Instead of putting several FreeMarker <#if> directives throughout the template, we'll create some HTML attributes at the top of the template, and use them in the table row and table cells later on. Finally, we'll indent the template file to make it easier to read. This may not always be a viable technique in production, as the extra spaces may be rendered improperly, (particularly across browsers), possibly depending on what we end up putting in the tag. For now, imagine that we're using the default "required" indicator, an asterisk, but it's conceivable we might want to use something like an image. Whitespace is something to be aware of when dealing with HTML. Our modified controlheader-core.ftl file now looks like this: <#assign hasFieldErrors = parameters.name?exists && fieldErrors?exists && fieldErrors[parameters.name]?exists/><#if hasFieldErrors> <#assign labelClass = "class='errorLabel'"/> <#assign trClass = "class='hasErrors'"/> <#assign tdClass = "class='tdLabel hasErrors'"/><#else> <#assign labelClass = "class='label'"/> <#assign trClass = ""/> <#assign tdClass = "class='tdLabel'"/></#if><#if hasFieldErrors> <#list fieldErrors[parameters.name] as error> <tr errorFor="${parameters.id}" class="hasErrors"> <td>&nbsp;</td> <td class="hasErrors"><#rt/> <span class="errorMessage">${error?html}</span><#t/> </td><#lt/> </tr> </#list></#if><tr ${trClass}> <td ${tdClass}> <#if parameters.label?exists> <label <#t/> <#if parameters.id?exists> for="${parameters.id?html}" <#t/> </#if> ${labelClass} ><#t/> ${parameters.label?html}<#t/> <#if parameters.required?default(false)> <span class="required">*</span><#t/> </#if> :<#t/> <#include "/${parameters.templateDir}/s2e2e/tooltip.ftl" /> </label><#t/> </#if> </td><#lt/> It's significantly different when compared to the controlheader-core.ftl file of the "xhtml" theme. However, it has the same functionality for our application, with the addition of the new hasErrors class applied to both the table row and cells for the recipe's name and description fields. We've also slightly modified where the field errors are displayed (it is no longer centered around the entire input field row, but directly above the field itself). We'll also modify the controlheader.ftl template to apply the hasErrors style to the table cell containing the input field. This template is much simpler and includes only our new hasErrors class and the original align code. Note that we can use the variable hasFieldErrors, which is defined in controlheader-core.ftl. This is a valuable technique, but has the potential to lead to spaghetti code. It would probably be better to define it in the controlheader.ftl template. <#include "/${parameters.templateDir}/${parameters.theme}/controlheader-core.ftl" /><td<#if hasFieldErrors>class="hasErrors"<#t/></#if><#if parameters.align?exists>align="${parameters.align?html}"<#t/></#if>><#t/> We'll create a style for the table cells with the hasErrors class, setting the background to be just a little red. Our new template sets the hasErrors class on both the label and the input field table cells, and we've collapsed our table borders, so this will create a table row with a light red background. .hasErrors td {background: #fdd;} Now, a missing Name or Description will give us a more noticeable error, as shown in the following screenshot: This is fairly a simple example. However, it does show that it's pretty straightforward to begin customizing our own templates to match the requirements of the application. By encapsulating some of the view layer inside the form tags, our JSP files are kept significantly cleaner. Other uses of templates Anything we can do in a typical JSP page can be done in our templates. We don't have to use Struts 2's template support. We can do many similar things in a JSP custom tag file (or a Java-based tag), but we'd lose some of the functionality that's already been built. Some potential uses of templates might include the addition of accessibility features across an entire site, allowing them to be encapsulated within concise JSP notation. Enhanced JavaScript functionality could be added to all fields, or only specific fields of a form, including things such as detailed help or informational pop ups. This overlaps somewhat with the existing tooltip support, we might have custom usage requirements or our own framework that we need to support. Struts 2 now also ships with a Java-based theme that avoids the use of FreeMarker tags. These tags provide a noticeable speed benefit. However, only a few basic tags are supported at this time. It's bundled as a plug-in, which can be used as a launching point for our own Java-based tags. Summary Themes and templates provide another means of encapsulating functionality and/or appearance across an entire application. The use of existing themes can be a great benefit, particularly when doing early prototyping of a site, and are often sufficient for the finished product. Dealing effectively with templates is largely a matter of digging through the existing template source. It also includes determining what our particular needs are, and modifying or creating our own themes, adding and removing functionality as appropriate. While this article only takes a brief look at templates, it covers the basics and opens the door to implementing any enhancements we may require. If you have read this article you may be interested to view : Exceptions and Logging in Apache Struts 2 Documenting our Application in Apache Struts 2 (part 1) Documenting our Application in Apache Struts 2 (part 2)
Read more
  • 0
  • 0
  • 3179

article-image-adding-interactive-course-material-moodle-19-part-3
Packt
20 Oct 2009
5 min read
Save for later

Adding Interactive Course Material in Moodle 1.9: Part 3

Packt
20 Oct 2009
5 min read
  Editing a Quiz Immediately after saving the Settings page, you are taken to the Editing Quiz page. This page is divided into five tabs. Each tab enables you to edit a different aspect of the quiz. This tab... Enables you to... Quiz Add questions to the quiz. Remove questions from the quiz. Arrange the questions in order. Create page breaks between questions. Assign a point value to each question. Assign a maximum point value to the quiz. Click into the editing page for each question. Questions Create a new question. Note that you must then add the new question to the quiz under the Quiz tab (see above). Also note that every question must belong to a category. Delete a question, not just from the quiz but from your site's question bank. Move a question from one category to another category. Click into the editing page for each question. Click into the editing page for each category. Categories Arrange the list of categories in order. Nest a category under another category (they become parent and subcategories). Publish a category, so that questions in that category can be used by other courses on the site. Delete a category (you must choose a new category to move the questions in the deleted category). Import Import questions from other learning systems. Import questions that were exported from Moodle. Export Export questions from Moodle, and save them in a variety of formats that Moodle and other learning systems can understand.       Create and Edit Question Categories Every question belongs to a category. You manage question categories under the Categories tab. There will always be a Default category. But before you create new questions, you might want to check to ensure that you have an appropriate category in which to put them. The categories which you can manage are listed on this page. To Add a New Category To add a new category, first select its Parent. If you select Top, the category will be a top-level category. Or, you can select any other category to which you have access, and then the new category will be a child of the selected category. In the Category field, enter the name for the new category. In the Category Info field, enter a description of the new category. The Publish field determines whether other courses can use the questions in this category. Click the Add button. To Edit a Category Next to the category, click the icon. The Edit categories page is displayed. You can edit the Parent, Category name, Category Info, and Publish setting. When you are finished, click the Update button. Your changes are saved and you are returned to the Categories page. Managing the Proliferation of Questions and Categories As the site administrator, you might want to monitor the creation of new question categories to ensure that they are logically named, don't have a lot of overlap, and are appropriate for the purpose of your site. As these question and their categories are shared among course creators, they can be a powerful tool for collaboration. Consider using the site-wide Teachers forum to notify your teachers, and course creators of new questions and categories. Create and Manage Questions You create and manage questions under the Questions tab. The collection of questions in your site is called the Question bank. As a teacher or the course creator, you have access to some or all the questions in the question bank. When you create questions, you add them to your site's question bank. When you create a quiz, you choose questions from the question bank for the quiz. Both these functions can be done on the same Editing Quiz page. Pay attention to which part of the page you are using—the one for creating new questions or the one for drawing question from the question bank. Display Questions from the Bank You can display questions from one category at a time. To select that category, use the Category drop-down list. If a question is deleted when it is still being used by a quiz, then it is not removed from the question bank. Instead, the question is hidden. The setting Also show old questions enables you to see questions that were deleted from the category. These deleted, or hidden, or old questions appear in the list with a blue box next to them. To keep your question bank clean, and to prevent teachers from using deleted questions, you can move all the deleted questions into a category called Deleted questions. Create the category Deleted questions and then use Also show old questions to show the deleted questions. Select them, and move them into Deleted questions. Move Questions between Categories To move a question into a category, you must have access to the target category. This means that the target category must be published, so that the teachers in all the courses can see it. Select the question(s) to move, select the category, and then click the Move to>> button: Create a Question To create a new question, from the Create new question drop-down list, select the type for the next question: This brings you to the editing page for the question: After you save the question, it is added to the list of questions in that category: Question Types The following chart explains the types of questions you can create, and gives some tips for using them.  
Read more
  • 0
  • 0
  • 1310

article-image-multimedia-and-assessments-moodle-19-part-2
Packt
20 Oct 2009
5 min read
Save for later

Multimedia and Assessments with Moodle 1.9 (part 2)

Packt
20 Oct 2009
5 min read
JClic (http://clic.xtec.net/en) is a free (under a GPL license) software application released by the Ministry of Education of the Government of Catalunya. It is written in Java, and allows us to create the following seven types of interactive activities: Association games - to identify the relationship between two groups of data Memory games - to discover hidden pairs of elements Exploring, Identifying, and Information games - to start with initial information and choose paths to the answer Puzzles – to order graphics, text, and audio, or to combine graphics and audio Written answers – to write text, a word, or a sentence Text activities – to solve exercises based on words, sentences, letters, and paragraphs (these can be completed, corrected, or ordered) Wordsearches and crosswords – to find hidden words or solve crossword puzzles JClic exercises can be more visually appealing than Hot Potatoes, as we will see, and can be particularly useful for younger students. But, as they require Java, this should be checked with the ICT coordinator as Java must be installed on the schools' PCs. In the software download area (http://clic.edu365.cat/en/jclic/download.htm), we can download JClic author, the application that allows us to create these activities. The file will use WebStart, and will run from a single file, named jclic.jnlp. When we run it for the first time, in Microsoft Vista at least, we will need to give permission for the application to Run (selecting the Always trust content from this publisher option will avoid having to perform this step every time we start JClic): Then JClic will start loading: The interface of JClic author is as shown in the following screenshot: As it can be seen, there are four available tabs: Project – the default tab, which allows us to define some details of the project. Media library – where pictures and other multimedia are managed. Activities – where the project activities are created or modified. This tab further contains four tabs. Sequences – where we can sequence several activities in the same project. The options inside these tabs will be available only after we create a new project. Start a new project The first step in building interactive JClic activities is to start a new project (via menu option File | New project): We should then define: The name of the project The name of the file in which the project will be saved (having a double extension of .jclic.zip) The default folder for saving the files to is:C:/Programme Files/JClic/projects/name of project (in Windows)$home/JClic/projects/name of project (in other OSs) We can change this and, if we are using multimedia files, again we should keep everything organized inside this folder. Creating a puzzle activity We are now ready to start creating our first activity, a puzzle. In Module 2 - A world of music—we can pick some of the pictures of instruments that our students gathered in the Instrument Mappers activities and create a jigsaw puzzle as part of a final game for the module. We will perform the following steps: Provide details of the project in the Project tab. Import a picture to the Media library. Add an activity called Exchangeable puzzle. Create a sequence. Note that we are starting from the tab on the left and moving to the right as we configure the activity. As an example, I created a project called Instruments: Next, I added a description of the activity and specified myself as an author by clicking on the plus (+) button. We can specify in more details, but for now this much information is enough as an example. Now, let's import a picture into our Media library by clicking on the icon on the far left on the toolbar: If we pick a picture from any folder on our computer, JClic will recommend that this be copied to the project folder (we should accept this recommendation, especially if we want to upload our activity to Moodle). Note that the Media library accepts different kinds of multimedia files, from MP3 to Flash and video. This can be useful in other types of activities. We now have a picture of a lamelaphone that will make a difficult jigsaw for our students. Lamelaphone image source: Weeks, Alex (2006). Mbira dzavadzimu 1.jpg. Retrieved October 12, 2008,from http://commons.wikimedia.org/wiki/File:Mbira_dzavadzimu_1.jpg The next step is to add the puzzle activity, on the Activities tab, by clicking on the icon on the far left of the toolbar: A dialog box is displayed, and in this menu we should select the Exchange puzzle option, entering a name for our puzzle, in the input field at the bottom of the dialog box: We can then add a description of the activity, and if needed, we can define a timer countdown (in the Counters section), among other options: Reports are mentioned in this dialog box. JClic provides a way to gather students' responses, but due to the complexity of this functionality, we will not deal with it in this book. In the Window tab, on the the Activities tab, we can also define some color options, as shown in the screenshot below: In the Messages tab, we can add an initial message, which for example, gives the context of the activity, and a final message, as feedback for the exercise by clicking on the dark gray areas: Finally, in the Panel tab, we should insert the lamelaphone picture from our Media library and define the kind of jigsaw that we want. In the following screenshot, I have done the following three things: Selected a jigsaw with curved unions. Defined 5x5 pieces. Selected the image from the Media library. Our puzzle activity is now ready, and we can now add a finding pairs activity to the same project, in a sequence.
Read more
  • 0
  • 0
  • 1052
article-image-exceptions-and-logging-apache-struts-2
Packt
16 Oct 2009
8 min read
Save for later

Exceptions and Logging in Apache Struts 2

Packt
16 Oct 2009
8 min read
Handling exceptions in Struts 2 Struts 2 provides a declarative exception handling mechanism that can be configured globally (for an entire package), or for a specific action. This capability can reduce the amount of exception handling code necessary inside actions under some circumstances, most notably when underlying systems, such as our services, throw runtime exceptions (exceptions that we don't need to wrap in a try/catch or declare that a method throws). To sum it up, we can map exception classes to Struts 2 results. The exception handling mechanism depends on the exception interceptor. If we modify our interceptor stack, we must keep that in mind. In general, removing the exception interceptor isn't preferred. Global exception mappings Setting up a global exception handler result is as easy as adding a global exception mapping element to a Struts 2 configuration file package definition and configuring its result. For example, to catch generic runtime exceptions, we could add the following: <global-exception-mappings><exception-mapping result="runtime"exception="java.lang.RuntimeException"/></global-exception-mappings> This means that if a java.lang.RuntimeException (or a subclass) is thrown, the framework will take us to the runtime result. The runtime result may be declared in an element, an action configuration, or both. The most specific result will be used. This implies that an action's result configuration might take precedence over a global exception mapping. For example, consider the global exception mapping shown in the previous code snippet. If we configure an action as follows, and a RuntimeException is thrown, we'll see the locally defined runtime result, even if there is a global runtime result. <action name="except1"class="com.packt.s2wad.ch09.examples.exceptions.Except1"><result name="runtime">/WEB-INF/jsps/ch9/exceptions/except1-runtime.jsp</result>... This can occasionally lead to confusion if a result name happens to collide with a result used for an exception. However, this can happen with global results anyway (a case where a naming convention for global results can be handy). Action-specific exception mappings In addition to overriding the result used for an exception mapping, we can also override a global exception mapping on a per-action basis. For example, if an action needs to use a result named runtime2 as the destination of a RuntimeException, we can configure an exception mapping specific to that action. <action name="except2"class="com.packt.s2wad.ch09.examples.exceptions.Except1"><exception-mapping result="runtime2"exception="java.lang.RuntimeException"/>... As with our earlier examples, the runtime2 result may be configured either as a global result or as an action-specific result. Accessing the exception We have many options regarding how to handle exceptions. We can show the user a generic "Something horrible has happened!" page, we can take the user back and allow them to retry the operation or refill the input form, and so on. The appropriate course of action depends on the application and, most likely, on the type of exception. We can display exception-specific information as well. The exception interceptor pushes an exception encapsulation object onto the stack with the exception and exceptionStack properties. While the stack trace is probably not appropriate for user-level error pages, the exception can be used to help create a useful error message, provide I18N property keys for messages (or values used in messages), suggest possible remedies, and so on. The simplest example of accessing the exception property from our JSP is to simply display the exception message. For example, if we threw a RuntimeException, we might create it as follows: throw newRuntimeException("Runtime thrown from ThrowingAction"); Our exception result page, then, could access the message using the usual property tag (or JSTL, if we're taking advantage of Struts 2's custom request processor): <s:property value="exception.message"/> The underlying action is still available on the stack—it's the next object on the value stack. It can be accessed from the JSP as usual, as long as we're not trying to access properties named exception or exceptionStack, which would be masked by the exception holder. (We can still access an action property named exception using OGNL's immediate stack index notation—[1].exception.) Architecting exceptions and exception handling We have pretty good control over what is displayed for our application exceptions. It is customizable based on exception type, and may be overridden on a per-action basis. However, to make use of this flexibility, we require a well-thought-out exception policy in our application. There are some general principles we can follow to help make this easier. Checked versus unchecked exceptions Before we start, let's recall that Java offers two main types of exceptions—checked and unchecked. Checked exceptions are exceptions we declare with a throws keyword or wrapped in a try/catch block. Unchecked exceptions are runtime exceptions or a subclass. It isn't always clear what type we should use when writing our code or creating our exceptions. It's been the subject of much debate over the years, but some guidelines have become apparent. One clear thing about checked exceptions is that they aren't always worth the aggravation they cause, but may be useful when the programmer has a reasonable chance of recovering from the exception. One issue with checked exceptions is that unless they're caught and wrapped in a more abstract exception (coming up next), we're actually circumventing some of the benefits of encapsulation. One of the benefits being circumvented is that when exceptions are declared as being thrown all the way up a call hierarchy, all of the classes involved are forced to know something about the class throwing the exception. It's relatively rare that this exposure is justifiable. Application-specific exceptions One of the more useful exception techniques is to create application-specific exception classes. A compelling feature of providing our own exception classes is that we can include useful diagnostic information in the exception class itself. These classes are like any other Java class. They can contain methods, properties, and constructors. For example, let's assume a service that throws an exception when the user calling the service doesn't have access rights to the service. One way to create and throw this exception would be as follows: throw new RuntimeException("User " + user.getId()+ " does not have access to the 'update' service."); However, there are some issues with this approach. It's awkward from the Struts 2's standpoint. Because it's a RuntimeException, we have only one option for handling the exception—mapping a RuntimeException to a result. Yes, we could map the exception type per-action, but that gets unwieldy. It also doesn't help if we need to map two different types of RuntimeExceptions to two different results. Another potential issue would arise if we had a process that examined exceptions and did something useful with them. For example, we might send an email with user details based on the above exception. This would amount to parsing the exception message, pulling out the user ID, and using it to get user details for inclusion in the email. This is where we'd need to create an exception class of our own, subclassed from RuntimeException. The class would have encapsulated exception related information, and a mechanism to differentiate between the different types of exceptions. A third benefit comes when we wrap lower-level exceptions—for example, a Spring-related exception. Rather than create a Spring dependency up the entire call chain, we'd wrap it in our own exception, abstracting the lower-level exception. This allows us to change the underlying implementation and aggregate differing exception types under one (or more) application-specific exception. One way of creating the above scenario would be to create an exception class that takes a User object and a message as its constructor arguments: package com.packt.s2wad.ch09.exceptions;public class UserAccessException extends RuntimeException {private User user;private String msg;public UserAccessException(User user, String msg) {this.user = user;this.msg = msg;}public String getMessage() {return "User " + user.getId() + " " + msg;}} We can now create an exception mapping for a UserAccessException (as well as a generic RuntimeException if we need it). In addition, the exception carries along with it the information needed to create useful messages: throw new UserAccessException(user,"does not have access to the 'update' service."); "Self-documenting" of code could be made even safer, in the sense of ensuring that it's only used in the ways in which it is intended. We could add an enum to the class to encapsulate the reasons the exception can be thrown, including the text for each reason. We'll add the following inside  our UserAccessException: public enum Reason {NO_ROLE("does not have role"),NO_ACCESS("does not have access");private String message;private Reason(String message) {this.message = message;}public String getMessage() { return message; }}; We'll also modify the constructor and getMessage() method to use the new Reason enumeration. public UserAccessException(User user, Reason reason) {this.user = user;this.reason = reason;}public String getMessage() {return String.format("User %d %s.",user.getId(), reason.getMessage());} Now, when we throw the exception, we explicitly know that we're using the exception class correctly (at least type-wise). The string message for each of the exception reasons is encapsulated within the exception class itself. throw new UserAccessException(user,UserAccessException.Reason.NO_ACCESS); With Java 5's static imports, it might make even more sense to create static helper methods in the exception class, leading to the concise, but understandable code: throw userHasNoAccess(user);
Read more
  • 0
  • 1
  • 4165

article-image-adding-interactive-course-material-moodle-19-part-1
Packt
16 Oct 2009
2 min read
Save for later

Adding Interactive Course Material in Moodle 1.9: Part 1

Packt
16 Oct 2009
2 min read
The following table gives you a brief description of each kind of activity. The sections that follow the table describe how and when to use these activities. Activity Description Assignment   An assignment is an activity completed offline, outside of Moodle. When the student completes the assignment, he or she either uploads a file for the instructor's review, or reports to the instructor in some other way. Regardless of whether the assignment requires uploading a file, the student receives a grade for the assignment. Choice   A choice is essentially a single, multiple-choice question that the instructor asks the class. The result can either be displayed to the class, or kept between the individual student and the instructor. Choices are a good way to get feedback from the students about the class. You can plant these choices in your course ahead of time, and keep them hidden until you need the students' feedback. You can also add them as needed. Journal   You can create an online journal, which will be unique for each student. A journal can be seen only by the student who writes it, and the instructor. Remember that a journal is attached to the course in which it appears. If you want to move a student's journal to another course, you'll need to make creative usage of the backup and restore functions.
Read more
  • 0
  • 0
  • 945