Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-papervision3d-external-models-part-1
Packt
18 Nov 2009
22 min read
Save for later

Papervision3D External Models: Part 1

Packt
18 Nov 2009
22 min read
This article covers the following: Modeling for Papervision3D Preparing for loading models Creating and loading models using Autodesk 3ds Max Loading an animation from Autodesk 3ds Max Creating and loading models using SketchUp Creating and loading models using Blender Controlling loaded materials Let's start off by having a look at some general practices to keep in mind when modeling for Papervision3D. Modeling for Papervision3D In this section, we will discuss several techniques that relate to modeling for Papervision3D. As Papervision3D is commonly used for web-based projects, modeling requires a different mindset than modeling for an animated movie, visualization, or game. Most of the techniques discussed relate to improving performance. This section is especially useful for modelers who need to create models for Papervision3D. Papervision3D PreviewerPapervision3D Previewer is a small program that should be part of every modeller's toolbox. This tool comes in handy for testing purposes. It allows a modeler to render an exported model in Papervision3D, and it displays some statistics that show how the model performs. At the time of writing, this tool was not compatible with Papervision3D 2.1, which could result in small problems when loading external models.Papervision3D Previewer can be downloaded from http://code.google.com/p/mrdoob/wiki/pv3dpreviewer Keep your polygon count low Papervision3D is a cutting edge technology that brings 3D to the Flash Player. It does this at an amazing speed relative to the capabilities of the Flash player. However, performance of Papervision3D is just a fraction of the performance that can be achieved with hardware-accelerated engines such as used by console games. Even with hardware-accelerated games there is a limit to the number of polygons that can be rendered, meaning there is always a compromise between detail and performance. This counts even more for Papervision3D, so always try to model using as few polygons as possible. Papervision3D users often wonder what the maximum number of triangles is that the Flash player can handle. There is no generic answer to this question, as performance depends on more factors than just the number of triangles. On average, the total triangle count should be no more than 3000, which equals 1500 polygons (remember that one polygon is made of two triangles). Unlike most 3D modeling programs, Papervision3D is triangle based and not polygon based. Add polygons to resolve artifacts Although this seems to contradict the previous suggestion to keep your polygon count low, sometimes you need more polygons to get rid of texture distortion or to reduce z-sorting artifacts. z-sorting artifacts will often occur in areas where objects intersect or closely intersect each other. Subdividing polygons in those areas can make z-sorting more accurate. Often this needs to be done by creating new polygons for the intersecting triangles of approximately the same size. There are several approaches to prevent z-sorting problems. Depending on the object you're using, it can be very time consuming to tweak and find the optimal amount and location of polygons. The amount of polygons you add in order to solve the problem should still be kept as low as possible. Finding the optimal values for your model will often result in switching a lot between Papervision3D and the 3D modeling program. Keep your textures small Textures used in the 3D modeling tool can be exported along with the model to a format that is readable for Papervision3D. This is a valuable feature as the texture will automatically be loaded by Papervision3D. However, the image, which was defined in the 3D authoring tool, will be used exactly as provided by Papervision3D. If you choose a 1024 by 1024 pixels image as the texture, for example the wheels of a car, Papervision3D loads the entire image and draws it on the wheel of a car that appears on screen at a size of 50 by 50 pixels for example. There are several problems related to this: It's a waste of bandwidth to load such a large image. Loading any image takes time, which should be kept as short as possible. It's a waste of capacity. Papervision3D needs to resize the image from 1024 by 1024 pixels to an image, which will be, for example, maximal 50 by 50 pixels on screen. Always choose texture dimensions that make sense for the application using it, and keep in mind that they have to be power of two. This will enable mipmapping and smoothing, which come without extra performance costs. Use textures that Flash can read 3D modeling programs usually read a variety of image sources. Some even support reading Adobe Photoshop's native file-format PSD. Flash can load only GIF, JPG, or PNG files at run time. Therefore, stick to these formats in your model so that you do not have to convert the textures when the model needs to be exported to Papervision3D. Use UV maps If your model is made up of several objects and textures, it's a good idea to use UV mapping, which is the process of unwrapping the model and defining all its textures into one single image. This way we can speed up initial loading of an application by making one request from Flash to load this image instead of loading dozens of images. UV mapping can also be used to tile or reuse parts of the image. The more parts of the UV-mapped image you can reuse, the more bandwidth you'll save. Always try to keep your UV-mapped image as small as possible, just as with keeping your normal textures small. In case you have a lot of objects sharing the same UV map and you need a large canvas to unwrap the UV map, be aware of the fact that the maximum image size supported by Flash Player 9 is 2880x2880 pixels. With the benefits of power of two textures in mind, the maximum width and height is 2048x2048 pixels. Baking textures Baking textures is the process of integrating shadows, lighting, reflection, or entire 3D objects into a single image. Most 3D modeling tools support this. This contradicts what has been said about tiling images in UV maps, as baking results in images that usually can only be used once because of the baked information on the texture. However, it can increase the level of realism of your application, just like shading does, but without the loss of performance caused by calculating shading in real time. Never use them in combination with a tiling image, as repeated shading, for instance, will result in unnatural looking renders. Therefore, each texture needs to be unique, which will cause longer loading times before you can show a scene. Use recognizable names for objects and materials It is always a good convention to use recognizable names for all your objects. This counts for the classes, methods, and properties in your code, and also for the names of the 3D objects in your modeling tool. Always think twice before renaming an object that is used by an application. The application might use the name of an object as the identifier to do something with it—for example, making it clickable. When working in a team of modelers and programmers, you really need to make this clear to the modelers as changing the name of an object can easily break your application. Size and positioning Maintaining the same relative size for your modeled objects, as you would use for instantiating primitives in your scene, is a good convention. Although you could always adjust the scale property of a loaded 3D model, it is very convenient when both Papervision3D and your modeling tool use the same scale. Remember that Papervision3D doesn't have a metric system defining units of a certain value such as meters, yards, pixels, and so on. It just uses units. Another convention is to position your object or objects at the origin of the 3D space in the modeling tool. Especially when exporting a single object from a 3D modeling tool, it is really helpful if it is located at a position of 0 on all axes. This way you can position the 3D object in Papervision3D by using absolute values, without needing to take the offset into account. You can compare this with adding movie clips to your library in Flash. In most cases, it is pretty useful when the elements of a movie clip are centered on their registration point. Finding the balance between quality and performance For each project you should try to find the balance between lightweight modeling and quality. Because each project is different in requirements, scale, and quality, there is no rule that applies for all. Keep the tips mentioned in the previous sections in mind and try to be creative with them. If you see a way to optimize your model, then do not hesitate to use it. Before we have a look at how to create and export models for Papervision3D, we will create a basic application for this purpose. Creating a template class to load models In order to show an imported 3D model using Papervision3D, we will create a basic application. Based on the orbit example (code bundle-chapter 6, click the following link to download: http://www.packtpub.com/files/code/5722_Code.zip) we create the following class. Each time we load a new model we just have to alter the init() method. First, have a look at the following base code for this example: package { import flash.events.Event; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.view.BasicView; public class ExternalModelsExample extends BasicView { private var model:DisplayObject3D; private var rotX:Number = 0.1; private var rotY:Number = 0.1; private var camPitch:Number = 90; private var camYaw:Number = 270; private var easeOut:Number = 0.1; public function ExternalModelsExample() { stage.frameRate = 40; init(); startRendering(); } private function init():void { model = new Plane(); scene.addChild(model); } private function modelLoaded(e:FileLoadEvent):void { //To be added } override protected function onRenderTick(e:Event=null):void { var xDist:Number = mouseX - stage.stageWidth * 0.5; var yDist:Number = mouseY - stage.stageHeight * 0.5; camPitch += ((yDist * rotX) - camPitch + 90) * easeOut; camYaw += ((xDist * rotY) - camYaw + 270) * easeOut; camera.orbit(camPitch, camYaw); super.onRenderTick(); } }} We have created a new plane using a wireframe as its material. The plane is assigned to a class property named model, which is of the DisplayObject3D type. In fact, any external model is a do3D. No matter what type of model we load in the following examples, we can always assign it to the model property. The classes that we'll use for loading 3D models all inherit from DisplayObject3D. Now that we have created a default application, we are ready to create our first model in 3D Studio Max, export it, and then import it into Papervison3D. Creating models in Autodesk 3ds Max and loading them into Papervision3D Autodesk 3ds Max (also known as 3D Studio Max or 3ds Max) is one of the widely-known commercial 3D modeling and animation programs. This is a good authoring tool to start with, as it can save to two of the file formats Papervision3D can handle. These are: COLLADA (extension *.dae): An open source 3D file type, which is supported by Papervision3D. This is the most advanced format and has been supported since Papervision3D's first release. It also supports animations and is actually just a plain text XML file. 3D Studio (extension *.3ds): As the name suggests, this is one of the formats that 3ds Max natively supports. Generally speaking it is also one of the most common formats to save 3D models in. As of 3ds Max version 9, there is a built-in exporter plugin available that supports exporting to COLLADA. However, you should avoid using this, as at the time of writing, the models it exports are not suitable for Papervision3D. Don't have a license of 3ds Max and want to get along with the following examples? Go to www.autodesk.com to download a 30-day trial. Installing COLLADA Max An exporter that does support COLLADA files suitable for Papervision3D is called COLLADA Max. This is a free and open source exporter that works with all versions of 3ds Max 7 and higher. Installing this exporter is easy. Just follow the steps mentioned below: Make sure you have installed 3ds Max version 7 or higher. Go to http://sourceforge.net/projects/colladamaya/. Click on View all files and select the latest COLLADA Max version. (At the time of writing this is COLLADA Max NextGen 0.9.5, which is still in beta, but is the only version that works with 3ds Max 2010). Save the download somewhere on your computer. Run the installer. Click Next, until the installer confirms that the exporter is installed. Start 3ds Max and double check if we can export using the COLLADA or COLLADA NextGen filetype, as shown in the following screenshot: If the only COLLADA export option is Autodesk Collada, then something went wrong during the installation of COLLADA Max, as this is not the exporter that works with Papervision3D. Now that 3ds Max is configured correctly for exporting a file format that can be read by Papervision3D, we will have a look at how to create a basic textured model in 3ds Max and export it to Papervision3D. Creating the Utah teapot and export it for Papervision3D If you already know how to work with 3ds Max, this step is quite easy. All we need to do is create the Utah teapot, add UV mapping, add a material to it, and export it as COLLADA. However, if you are new to 3ds Max, the following steps needs to be clarified. First, we start 3ds Max and create a new scene. The creation of a new scene happens by default on startup. The Utah teapot is one of the objects that comes as a standard primitive in 3ds Max. This means you can select it from the default primitives menu and draw it in one of the viewports. Draw it in the top viewport so that the teapot will not appear rotated over one of its axes. Give it a Radius of 250 in the properties panel on the right, in order to make it match with the units that we'll use in Papervision3D. Position the teapot at the origin of the scene. You can do this by selecting it and changing the x, y, and z properties at the bottom of your screen. You would expect that you need to set all axes to 0, although this is not the case. In this respect, the teapot differs from other primitives in 3ds Max, as the pivot point is located at the bottom of the teapot. Therefore, we need to define a different value for the teapot on the z-axis. Setting it to approximately -175 is a good value. To map a material to the teapot, we need to define a UV map first. UV mapping is also known as UVW mapping. Some call it UV mapping and others call it UVW mapping. 3ds Max uses the term UVW mapping. While having the teapot still selected, go to modify and then select UVW Mapping from the modifier list. Select Shrink Wrap and click Fit in the Alignment section. This will create a UVW map for us. Open the material editor using keyboard shortcut m. Here we define the materials that we use in 3ds Max. Give the new material a name. Replace 01 – Default with a material name of your choice—for example, teapotMaterial. Provide a bitmap as the diffuse material. You can do this by clicking on the square button, at the right of the Diffuse value within Blinn Basic Parameters section. A new window called Material/Map Browser will open. Double-click Bitmap to load an external image. Select an image of your choice. We will use teapotMaterial.jpg The material editor will now update and show the selected material on an illustrative sphere. This is your newly-created material, which you need to drag on the created teapot. The teapot model can now be exported. Depending on the version of the installed COLLADA exporter, select COLLADA or COLLADA NextGen. Note that you should not export using Autodesk Collada, as this exporter doesn't work properly for Papervision3D. Give it a filename of your choice, for example teapot, and hit Save. The exporter window will pop up. The default settings are fine for exporting to Papervision3D, so click OK to save the file. Save the model in the default 3ds Max file format (.max) somewhere on your local disk, so we can use it later when discussing other ways to export this model to Papervision3D. The model that we have created and exported is now ready to be imported by Papervision3D. Let's take a look at how this works. Importing the Utah teapot into Papervision3D To work with the exported Utah teapot, we will use the ExternalModelsExample project that we created previously in this article. Browse to the folder inside your project where you have saved your document class. Create a new folder called assets and copy to this folder, the created COLLADA file along with the image used as the material of the teapot. The class used to load an external COLLADA file is called DAE, so let's import it. import org.papervision3d.objects.parsers.DAE; This type of class is also known as a parser, as it parses the model from a loaded file. When you have a closer look at the source files of Papervision3D and its model parsers, you will probably find out about the Collada class. This might be a little confusing as we use the DAE parser to load a COLLADA file and we do not use the Collada parser. Although you could use either, this article uses the DAE parser exclusively, as it is a more recent class, supporting more features such as animation. There is no feature that is supported by the Collada parser, and is not supported by the DAE parser. Replace all code inside the init() method with the following code that loads a COLLADA file: model = new DAE();model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);DAE(model).load("assets/teapot.DAE"); Because model is defined as a DisplayObject3D class type, we need to cast it to DAE to make use of its methods so that we can call the load() method. An event listener is defined, waiting for the model to be completely loaded and parsed. Once it is loaded, the modelLoaded() method will be triggered. It is a good convention to add models only to the scene once the model is completely loaded. Add the following line of code to the modelLoaded() method: scene.addChild(model); COLLADA Utah Teapot Example Publishing this code will result in the teapot with the texture as created in 3ds Max. In real-world applications it is good practice to keep your models in one folder and your textures in another. You might want to organize the files similar to the following structure: Models in /assets/models/ Textures in /assets/textures/ By default, textures are loaded from the same folder as the model is loaded from, or optionally from the location as specified in the COLLADA file. To include the /assets/textures/ folder we can add a file search path, which defines to have a look in the specified folder, to see if the file is located there, in case none can be found on the default paths. This can be defined as follows: daeModel.addFileSearchPath("assets/textures"); You can call this method multiple times, in order to have multiple folders defined. Internally, in Papervision3D, it will loop through an array of file paths. Exporting and importing the Utah teapot in 3ds format Now that we have seen how to get an object from 3ds Max into a Papervision3D project, we have a look at another format that is supported by both 3ds Max and Papervision3D. This format is called 3D Studio, using a 3ds extension. It is one of the established 3D file formats that are supported by most 3D modeling tools. Exporting and importing is very similar to COLLADA. Let's first export the file to the 3D Studio format. Open the Utah teapot, which we've modeled earlier in this article. Leave the model as it is, and go straight to export. This time we select 3D Studio (*.3DS) as the file type. Save it into your project folder and name it teapot. Click OK when asked whether to preserve Max's texture coordinates. If your model uses teapotMaterial.jpg, or an image with more than eight characters in its filename, the exporter will output a warning. You can close this warning, but you need to be aware of the output message. It says that the bitmap filename is a non-8.3 filename, that is, a maximum amount of 8 characters for the filename and a 3-character extension. The 3D Studio file is an old format, released at the time when there was a DOS version of 3ds Max. Back then it was an OS naming convention to use short filenames, known as 8.3 filenames. This convention still applies to the 3D Studio format, for the sake of backward compatibility. Therefore, the reference to the bitmap has been renamed inside the exported 3D Studio file. Because the exported 3D Studio file changed only the reference to the bitmap filename internally and it did not affect the file it refers to, we need to create a file using this renamed file reference. Otherwise, it won't be able to find the image. In this case we need to create a version of the image called teapotMa.jpg. Save this file in the same folder as the exported 3D Studio file. As you can see, it is very easy to export a model from 3ds Max to a format Papervision3D can read. Modeling the 3D object is definitely the hardest and most time consuming part, simply because creating models takes a lot of time. Loading the model into Papervision3D is just as easy as exporting it. First, copy the 3D Studio file plus the renamed image to the assets folder of your project. We can then alter the document class in order to load the 3ds file. The class that is used to parse a 3D Studio file is called Max3DS and needs to be imported. import org.papervision3d.objects.parsers.Max3DS; In the init() method you should replace or comment the code that loads the COLLADA model from our previous example, with the following: model = new Max3DS();model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);Max3DS(model).load("assets/teapot.3ds", null, "./assets/"); As the first parameter of the load method, we pass a file reference to the model we want to load. The second parameter defines a materials list, which we will not use for this example. The third and final parameter defines the texture folder. This folder is relative to the location of the published SWF. Note that this works slightly different than the DAE parser, which loads referenced images from the path relative to the folder in which the COLLADA file is located or loads images as specified by the addFileSearchPath() method. ExternalModelsExample Publish the code and you'll see the same teapot. However, this time it's using the 3D Studio file format as its source. Importing animated models The teapot is a static model that we exported from a 3D program and loaded into Papervision3D. It is also possible to load animated models, which contain one or multiple animations. 3ds Max is one of the programs in which you can create an animation for use in Papervision3D. Animating doesn't require any additional steps. You can just create the animation and export it. This also goes for other modeling tools that support exporting animations to COLLADA. For the sake of simplicity, this example will make use of a model that is already animated in 3ds Max. The model contains two animations, which together make up one long animation on a shared timeline. We will export this model and its animation to COLLADA, load it into Papervision3D, and play the two animations. Open animatedMill.max in 3ds Max. This file can be found in the zip file that can be downloaded from: http://www.packtpub.com/files/code/5722_Code.zip. You can see the animation of the model directly in 3ds Max by clicking the play button in the menu at the bottom right corner, which will animate the blades of the mill. The first 180 frames animate the blades from left to right. Frames 181 to 360 animate the blades from right to left. As the model is already animated, we can go ahead with exporting, without making any changes to the model. Export it using the COLLADA filetype and save it somewhere on your computer. When the COLLADA Max exporter settings window pops up, we need to check the Sample animation checkbox. By default Start and End are set to the length of the timeline as it is defined in 3ds Max. In case you just want to export a part of it, you can define the start and end frames you want to export. For this example we leave them as they are: 0 and 360. By completing these steps you have successfully exported an animation in the COLLADA format for Papervision3D. Now, have a look at how we can load the animated model into Papervision3D. First, you need to copy the exported COLLADA and the applied material—Blades.jpg, House.jpg, and Stand.jpg—to the assets folder of your project. To load an animated COLLADA, we can use the DAE class again. We only need to define some parameters at instantiation, so the animation will loop. model = new DAE(true,null,true);model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);DAE(model).load("assets/animatedMill.dae"); Take a look at what these parameters stand for.
Read more
  • 0
  • 0
  • 3013

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

Keeping Extensions Secure with Joomla! 1.5: Part 1

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

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

RESTful Java Web Services Design

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

article-image-create-quick-application-cakephp-part-2
Packt
18 Nov 2009
7 min read
Save for later

Create a Quick Application in CakePHP: Part 2

Packt
18 Nov 2009
7 min read
Editing a Task Now that we can add tasks to CakeTooDoo, the next thing that we will be doing is to have the ability to edit tasks. This is necessary because the users should be able to tick on a task when it has been completed. Also, if the users are not happy with the title of the task, they can change it. To have these features in CakeTooDoo, we will need to add another action to our Tasks Controller and also add a view for this action. Time for Action: Creating the Edit Task Form Open the file tasks_controller.php and add a new action named edit as shown in the following code: function edit($id = null) { if (!$id) { $this->Session->setFlash('Invalid Task'); $this->redirect(array('action'=>'index'), null, true); } if (empty($this->data)) { $this->data = $this->Task->find(array('id' => $id)); } else { if ($this->Task->save($this->data)) { $this->Session->setFlash('The Task has been saved'); $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('The Task could not be saved. Please, try again.'); } } } Inside the directory /CakeTooDoo/app/views/tasks, create a new file named edit.ctp and add the following code to it: <?php echo $form->create('Task');?> <fieldset> <legend>Edit Task</legend> <?php echo $form->hidden('id'); echo $form->input('title'); echo $form->input('done'); ?> </fieldset> <?php echo $form->end('Save');?> We will be accessing the Task Edit Form from the List All Task page. So, let's add a link from the List All Tasks page to the Edit Task page. Open the index.ctp file in /CakeTooDoo/app/views directory, and replace the HTML comment <!-- different actions on tasks will be added here later --> with the following code: <?php echo $html->link('Edit', array('action'=>'edit', $task['Task']['id'])); ?> Now open the List All Tasks page in the browser by pointing it to http://localhost/CakeTooDoo/tasks/index and we will see an edit link beside all the tasks. Click on the edit link of the task you want to edit, and this will take you to do the Edit Task form, as shown below: Now let us add links in the Edit Task Form page to the List All Tasks and Add New Task page. Add the following code to the end of edit.ctp in /CakeTooDoo/app/views: <?php echo $html->link('List All Tasks', array('action'=>'index')); ?><br /> <?php echo $html->link('Add Task', array('action'=>'add')); ?> What Just Happened? We added a new action named edit in the Tasks controller. Then we went on to add the view file edit.ctp for this action. Lastly, we linked the other pages to the Edit Task page using the HTML helper. When accessing this page, we need to tell the action which task we are interested to edit. This is done by passing the task id in the URL. So, if we want to edit the task with the id of 2, we need to point our browser to http://localhost/CakeTooDoo/tasks/edit/2. When such a request is made, Cake forwards this request to the Tasks controller's edit action, and passes the value of the id to the first parameter of the edit action. If we check the edit action, we will notice that it accepts a parameter named $id. The task id passed in the URL is stored in this parameter. When a request is made to the edit action, the first thing that it does is to check if any id has been supplied or not. To let users edit a task, it needs to know which task the user wants to edit. It cannot continue if there is no id supplied. So, if $id is undefined, it stores an error message to the session and redirects to the index action that will show the list of current tasks along with the error message. If $id is defined, the edit action then checks whether there is any data stored in $this->data. If no data is stored in $this->data, it means that the user has not yet edited. And so, the desired task is fetched from the Task model, and stored in $this->data in the line: $this->data = $this->Task->find(array('id' => $id)); Once that is done, the view of the edit action is then rendered, displaying the task information. The view fetches the task information to be displayed from $this->data. The view of the edit action is very similar to that of the add action with a single difference. It has an extra line with echo $form->hidden('id');. This creates an HTML hidden input with the value of the task id that is being edited. Once the user edits the task and clicks on the Save button, the edited data is resent to the edit action and saved in $this->data. Having data in $this->data confirms that the user has edited and submitted the changed data. Thus, if $this->data is not empty, the edit action then tries to save the data by calling the Task Model's save() function: $this->Task->save($this->data). This is the same function that we used to add a new task in the add action. You may ask how does the save() function of model knows when to add a new record and when to edit an existing one? If the form data has a hidden id field, the function knows that it needs to edit an existing record with that id. If no id field is found, the function adds a new record. Once the data has been successfully updated, a success message is stored in the session and it redirects to the index action. Of course the index page will show the success message. Adding Data Validation If you have come this far, by now you should have a working CakeTooDoo. It has the ability to add a task, list all the tasks with their statuses, and edit a task to change its status and title. But, we are still not happy with it. We want the CakeTooDoo to be a quality application, and making a quality application with CakePHP is as easy as eating a cake. A very important aspect of any web application (or software in general), is to make sure that the users do not enter inputs that are invalid. For example, suppose a user mistakenly adds a task with an empty title, this is not desirable because without a title we cannot identify a task. We would want our application to check whether the user enters title. If they do not enter a title, CakeTooDoo should not allow the user to add or edit a task, and should show the user a message stating the problem. Adding these checks is what we call Data Validation. No matter how big or small our applications are, it is very important that we have proper data validation in place. But adding data validation can be a painful and time consuming task. This is especially true, if we have a complex application with lots of forms. Thankfully, CakePHP comes with a built-in data validation feature that can really make our lives much easier. Time for Action: Adding Data Validation to Check for Empty Title In the Task model that we created in /CakeTooDoo/app/models, add the following code inside the Task Model class. The Task Model will look like this: <?php class Task extends AppModel { var $name = 'Task'; var $validate = array( 'title' => array( 'rule' => VALID_NOT_EMPTY, 'message' => 'Title of a task cannot be empty' ) ); } ?> Now open the Add Task form in the browser by pointing it to http://localhost/CakeTooDoo/tasks/add, and try to add a task with an empty title. It will show the following error message:
Read more
  • 0
  • 0
  • 2328

article-image-microsoft-chart-xml-data
Packt
18 Nov 2009
4 min read
Save for later

Microsoft Chart with XML Data

Packt
18 Nov 2009
4 min read
Introduction SQL 2000 Server provided T-SQL language extensions to operate bi-directionally with relational and XML sources. It also provided two system stored procedures, sp_XML_preparedocument and sp_XML_removedocument, that assist the XML to Relational transformation. This support for returning XML data from relational data using the For XML clause is continued in SQL Server 2005 and SQL Server 2008 although the support for XML is lot more extensive. The shape of the data returned by the For XML clause is further modified by choosing the following modes, raw, auto, explicit, or path. As a preparation for this article we will be creating an XML document starting from the PrincetonTemp table used in a previous article, Binding MS Chart Control to LINQ Data Source Control, on this site. Creating an XML document from an SQL Table Open the SQL Server Management and create a new query [SELECT * from PrincetonTemp for XML auto]. You can use the For XML Auto clause to create a XML document (actually what you create is a fragment - a root-less XML without a processing directive) as shown in Figure 01. Figure 01: For XML Auto clause of a SELECT statement The result shown in a table has essentially two columns with the second column containing the document fragment shown in the next listing. Listing 01: <PrincetonTemp Id="1" Month="Jan " Temperature="4.000000000000000e+001" RecordHigh="6.000000000000000e+001"/> <PrincetonTemp Id="2" Month="Feb " Temperature="3.200000000000000e+001" RecordHigh="5.000000000000000e+001"/> <PrincetonTemp Id="3"Month="Mar " Temperature="4.300000000000000e+001" RecordHigh="6.500000000000000e+001"/> <PrincetonTemp Id="4" Month="Apr " Temperature="5.000000000000000e+001" RecordHigh="7.000000000000000e+001"/> <PrincetonTemp Id="5" Month="May " Temperature="5.300000000000000e+001" RecordHigh="7.400000000000000e+001"/> <PrincetonTemp Id="6" Month="Jun " Temperature="6.000000000000000e+001" RecordHigh="7.800000000000000e+001"/> <PrincetonTemp Id="7" Month="Jul " Temperature="6.800000000000000e+001" RecordHigh="7.000000000000000e+001"/> <PrincetonTemp Id="8" Month="Aug " Temperature="7.100000000000000e+001" RecordHigh="7.000000000000000e+001"/> <PrincetonTemp Id="9" Month="Sep " Temperature="6.000000000000000e+001" RecordHigh="8.200000000000000e+001"/> <PrincetonTemp Id="10" Month="Oct " Temperature="5.500000000000000e+001" RecordHigh="6.700000000000000e+001"/> <PrincetonTemp Id="11" Month="Nov " Temperature="4.500000000000000e+001" RecordHigh="5.500000000000000e+001"/> <PrincetonTemp Id="12" Month="Dec " Temperature="4.000000000000000e+001" RecordHigh="6.200000000000000e+001"/> This result is attribute-centric as each row of data corresponds to a row in the relational table with each column represented as an XML attribute. The same data can be extracted in an element centric manner by using the directive elements in the SELECT statement as shown in the next figure. Figure 02: For XML auto, Elements clause of a Select statement This would still give us an XML fragment but now it is displayed with element nodes as shown in the next listing (only two nodes 1 and 12 are shown). Listing 02: <PrincetonTemp><Id>1</Id><Month>Jan </Month><Temperature>4.000000000000000e+001</Temperature> <RecordHigh>6.000000000000000e+001</RecordHigh> </PrincetonTemp> ... <PrincetonTemp><Id>12</Id><Month>Dec </Month><Temperature>4.000000000000000e+001</Temperature> <RecordHigh>6.200000000000000e+001 </RecordHigh></PrincetonTemp> To make a clear distinction between the results returned by the two select statements the first row of data is shown in blue. This has returned elements and not attributes. As you can see the returned XML still lacks a root element as well as the XML processing directive. To continue with displaying this data in MS Chart Save Listing 2 as PrincetonXMLDOC.xml to a location of your choice. Create a Framework 3.5 Web Site project Let us create a web site project and display the chart on the Default.aspx page. Open Visual Studio 2008 from its shortcut on the desktop. Click File  New | Web Site...|(or Shift+Alt+N) to open the New Web Site window. Change the default name of the site to a name of your choice (herein Chart_XMLWeb) as shown. Make sure you are creating a .NET Framework 3.5 web site as shown here. Figure 03: New Framework 3.5 Web Site Project Click on APP_Data folder in the solution explorer as shown in the next figure and click on Add Existing Item… menu item. Figure 04: Add an existing item to the web site folder In the interactive window that gets displayed browse to the location where you saved the PrincetonXMLDOC.xml file and click Add button. This will add the XML file to the ADD_Data folder of the web site project. Double click PrincetonXMLDOC.xml in the web site project folder to display and verify its contents as shown in the next figure. Only nodes 1 and 12 are shown expanded. As mentioned previously this is an XML fragment. Figure 05: Imported PrincetonXMLDOC.xml Modify this document by adding the <root/> as well as the XML processing instruction as shown in the next figure. Build the project. Figure 06: Modified PrincetonXMLDOX.xml (valid XML document)
Read more
  • 0
  • 0
  • 14701

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

Formatting and Enhancing Your Moodle Materials: Part 1

Packt
18 Nov 2009
7 min read
There are three main types of Moodle pages to consider when it comes to design: Moodle front pages Moodle course pages Moodle activities Before we go into detail about design considerations, let's look at examples of each of these to see how we can improve them with a few basic steps. Moodle front page If we take Moodle straight out of the box, set up some blocks for the main menu, provide some useful links, and set the front page settings to show a list of courses, we could have something like this: BEFORE It's functional enough, but not very engaging. Just by making a few changes, we can make the front page much more interesting and readable: AFTER What's changed? There's a new theme (Moodle speak for the color scheme and automatic font choices). As we'll see in a bit, some themes also include tabs and drop-down menus. There's an appropriate image in the top-center of the screen to draw users in. The About this site block has a photo of the administrator, which provides a personal touch. There's an easily-identifiable "start here icon"—another helpful feature that guides your users in the right direction. Moodle course page Like the Moodle front page, a standard course page automatically creates three columns for us to fill with text. If we choose a topics format from the Settings menu and write out a list of activities and links for our course, it could look something like this: BEFORE The problem here is that it's difficult to distinguish important information from unimportant information. There's a lot of scrolling to be done, and there are no visual clues as to what the course page is about. Here's one way of transforming the page: AFTER What's changed? There's a new theme. The theme includes tabs with links to key parts of the site. There's an image related to the course topic (teaching) at the top of the course page. The long list in the previous version has been reduced to a more manageable size. Important information is at the top of the page, and is in a larger font size. It contrasts with less important information, which has a smaller font size. Lines are used to separate different sorts of information. There is more color harmony—at attempt to get the colors to blend. There's an avatar introduction in the left block for new users. Moodle activity When we're pushed for time, it's all too tempting just to set out a list of references without paying due attention to instructions and a helpful hierarchy of information, as in the following example: BEFORE There's a lot of information here. We can use the Book module to organize the information, and make the page more readable, as in the following transformation: AFTER What's changed? The previous list has been divided into sections in the Book module There's a "how-to" section at the beginning of the Table of Contents Graphics from the target websites have been included as visual clues The Tool labels such as Audacity and Findsounds are in a larger font size to make them stand out An action girl icon indicates task instructions Task instructions are in bold blue to make them stand out A grid is used to separate sections As we can see, by enhancing the visual design of our sites we can make our materials more engaging and effective. We can also make them more attractive by improving the quality of the audio, images, and video that we use. Here are some principles we could take on board: Contrast Consider hierarchies of importance in your materials. The default font size on HTML pages is 12 points, similar to what you're reading now. Vary the size to make more important information stand out. You can also use images, buttons, and navigation signs to help users see the function of pages and content more quickly and remember it. Consistency Being consistent in your use of fonts for certain sorts of information, font sizes for ranking information, and navigation links will make it easier for users to understand the site and will make it more aesthetically pleasing. It's also better not to use too many different fonts or make your site too fancy or you will end up with a dog's breakfast. As a rule, it'll look better if you use different sizes of a limited number of fonts, rather than including lots of different fonts. To promote design consistency on your Moodle site, consider setting up a style guide so that all teachers use the same design framework. Alignment A basic principle of graphic design is to make sure that the objects on your page are aligned with each other. Imagine a grid that they stick to. Aligned objects look more professional and enhance contrast within pages. Moodle organizes that automatically for us with front pages and course pages, but when we set up instruction pages for activities, we need to keep alignment principles in mind, as we have more design freedom. Quality Aim for the best quality audio recordings and images. It is likely to make a big difference to language learners if they can listen to clear recordings and easily identify the content of images. This article Each of the following sections in this article contributes to the above principles by demonstrating some of the tools available in Moodle that help you with your design. You'll find a consideration of these and other website design issues at http://www.asktog.com/basics/firstPrinciples.html. Here are the main topics covered in this article: Text Images Videos Sound Navigation Blocks Layout Style guide Accessibility Feedback Text There are two main ways of entering text in Moodle: Adding text pages Adding web pages using the HTML editor The most common way is by using the HTML editor. Most of this section on text will look at formatting options using that. Adding text pages When you select Add a resource... and then Compose a text page, you get a choice of formatting options for your page. You might find it useful to use the Moodle auto-format, as it automatically creates emoticons, paragraphs, and hyperlinks for you if you write in web addresses. Creating hyperlinks is a little more time-consuming if you choose the HTML format, as you have to create all hyperlinks manually. Markdown format is also useful if you want to create a structured document with lists and emphasis. You can, of course, produce all these in the HTML format, using the editing menu. The following options are available when you select Add a resource... and then Compose a text page. Formatting options Details Moodle auto-format This has limited formatting options, but will automatically turn URLs like http://moodle.org into hyperlinks and will include emoticons like J when you type :). It keeps line breaks and converts blank lines into new paragraphs. HTML format This does not automatically format text, but gives you a wide range of possibilities for editing your text. It allows you to change font faces, font sizes, and color, as well as embed graphic images, sound, and video. Note that if you select Compose a text page and then the HTML format option, you will need to enter pure HTML-that's the code that produces web pages. If you are not familiar with HTML, you'll be better off choosing Compose a web page and then using the HTML graphic editor. Plain text format This format keeps spaces and new lines, but no other formatting is available. Markdown format Markdown allows you to easily add emphasis (bold, italics), structure (bullet points and headings), and links (to images or other web resources). You can use Markdown in many places in Moodle. Simply select it from the formatting drop-down list, which is found below the text entry area, wherever you have the choice.  
Read more
  • 0
  • 0
  • 3679
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-event-delivery-network-oracle-soa-suite-11g-r1
Packt
18 Nov 2009
2 min read
Save for later

Event Delivery Network with Oracle SOA Suite 11g R1

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

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

Plotting Geographical Data using Basemap

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

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

Formatting and Enhancing Your Moodle Materials: Part 2

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

article-image-most-wanted-apache-myfaces-trinidad-12-tags-and-tag-attributes
Packt
18 Nov 2009
6 min read
Save for later

Most Wanted Apache MyFaces Trinidad 1.2 Tags and Tag Attributes

Packt
18 Nov 2009
6 min read
Component library structure Trinidad's approach to web technology is comprehensive: Aimed at full control of all the bits and pieces that make up a web application, little should be left that needs to be added. So based on such a closed world, Trinidad presents itself with a wealth of components and tags that even include very basic XHTML tags as replacements for the real XHTML originals. This is no radical replacement approach, rather it enables Trinidad to remain in full control of mechanisms such as partial-page rendering (PPR, also generally known as Ajax) that otherwise would need to deal with potentially incompatible libraries externally. The following image provides an outline of Trinidad's structural package design: Trinidad is divided into the following two namespaces: tr: It is the usual tag library id that references Trinidad's core library tags. It's a large library of over 100 components ranging from layout components and navigational components, to special viewer components that all implicitly support skinning, partial-page rendering, popup dialogs, error or info messaging, and so on. trh: It is the usual tag library id that references Trinidad's XHTML support library tags, a small companion that offers alternatives for those XHTML tags that are usually applied to build XHTML structures, for example, XHTML tables. Let us take a closer look at both namespaces. The upcoming image shows the core API's hierarchical structure. The tags are backed by two types of Trinidad classes—UIX* classes that deal with the JSF component requirements to implement specific JSF lifecycle processing methods, and Core* classes that deal with the specific properties (getters or setters). Trinidad’s XHTML tag library namespace (trh) Two groups can be distinguished from the trh namespace. The first one deals with the definition of an XHTML page and provides the developer with the following tags: <trh:html>: It is used to define the whole XHTML page, analogous to <html> <trh:head>: It is used to define the header, analogous to <head> <trh:body>: It is used to define the main contents, analogous to <body> <trh:script>: It is used to define a JavaScript to be executed, analogous to <script> <trh:tableLayout>: It is used to define an XHTML table. <trh:rowLayout>: It is used to define an XHTML table line, analogous to <tr>; note that it can also be used to display an arbitrary line, particularly when elements need to be kept in one and the same line. Alternatively, it is particularly interesting to look at the tr namespace as it provides some less heavy structures free from table constructions, for instance panelGroupLayout with a layout set to vertical or a panelBorderLayout, both generating div structures instead. <trh:cellFormat>: It is used to define an XHTML table cell as part of an XHTML table. The attributes of each tag are defined in a most consistent, and thus recognizable way. By the way, there are also tags for the construction of framesets such as trh:frame in case anyone still wants to make use of framesets. However, before we deal with the attributes let us conclude this structural overview by a look at the organization of the functionality of the core tag library. Trinidad’s core tag library namespace (tr) The following groups can be functionally distinguished which is also reflected in the packages structure of Trinidad's API (all beginning with org.apache.myfaces.trinidad.component; which has been left out here to avoid repetition). Note that, for completeness, we will also include information on the pure Java side as well as information on the few components that stem from the trh namespace: Basic document composition tags from the core API: document, stylesheet, form, subform. poll also appears here although it is not a composition tag. Form input and display tags, components from the core.input API: inputText, inputDate, inputListOfValues, and so on. Command or navigation tags from core.nav that includes two tag types: One that is focused on command tags that assumes a given form, presupposing the use of form and display tags from the foregoing group—commandButton, commandLink, goButton, goLink, and so on. The other deals exclusively with navigation: navigationTree, navigationPane, breadCrumbs, and so on. Large input and output component tags from core.data, for example, table, tree, and treeTable components. Layout component tags from core.layout, for example, all the swing-like panel tags, such as panelBorderLayout, panelHorizontalLayout, panelAccordion, showDetail, showDetailItem, and so on. Basic output components from core.output that are almost always used in a web application, for example, messages, outputText, outputLabel, spacer, statusIndicator, and so on. Model objects from core.model devised for various tags ; they provide the corresponding view models for their tag viewer counterparts, for example, SortableModel, CollectionModel and RowKeySet for tr:table, ChildPropertyTreeModel for tr:tree and ChartModel for tr:chart. A couple of converter components from trinidad.convert equip JSF and Trinidad input components with powerful JSF conversion, that is, convertNumber and convertDateTime. Validator components from trinidad.validator equip JSF and Trinidad input components with powerful JSF validation such as range validation (validateDateTimeRange) and validation by regular expression match (validateRegExp). Events and event listeners from trinidad.event add new event types and listeners specific for Trinidad components such as those that support Trinidad's dialog framework, for example, commandButton to launch a popup dialogue using LaunchEvent, ReturnEvent, and ReturnListener. It provides only a few tags, but these can be very utile, for example, fileDownloadActionListener, resetActionListener, returnActionListener, and setActionListener. There is a lot more to be found on the pure Java API side that either surfaces indirectly on the tag library as attributes, or is used implicitly by the tags themselves. Furthermore, there are utility classes and context support classes—RequestContext being probably the most prominent one because it offers a lot of functionality, for example, PPR from the server side. The following figure illustrates the Java side of things (it shows what the structure of some of the classes behind core.input look like): The preceding figure is an outline of the core.input API hierarchy. Again, we can see the typical UIX* and Core* structure. Finally, let us take a closer look at the tag attributes.
Read more
  • 0
  • 0
  • 1913
article-image-joomla-15-blogging-and-rss-feeds
Packt
18 Nov 2009
7 min read
Save for later

Joomla! 1.5 Blogging and RSS Feeds

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

article-image-joomla-flash-flashy-templates-headers-banners-and-tickers-part-2
Packt
18 Nov 2009
4 min read
Save for later

Joomla! with Flash: Flashy Templates, Headers, Banners, and Tickers: Part 2

Packt
18 Nov 2009
4 min read
Using Flash headers We have seen that one of the uses of Flash in Joomla! templates is as a header. By using a Flash animation in a site's header you can create some stunning effects. As we have already seen, while designing the template, we may embed Flash animation in the header region and control the layout using an appropriate CSS stylesheet. To embed such Flash animations like these, you can use the <object> </object> XHTML tag. We have seen its use in the previous section. An alternative to this is showing the Flash header at some module position. There are several extensions that can be used for showing Flash objects at a module position. We will be looking at some of them next. Using Flexheader3 Flexheader3 is a Joomla! 1.5-compatible extension for using Flash as headers in Joomla! sites. This is available for download for free at http://flexheader2.andrehotzler.de/en/download/folder/208-flexheader3.html. After downloading the package, install it from the Extensions | Install/Uninstall screen in Joomla! administration. Then click on Extensions | Module Manager. In the Module Manager screen, you will find the module named Flexheader3. Click on it and that shows the Module: [Edit] screen for the Flexheader3 module, as shown in the following screenshot: The Details section is similar to other modules from where you enable the module, select the module position to display this, select the order of display, and assign menus for which this module will be displayed. The module-specific settings are in the Parameters section. As you see, selecting the module position is crucial for this module. Most of the templates don't have a position to display the header using a module. Therefore, you may need to create a module position for displaying a Flash header. The following section shows you how to create a module position displaying a header. Creating a module position To create a module position in your template you need to edit at least two files. Browse to the /templates directory, and click on the name of the template that you want to modify. You need to edit two files in the template folder: index.php and templateDetails.xml. First, open the templateDetails.xml file in your text editor and find the <positions> tag. Under this, type the line highlighted in the following code so that the file looks like the following: <positions> <position>flexheader</position> <position>left</position> <position>user1</position> ... <position>right</position> <position>debug</position> </positions> Remember to type <position>flexheader</position> before ending </positions> tag. Placing it outside the <positions> </positions> block will make the template unusable. After modifying the templateDetails.xml file, open the index.php file in your text editor. Find out the code for including a header image in that template. Generally, this is done by inserting an image using the <img src=... /> tag. If you don't find such a tag, then look for <div id="header" ... > or something like that. In such cases, CSS is used to display the background image to the div element. Once you have found the code for showing the header image, replace it with the following code: <jdoc:include type="modules" name="flexheader" style="RAW" /> This line of code means that you are instructing to include modules designated for the flexheader position. When we assign the Flexheader3 module to this position, the contents of that module will be displayed in this position. Generally, this module will produce a code like the following in this position: <img src="/images/header.png" title="My header image" alt="Header image" style="width: 528px; height: 70px;" /> When changes to index.php are made, save those changes. We will be configuring the module to display a Flash header in this module position.
Read more
  • 0
  • 0
  • 5859

article-image-archiva-team-part-2
Packt
18 Nov 2009
7 min read
Save for later

Archiva in a Team: Part 2

Packt
18 Nov 2009
7 min read
Deleting artifacts in your repository Sometimes the need for deleting artifacts from the repository arises. For example, if an artifact was deployed by accident to the repository or the artifact has already been released but an old snapshot version is still available. In Archiva, there are different ways of deleting artifacts from the repository—through WebDAV, via the web application, through the scheduled repository purging, or by directly deleting it in the file system. It is not recommended that artifacts be deleted directly from the file system. Not only does it require access to the server itself, it is also prone to error. Artifacts that should not be deleted could be deleted by mistake. In case you still want to directly delete an artifact from the file system, all files related to the artifact such as metadata files and checksums must also be deleted. The repository must be scanned as well in order to update the metadata files. This can be done by clicking the Scan Repository Now button of the repository configuration in the Repositories page. The database scanning also needs to be explicitly executed to immediately remove the deleted artifact from the database. One of the advantages of using the Delete Artifact form in the web application is that you do not need to have direct access to the server. All you need is the required Archiva permissions, which come with the Repository Manager role (without the permissions Delete Artifact will not be visible in the navigation menu). Another advantage is that the repository scanning no longer needs to be explicitly executed as Archiva already executes the repository and database scanning consumers to update the index and the database for you. Now, let's try deleting an old artifact from one of the repositories. If you go to http://localhost:8081/archiva/repository/snapshots/com/effectivemaven/centrepoint/centrepoint, the old 1.0-SNAPSHOT version of the project still exists. We will remove this artifact from the repository using the delete artifact web form. First, click Delete Artifact from the navigation menu and then fill in the form as follows: Click the Submit button. After the artifact has been deleted, you should see the confirmation message Artifact 'com.effectivemaven.centrepoint:centrepoint:1.0-SNAPSHOT' was successfully deleted from repository 'snapshots'. If you browse the repository at http://localhost:8081/archiva/repository/snapshots, the related artifacts such as the POM, maven-metadata.xml, and the checksums were also deleted. To delete artifacts through WebDAV, just open the repository using a WebDAV client and delete the artifact like in a regular file system. As for the scheduled repository purging, we will discuss this in the following sections. We have tackled the subjects of repository groups, RSS feeds, and deleting artifacts in the repository. This article would never be complete without covering repository maintenance. The succeeding sections will be all about that. The Archiva reports Archiva generates two types of reports. These are the repository statistics, providing information such as statistical data of a repository's content and the repository health report, which makes us aware of any problems in the repository such as artifacts that have invalid POM files. Both accept different criteria for customizing the generated output as seen in the following screenshot: Now, let's discuss the configuration for each report. Repository statistics This report provides statistical repository information such as the total number of artifacts in the repository, its total size, the number of plugins in the repository, and the likes based on a given repository scan execution time. This report can be used for analyzing the current content of your repositories, and tracking its growth, usage, and evolution over time. The report can be constrained by the given Start Date and End Date. If no Start Date and End Date are provided, all statistics right from the start up to the current date will be included in the report (to a maximum of the number of rows given in the Row Count). For the Repository Statistics, we can also configure the Repositories To Be Compared. If only one repository is selected in Repositories To Be Compared, the generated report will contain details of a single repository. The following is a sample report where only one repository is selected: Let's run through the contents of the sample Repository Statistics report given previously for repository internal. The Total File Count pertains to the total number of files in the repository during each execution of the repository scan. The Total Size, on the other hand, is the size (in bytes) of the repository at that time. The number of unique groups and artifact names are broken down in the report as well as the number of plugins, archetypes, JAR, and WAR files. The last two columns—number of deployments and artifact requests—are not yet implemented but will be fixed in the future releases. On the other hand, if more than one repository is selected in the Repositories To Be Compared, the generated report would contain a comparison of the latest statistics of the repositories based on the specified End Date. This is useful for tracking which repositories are the most utilized. For example, if different development groups host their own repositories, the comparison can show which groups are using the most space. Look at the following screenshot for a sample comparison report to see the difference from the previous one: To allow you to view this report outside of the web application, the report can be exported as a CSV file by clicking on the Export to CSV link. You should be able to open the exported file as an Excel spreadsheet. Repository health One of the secrets behind a successful and reproducible build is a clean and healthy repository. Corrupt metadata or an invalid or missing POM file are the usual causes for a build to break. To prevent this from happening, we must ensure that the repositories we are getting our artifacts from are in good health. Archiva provides a way of doing this through the Repository Health report and its built-in utilities for updating metadata and fixing checksums. The Repository Health report provides a detailed list of artifacts in the repository that are found to be defective. It gives a starting point for correcting any problems and can be used when diagnosing build errors with a particular artifact. For example, a common reason for an artifact being defective is when the version of the artifact specified in the POM is different from the actual version in its filename. This could easily happen when using deploy:deploy-file (or even using the Archiva web upload form) as the actual filename used for the uploaded artifact is determined based on the supplied parameters. It is a possibility that the included POM in the upload has different coordinates from the provided parameters. These defects are discovered during Archiva's database scan, when the actual POM file is read and added to the database. We can narrow down the report by providing a specific Group ID and/or a Repository ID which will be used for querying defective artifacts that match these criteria. If you try querying for the report using the default configuration, you should be able to see a generated report similar to the following one, which shows a defective POM in repository internal. To repair such an error, you can manually fix the POM in the Archiva repository by updating it in the file system. If the defect is caused by a transfer error when the artifact was proxied, you can delete the artifact (including the metadata and checksums) then force Archiva to retrieve it again by requesting it. A word of caution though—making these changes could affect the reproducibility of a dependent project's build. For example, it is possible that the actual artifact in the central repository is the defective one. If you fixed the artifact in your internal Archiva repository, project builds that go through the local proxy may get a successful build. However, the project is built directly off central and the build fails because the dependency artifact is defective. That summarizes monitoring the health of our repositories. The next section discusses the built-in Archiva utilities which in one way or another clean up and repair broken artifacts and metadata in the repositories.    
Read more
  • 0
  • 0
  • 1572
article-image-restful-web-service-implementation-resteasy
Packt
18 Nov 2009
2 min read
Save for later

RESTful Web Service Implementation with RESTEasy

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

article-image-user-interaction-and-email-automation-symfony-13-part1
Packt
18 Nov 2009
14 min read
Save for later

User Interaction and Email Automation in Symfony 1.3: Part1

Packt
18 Nov 2009
14 min read
The signup module We want to provide the users with the functionality to enter their name, email address, and how they found our web site. We want all this stored in a database and to have an email automatically sent out to the users thanking them for signing up. To start things off, we must first add some new tables to our existing database schema. The structure of our newsletter table will be straightforward. We will need one table to capture the users' information and a related table that will hold the names of all the places where we advertised our site. I have constructed the following entity relationship diagram to show you a visual relationship of the tables: All the code used in this article can be accessed here. Let's translate this diagram into XML and place it in the config/schema.xml file: <table name="newsletter_adverts" idMethod="native" phpName="NewsletterAds"> <column name="newsletter_adverts_id" type="INTEGER" required="true" autoIncrement="true" primaryKey="true" /> <column name="advertised" type="VARCHAR" size="30" required="true" /> </table> <table name="newsletter_signups" idMethod="native" phpName="NewsletterSignup"> <column name="id" type="INTEGER" required="true" autoIncrement="true" primaryKey="true" /> <column name="first_name" type="VARCHAR" size="20" required="true" /> <column name="surname" type="VARCHAR" size="20" required="true" /> <column name="email" type="VARCHAR" size="100" required="true" /> <column name="activation_key" type="VARCHAR" size="100" required="true" /> <column name="activated" type="BOOLEAN" default="0" required="true" /> <column name="newsletter_adverts_id" type="INTEGER" required="true"/> <foreign-key foreignTable="newsletter_adverts" onDelete="CASCADE"> <reference local="newsletter_adverts_id" foreign="newsletter_adverts_id" /> </foreign-key> <column name="created_at" type="TIMESTAMP" required="true" /> <column name="updated_at" type="TIMESTAMP" required="true" /> </table> We will need to populate the newsletter_adverts table with some test data as well. Therefore, I have also appended the following data to the fixtures.yml file located in the data/fixtures/ directory: NewsletterAds: nsa1: advertised: Internet Search nsa2: advertised: High Street nsa3: advertised: Poster With the database schema and the test data ready to be inserted into the database, we can once again use the Symfony tasks. As we have added two new tables to the schema, we will have to rebuild everything to generate the models using the following command: $/home/timmy/workspace/milkshake>symfony propel:build-all-load --no-confirmation Now we have populated the tables in the database, and the models and forms have been generated for use too. Binding a form to a database table Symfony contains a whole framework just for the development of forms. The forms framework makes building forms easier by applying object-oriented methods to their development. Each form class is based on its related table in the database. This includes the fields, the validators, and the way in which the forms and fields are rendered. A look at the generated base class Rather than starting off with a simple form, we are going to look at the base form class that has already been generated for us as a part of the build task we executed earlier. Because the code is generated, it will be easier for you to see the initial flow of a form. So let's open the base class for the NewsletterSignupForm form. The file is located at lib/form/base/BaseNewsletterSignupForm.class.php: class BaseNewsletterSignupForm extends BaseFormPropel { public function setup() { $this->setWidgets(array( 'id' => new sfWidgetFormInputHidden(), 'first_name' => new sfWidgetFormInput(), 'surname' => new sfWidgetFormInput(), 'email' => new sfWidgetFormInput(), 'activation_key' => new sfWidgetFormInput(), 'activated' => new sfWidgetFormInputCheckbox(), 'newsletter_adverts_id' => new sfWidgetFormPropelChoice (array('model' => 'NewsletterAds', 'add_empty' => false)), 'created_at' => new sfWidgetFormDateTime(), 'updated_at' => new sfWidgetFormDateTime(), )); $this->setValidators(array( 'id' => new sfValidatorPropelChoice(array ('model' => 'NewsletterSignup', 'column' => 'id', 'required' => false)), 'first_name' => new sfValidatorString(array('max_length' => 20)), 'surname' => new sfValidatorString(array('max_length' => 20)), 'email' => new sfValidatorString(array('max_length' => 100)), 'activation_key' => new sfValidatorString(array('max_length' => 100)), 'activated' => new sfValidatorBoolean(), 'newsletter_adverts_id'=> new sfValidatorPropelChoice(array ('model' => 'NewsletterAds', 'column' => 'newsletter_adverts_id')), 'created_at' => new sfValidatorDateTime(), 'updated_at' => new sfValidatorDateTime(), )); $this->widgetSchema->setNameFormat('newsletter_signup[%s]'); $this->errorSchema = new sfValidatorErrorSchema ($this->validatorSchema); parent::setup(); } There are five areas in this base class that are worth noting: This base class extends the BaseFormPropel class, which is an empty class. All base classes extend this class, which allows us to add global settings to all our forms. All of the columns in our table are treated as fields in the form, and are referred to as widgets. All of these widgets are then attached to the form by adding them to the setWidgets() method. Looking over the widgets in the array, you will see that they are pretty standard, such as sfWidgetFormInputHidden(), sfWidgetFormInput(). However, there is one widget added that follows the relationship between the newsletter_sigups table and the newsletter_adverts table. It is the sfWidgetFormPropelChoice widget. Because there is a 1:M relation between the tables, the default behavior is to use this widget, which creates an HTML drop-down box and is populated with the values from the newsletter_adverts table. As a part of the attribute set, you will see that it has set the model needed to retrieve the values to NewsletterAds and the newsletter_adverts_id column for the actual values of the drop-down box. All the widgets on the form must be validated by default. To do this, we have to call the setValidators() method and add the validation requirements to each widget. At the moment, the generated validators reflect the attributes of our database as set in the schema. For example, the first_name field in the statement 'first_name' => new sfValidatorString(array('max_length' => 20)) demonstrates that the validator checks if the maximum length is 20. If you remember, in our schema too, the first_name column is set to 20 characters. The final part calls the parent's setup() function. The base class BaseNewsletterSignupForm contains all the components needed to generate the form for us. So let's get the form on a page and take a look at the method to customize it. There are many widgets that Symfony provides for us. You can find the classes for them inside the widget/ directory of your Symfony installation. The Symfony propel task always generates a form class and its corresponding base class. Of course, not all of our tables will need to have a form bound to them. Therefore, delete all the form classes that are not needed. Rendering the form Rendering this basic form requires us to instantiate the form object in the action. Assigning the form object to the global $this variable means that we can pass the form object to the template just like any other variable. So let's start by implementing the newsletter signup module. In your terminal window, execute the generate:module task like this: $/home/timmy/workspace/milkshake>symfony generate:module frontend signup Now we can start with the application logic. Open the action class from apps/frontend/modules/signup/actions/actions.class.php for the signup module and add the following logic inside the index action: public function executeIndex(sfWebRequest $request) { $this->form = new NewsletterSignupForm(); return sfView::SUCCESS; } As I had mentioned earlier, the form class deals with the form validation and rendering. For the time being, we are going to stick to the default layout by allowing the form object to render itself. Using this method initially will allow us to create rapid prototypes. Let's open the apps/frontend/signup/templates/indexSuccess.php template and add the following view logic: <form action="<?php echo url_for('signup/submit') ?>" method="POST"> <table><?php echo $form ?></table> <input type="submit" /> </form> The form class is responsible for rendering of the form elements only. Therefore, we have to include the <form> and submit HTML tags that wrap around the form. Also, the default format of the form is set to 'table'. Again, we must also add the start and end tags of the <table>. At this stage, we would normally be able to view the form in the browser. But doing so will raise a Symfony exception error. The cause of this is that the results retrieved from the newsletter_adverts table are in the form of an array of objects. These results need to populate the select box widget. But in the current format, this is not possible. Therefore, we have to convert each object into its string equivalent. To do this, we need to create a PHP magic function of __toString() in the DAO class NewsletterAds. The DAO class for NewlsetterAds is located at lib/model/NewsletterAds.php just as all of the other models. Here we need to represent each object as its name, which is the value in the advertised column. Remember that we need to add this method to the DAO class as this represents a row within the results, unlike the peer class that represents the entire result set. Let's add the function to the NewsletterAds class as I have done here: class NewsletterAds extends BaseNewsletterAds { public function __toString() { return $this->getAdvertised(); } } We are now ready to view the completed form. In your web browser, enter the URL http://milkshake/frontend_dev.php/signup and you will see the result shown in the following screenshot: As you can see, although the form has been rendered according to our table structure, the fields which we do not want the user to fill in are also included. Of course, we can change this quiet easily. But before we take a look at the layout of the form, let's customize the widgets and widget validators. Now we can begin working on the application logic for submitting the form. Customizing form widgets and validators All of the generated form classes are located in the lib/form and the lib/form/base directories. The latter is where the default generated classes are located, and the former is where the customizable classes are located. This follows the same structure as the models. Each custom form class inherits from its parent. Therefore, we have to override some of the functions to customize the form. Let's customize the widgets and validators for the NewsletterSignupForm. Open the lib/forms/NewsletterSignupForm.class.php file and paste the following code inside the configure() method: //Removed unneeded widgets unset( $this['created_at'], $this['updated_at'], $this['activation_key'], $this['activated'], $this['id'] ); //Set widgets //Modify widgets $this->widgetSchema['first_name'] = new sfWidgetFormInput(); $this->widgetSchema['newsletter_adverts_id'] = new sfWidgetFormPropelChoice(array('model' => 'NewsletterAds', 'add_empty' => true, 'label'=>'Where did you find us?')); $this->widgetSchema['email'] = new sfWidgetFormInput (array('label' => 'Email Address')); //Add validation $this->setValidators(array ('first_name'=> new sfValidatorString(array ('required' => true), array('required' => 'Enter your firstname')), 'surname'=> new sfValidatorString(array('required' => true), array('required' => 'Enter your surname')), 'email'=> new sfValidatorString(array('required' => true), array('invalid' => 'Provide a valid email', 'required' => 'Enter your email')), 'newsletter_adverts_id' => new sfValidatorPropelChoice(array('model' => 'NewsletterAds', 'column' => 'newsletter_adverts_id'), array('required' => 'Select where you found us')), )); //Set post validators $this->validatorSchema->setPostValidator( new sfValidatorPropelUnique(array('model' => 'NewsletterSignup', 'column' => array('email')), array('invalid' => 'Email address is already registered')) ); //Set form name $this->widgetSchema->setNameFormat('newsletter_signup[%s]'); //Set the form format $this->widgetSchema->setFormFormatterName('list'); Let's take a closer look at the code. Removing unneeded fields To remove the fields that we do not want to be rendered, we must call the PHP unset() method and pass in the fields to unset. As mentioned earlier, all of the fields that are rendered need a corresponding validator, unless we unset them. Here we do not want the created_at and activation_key fields to be entered by the user. To do so, the unset() method should contain the following code: unset( $this['created_at'], $this['updated_at'], $this['activation_key'], $this['activated'], $this['id'] ); Modifying the form widgets Although it'll be fine to use the remaining widgets as they are, let's have a look at how we can modify them: //Modify widgets $this->widgetSchema['first_name'] = new sfWidgetFormInput(); $this->widgetSchema['newsletter_adverts_id'] = new sfWidgetFormPropelChoice(array('model' => 'AlSignupNewsletterAds', 'add_empty' => true, 'label'=>'Where did you find us?')); $this->widgetSchema['email'] = new sfWidgetFormInput(array('label' => 'Email Address')); There are several types of widgets available, but our form requires only two of them. Here we have used the sfWidgetFormInput() and sfWidgetFormPropelChoice() widgets. Each of these can be initialized with several values. We have initialized the email and newsletter_adverts_id widgets with a label. This basically renders the label field associated to the widget on the form. We do not have to include a label because Symfony adds the label according to the column name. Adding form validators Let's add the validators in a similar way as we have added the widgets: //Add validation $this->setValidators(array( 'first_name'=> new sfValidatorString(array('required' => true), array('required' => 'Enter your firstname')), 'surname'=> new sfValidatorString(array('required' => true), array('required' => 'Enter your surname')), 'email'=> new sfValidatorEmail(array('required' => true), array('invalid' => 'Provide a valid email', 'required' => 'Enter your email')), 'newsletter_adverts_id' => new sfValidatorPropelChoice(array ('model' => 'NewsletterAds', 'column' => 'newsletter_adverts_id'), array('required' => 'Select where you found us')), )); //Set post validators $this->validatorSchema->setPostValidator(new sfValidatorPropelUnique(array('model' => 'NewsletterSignup', 'column' => array('email')), array('invalid' => 'Email address is already registered')) ); Our form will need four different types of validators: sfValidatorString: This checks the validity of a string against a criteria. It takes four arguments—required, trim, min_length, and max_length. SfValidatorEmail: This validates the input against the pattern of an email address. SfValidatorPropelChoice: It validates the value with the values in the newsletter_adverts table. It needs the model and column that are to be used.   SfValidatorPropelUnique: Again, this validator checks the value against the values in a given table column for uniqueness. In our case, we want to use the NewsletterSignup model to test if the email column is unique. As mentioned earlier, all the fields must have a validator. Although it's not recommended, you can allow extra parameters to be passed in. To achieve this, there are two steps: You must disable the default option of having all fields validated by $this->validatorSchema->setOption('allow_extra_fields', true). Although the above step allows the values to bypass validation, they will be filtered out of the results. To prevent this, you will have to set $this->validatorSchema->setOption('filter_extra_fields', false). Form naming convention and setting its style The final part we added is the naming convention for the HTML attributes and the style in which we want the form rendered. The HTML output will use our naming convention. For example, in the following code, we have set the convention to newsletter_signup[fieldname] for each input field's name. //Set form name $this->widgetSchema->setNameFormat('newsletter_signup[%s]'); //Set the form format $this->widgetSchema->setFormFormatterName('list'); Two formats are shipped with Symfony that we can use to render our form. We can either render it in an HTML table or an unordered list. As we have seen, the default is an HTML table. But by setting this as list, the form is now rendered as an unordered HTML list, just like the following screenshot. (Of course, I had to replace the <table> tags with the <ul> tags.)
Read more
  • 0
  • 0
  • 2207
Modal Close icon
Modal Close icon