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

How-To Tutorials

7018 Articles
article-image-flash-development-android-visual-input-camera
Packt
21 Jun 2011
7 min read
Save for later

Flash Development for Android: Visual Input via Camera

Packt
21 Jun 2011
7 min read
Camera and microphone are standard accessories on most mobile devices and Android devices are no exception to this. The present article will cover everything from accessing the camera and taking photos to recording video data. All of the recipes in this article are represented as pure ActionScript 3 classes and are not dependent upon external libraries or the Flex framework. Therefore, we will be able to use these examples in any IDE we wish. Detecting camera and microphone support in Android Nearly all Android devices come equipped with camera hardware for capturing still images and video. Many devices now have both front and rear-facing cameras. It is important to know whether the default device camera is usable through our application. We should never assume the availability of certain hardware items, no matter how prevalent across devices. Similarly, we will want to be sure to have access to the device microphone as well, when capturing video or audio data. How to do it... We will determine which audio and video APIs are available to us on our Android device: First, import the following classes into your project: import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.media.Camera; import flash.media.CameraUI; import flash.media.Microphone; import flash.text.TextField; import flash.text.TextFormat; Declare a TextField and TextFormat object pair to allow visible output upon the device: private var traceField:TextField; private var traceFormat:TextFormat; We will now set up our TextField, apply a TextFormat, and add the TextField to the DisplayList. Here, we create a method to perform all of these actions for us: protected function setupTextField():void { traceFormat = new TextFormat(); traceFormat.bold = true; traceFormat.font = "_sans"; traceFormat.size = 44; traceFormat.align = "center"; traceFormat.color = 0x333333; traceField = new TextField(); traceField.defaultTextFormat = traceFormat; traceField.selectable = false; traceField.mouseEnabled = false; traceField.width = stage.stageWidth; traceField.height = stage.stageHeight; addChild(traceField); } Now, we must check the isSupported property of each of these objects. We create a method here to perform this across all three and write results to a TextField: protected function checkCamera():void { traceField.appendText("Camera: " + Camera.isSupported + "n"); traceField.appendText("CameraUI: " + CameraUI.isSupported + "n"); traceField.appendText("Microphone: " + Microphone.isSupported + "n"); } We now know the capabilities of video and audio input for a particular device and can react accordingly: How it works... Each of these three classes has a property isSupported, which we may invoke at any time to verify support on a particular Android device. The traditional Camera and mobile-specific CameraUI both refer to the same hardware camera, but are entirely different classes for dealing with the interaction between Flash and the camera itself, as CameraUI relies upon the default device camera applications to do all the capturing, and Camera works exclusively within the Flash environment. The traditional Microphone object is also supported in this manner. There's more... It is important to note that even though many Android devices come equipped with more than one camera, only the primary camera (and microphone) will be exposed to our application. Support for multiple cameras and other sensors will likely be added to the platform as Android evolves. Using the traditional camera API to save a captured image When writing applications for the web through Flash player, or for a desktop with AIR, we have had access to the Camera class through ActionScript. This allows us to access different cameras attached to whatever machine we are using. On Android, we can still use the Camera class to access the default camera on the device and access the video stream it provides for all sorts of things. In this example, we will simply grab a still image from the Camera feed and save it to the Android CameraRoll. How to do it... We will construct a Video object to bind the Camera stream to, and use BitmapData methods to capture and then save our rendered image using the mobile CameraRoll API: At a minimum, we need to import the following classes into our project: import flash.display.BitmapData; import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.TouchEvent; import flash.media.Camera; import flash.media.CameraRoll; import flash.media.Video; import flash.ui.Multitouch; import flash.ui.MultitouchInputMode; Now we must declare the object instances necessary for camera access and file reference: private var video:Video; private var camera:Camera; private var capture:BitmapData; private var cameraRoll:CameraRoll; private var videoHolder:Sprite; Initialize a Video object, passing in the desired width and height, and add it to the DisplayList: protected function setupVideo():void { videoHolder = new Sprite(); videoHolder.x = stage.stageWidth/2; videoHolder.y = stage.stageHeight/2; video = new Video(360, 480); videoHolder.addChild(video); video.x = -180; video.y = -240; videoHolder.rotation = 90; addChild(videoHolder); } Initialize a Camera object and employ setMode to specify width, height, and frames per second before attaching the Camera to our Video on the DisplayList: protected function setupCamera():void { camera = Camera.getCamera(); camera.setMode(480, 360, 24); video.attachCamera(camera); } We will now register a TouchEvent listener of type TOUCH_TAP to the Stage. This will enable the user to take a snapshot of the camera display by tapping the device screen: protected function registerListeners():void { Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; stage.addEventListener(TouchEvent.TOUCH_TAP, saveImage); } To capture an image from the camera feed, we will initialize our BitmapData object, matching the width and height of our Video object, and employ the draw method to translate the Video pixels to BitmapData. To save our acquired image to the device, we must initialize a CameraRoll object and invoke addBitmapData(), passing in the BitmapData object we have created using Video object pixels. We will also determine whether or not this device supports the addBitmapData() method by verifying CameraRoll. supportsAddBitmapData is equal to true: protected function saveImage(e:TouchEvent):void { capture = new BitmapData(360, 480); capture.draw(video); cameraRoll = new CameraRoll(); if(CameraRoll.supportsAddBitmapData){ cameraRoll.addBitmapData(capture); } } If we now check our Android Gallery, we will find the saved image: How it works... Most of this is performed exactly as it would be with normal Flash Platform development on the desktop. Attach a Camera to a Video, add the Video to the DisplayList, and then do whatever you need for your particular application. In this case, we simply capture what is displayed as BitmapData. The CameraRoll class, however, is specific to mobile application development as it will always refer to the directory upon which the device camera stores the photographs it produces. If you want to save these images within a different directory, we could use a File or FileReference object to do so, but this involves more steps for the user. Note that while using the Camera class, the hardware orientation of the camera is landscape. We can deal with this by either restricting the application to landscape mode, or through rotations and additional manipulation as we've performed in our example class. We've applied a 90 degree rotation to the image in this case using videoHolder.rotation to account for this shift when reading in the BitmapData. Depending on how any specific application handles this, it may not be necessary to do so. There's more... Other use cases for the traditional Camera object are things such as sending a video stream to Flash Media Server for live broadcast, augmented reality applications, or real-time peer to peer chat.
Read more
  • 0
  • 0
  • 4143

article-image-cryengine-3-sandbox-basics
Packt
21 Jun 2011
9 min read
Save for later

CryENGINE 3: Sandbox Basics

Packt
21 Jun 2011
9 min read
  CryENGINE 3 Cookbook Over 100 recipes written by Crytek developers for creating AAA games using the technology that created Crysis 2 Placing the objects in the world Placing objects is a simple task; however, basic terrain snapping is not explained to most new developers. It is common to ask why, when dragging and dropping an object into the world, they cannot see the object. This section will teach you the easiest ways to place an object into your map by using the Follow Terrain method. Getting ready Have My_Level open inside of Sandbox (after completing either of the Terrain sculpting or Generating a procedural terrain recipes). Review the Navigating a level with the Sandbox Camera recipe to get familiar with the Perspective View. Have the Rollup Bar open and ready. Make sure you have the EditMode ToolBar open (right-click the top main ToolBar and tick EditMode ToolBar). How to do it... First select the Follow Terrain button. Then open the Objects tab within the Rollup Bar. Now from the Brushes browser, select any object you wish to place down (for example, defaults/box). You may either double-click the object, or drag-and-drop it onto the Perspective View. Move your mouse anywhere where there is visible terrain and then click once more to confirm the position you wish to place it in. How it works... The Follow Terrain tool is a simple tool that allows the pivot of the object to match the exact height of the terrain in that location. This is best seen on objects that have a pivot point close to or near the bottom of them. There's more... You can also follow terrain and snap to objects. This method is very similar to the Follow Terrain method, except that this also includes objects when placing or moving your selected object. This method does not work on non-physicalized objects.   Refining the object placement After placing the objects in the world with just the Follow Terrain or Snapping to Objects, you might find that you will need to adjust the position, rotation, or scale of the object. In this recipe, we will show you the basics of how you might be able to do so along with a few hotkey shortcuts to make this process a little faster. This works with any object that is placed in your level, from Entities to Solids. Getting ready Have My_Level open inside of Sandbox Review the Navigating a level with the Sandbox Camera recipe to get familiar with the Perspective View. Make sure you have the EditMode ToolBar open (right-click on the top main ToolBar and tick EditMode ToolBar). Place any object in the world. How to do it... In this recipe, we will call your object (the one whose location you wish to refine) Box for ease of reference. Select Box. After selecting Box, you should see a three axis widget on it, which represents each axis in 3D space. By default, these axes align to the world: Y = Forward X = Right Z = Up To move the Box in the world space and change its position, proceed with the following steps: Click on the Select and Move icon in the EditMode ToolBar (1 for the keyboard shortcut). Click on the X arrow and drag your mouse up and down relative to the arrow's direction. Releasing the mouse button will confirm the location change. You may move objects either on a single axis, or two at once by clicking and dragging on the plane that is adjacent to any two axes: X + Y, X + Z, or Y + Z. To rotate an object, do the following: Select Box (if you haven't done so already). Click on the Select and Rotate icon in the EditMode ToolBar (2 for the keyboard shortcut). Click on the Z arrow (it now has a sphere at the end of it) and drag your mouse from side to side to roll the object relative to the axis. Releasing the mouse button will confirm the rotation change. You cannot rotate an object along multiple axes. To scale an object, do the following: Select Box (if you haven't done so already). Click on the Select and Scale icon in the EditMode ToolBar (3 for the keyboard shortcut). Click on the CENTER box and drag your mouse up and down to scale on all three axes at once. Releasing the mouse button will confirm the scale change. It is possible to scale on just one axis or two axes; however, this is highly discouraged as Non-Uniform Scaling will result in broken physical meshes for that object. If you require an object to be scaled up, we recommend you only scale uniformly on all three axes! There's more... Here are some additional ways to manipulate objects within the world. Local position and rotation To make position or rotation refinement a bit easier, you might want to try changing how the widget will position or rotate your object by changing it to align itself relative to the object's pivot. To do this, there is a drop-down menu in the EditMode ToolBar that will have the option to select Local. This is called Local Direction. This setup might help to position your object after you have rotated it. Grid and angle snaps To aid in positioning of non-organic objects, such as buildings or roads, you may wish to turn on the Snap to Grid option. Turning this feature on will allow you to move the object on a grid (currently relative to its location). To change the grid spacing, click the drop-down arrow next to the number to change the spacing (grid spacing is in meters). Angle Snaps is found immediately to the right of the Grid Snaps. Turning this feature on will allow you to rotate an object by every five degrees. Ctrl + Shift + Click Even though it is a Hotkey, to many developers this hotkey is extremely handy for initial placement of objects. It allows you to move the object quickly to any point on any physical surface relative to your Perspective View.   Utilizing the layers for multiple developer collaboration A common question that is usually asked about the CryENGINE is how does one developer work on the same level as another at the same time. The answer is—Layers. In this recipe, we will show you how you may be able to utilize the layer system for not only your own organization, but to set up external layers for other developers to work on in parallel. Getting ready Have My_Level open inside of Sandbox. Review the Navigating a level with the Sandbox Camera to get familiar with the Perspective View. Have the Rollup Bar open and ready. Review the Placing the objects in the world (place at least two objects) recipe. How to do it... For this recipe, we will assume that you have your own repository for your project or some means to send your work to others in your team. First, start by placing down two objects on the map. For the sake of the recipe, we shall refer to them as Box1 and Box2. After you've placed both boxes, open the Rollup Bar and bring up the Layers tab. Create a new layer by clicking the New Layer button (paper with a + symbol). A New Layer dialog box will appear. Give it the following parameters: Name = ActionBubble_01 Visible = True External = True Frozen = False Export To Game = True Now select Box1 and open the Objects tab within the Rollup Bar. From here you will see in the main rollup of this object with values such as – Name, Helper Size, MTL, and Minimal Spec. But also in this rollup you will see a button for layers (it should be labelled as Main). Clicking on that button will show you a list of all other available layers. Clicking again on another layer that is not highlighted will move this object to that layer (do this now by clicking on ActionBubble_01). Now save your level by clicking—File | Save. Now in your build folder, go to the following location: -... GameLevelsMy_Level. From here you will notice a new folder called Layers. Inside that folder, you will see ActionBubble_01.lyr. This layer shall be the layer that your other developers will work on. In order for them to be able to do so, you must first commit My_Level.cry and the Layers folder to your repository (it is easiest to commit the entire folder). After doing so, you may now have your other developer make changes to that layer by moving Box1 to another location. Then have them save the map. Have them commit only the ActionBubble_01.lyr to the repository. Once you have retrieved it from the updated repository, you will notice that Box1 will have moved after you have re-opened My_Level.cry in the Editor with the latest layer. How it works... External layers are the key to this whole process. Once a .cry file has been saved to reference an external layer, it will access the data inside of those layers upon loading the level in Sandbox. It is good practice to assign a Map owner who will take care of the .cry file. As this is the master file, only one person should be in charge of maintaining it by creating new layers if necessary. There's more... Here is a list of limitations of what external layers cannot hold. External layer limitations Even though any entity/object you place in your level can be placed into external layers, it is important to note that there are some items that cannot be placed inside of these layers. Here is a list of the common items that are solely owned by the .cry file: Terrain Heightmap Unit Size Max Terrain Height Holes Textures Vegetation Environment Settings (unless forced through Game Logic) Ocean Height Time of Day Settings (unless forced through Game Logic) Baked AI Markup (The owner of the .cry file must regenerate AI if new markup is created on external layers) Minimap Markers  
Read more
  • 0
  • 0
  • 12199

article-image-generating-jsf-applications-jpa-entities
Packt
20 Jun 2011
6 min read
Save for later

Generating JSF Applications from JPA Entities

Packt
20 Jun 2011
6 min read
Java EE 6 Development with NetBeans 7 Develop professional enterprise Java EE applications quickly and easily with this popular IDE To generate JSF pages from existing JPA entities, we need to right-click on the project, select File | New File, then select the JavaServer Faces category and the JSF Pages from Entity Classes file type. In order for us to be able to generate JSF pages from existing JPA entities, the current project must be a Web Application project. After clicking on Next>, we need to select one or more JPA entities. We would typically want to select all of them, they can easily be selected by clicking on the Add All>> button. The next page in the wizard allows us to specify a package for newly created JSF managed beans. Two types of classes are generated by the wizard, JPA Controllers and JSF Classes, we can specify packages for both of these individually. We are also given the opportunity to specify a folder for the JSF pages to be created, if we leave this field blank, pages will be created in our project's Web Pages folder. The value of the Session Bean Package and JSF Classes Package text fields default to the package where our JPA entities reside. It is a good idea to modify this default since placing the JSF managed beans in a different package separates the data access layer classes from the user interface and controller layers of our application. After clicking on Finish, a complete web application that can perform CRUD operations will be created. As we can see, NetBeans generates a folder for each of our entities under the Web Pages folder of our application. Each of the folders has a Detail, Edit, List, and New XHTML files. These files are JSF pages using Facelets as their view technology. The Detail page will display all properties for a JPA entity, the Edit page will allow users to update information for a specific entity, the List page will display all instances of a specific entity in the database, and the New page will provide functionality to create new entities. The generated application is a standard JSF application. We can execute it by simply right-clicking on the project and selecting Run. At that point the usual things happen, the application server is started if it wasn't up already, the application is deployed, and a web browser window is opened displaying the welcome page for our application. As we can see, the welcome page contains a link corresponding to each of our JPA entities. The links will display a table displaying all existing instances of our entity in the database. When we click on the Show All Customer Items, the following page is shown: Since we haven't inserted any data to the database yet, the page displays the message (No Customer Items Found). We can insert a customer into the database by clicking on the Create New Customer link. Notice how an input field is generated for each property in our entity, which in turn corresponds to a column in the database table. As we can see, an input field was generated for the primary key field of our entity. This field is only generated if the JPA entity does not use a primary key generation strategy. After entering some information on the page and clicking on the Save link, the data is saved, or the form is cleared and the message Customer was successfully created is shown. We can see our newly created customer by clicking on Show All Customer Items. At this point we can see our newly created customer in the list of customers on this JSP. Notice that the page has links to View, Edit, and Destroy (delete) the entity. Let's say we would want to add an address for our customer, we could do so by clicking on the Index link, then clicking on Show All Address Items, then on New Address. The Address entity is at the "one" end of several one-to-many relationships, notice how a combo box is generated for each one of the entities at the "many" end. Since we wish to assign this address to the customer we just added, we attempt to select a customer from the CustomerId combo box. A better name could be used for the CustomerId field, the reason this is the label for the combo box is because it matches the property name on the Address JPA entity, which in turn could have a better name such as customer. Recall that all entities on this project were automatically generated from an existing database schema. Clicking on the combo box reveals a cryptic, almost undecipherable (from the users' point of view anyway) label for our customer. The reason we see this label is because the labels generated for each item in the combo box come from the toString() method of the entities used to populate it. We can work around this issue by modifying the toString() method so that it returns a user-friendly String suitable to use as a label. As we can see, the generated code from NetBeans wizards could certainly use some tweaking, such as modifying the toString() methods of each JPA entity so that it can be used as a label, modifying some of the property names on the entities so that they make more sense to us developers, modifying the labels on the generated JSF pages so that they are more user-friendly, and last but not least, the pages themselves are not very visually appealing. It would be a good idea to modify them so that they don't look so plain. Nevertheless, as we can see we can have a fully working application completely created by a few clicks of the mouse. This functionality certainly saves us a lot of time and effort. Summary In this article we saw how NetBeans can generate a complete JSF application from existing JPA entities. Further resources on this subject: Java Refactoring in NetBeans [Article] NetBeans IDE 7: Building an EJB Application [Article] Java Data Objects and Service Data Objects in SOA [Article]
Read more
  • 0
  • 0
  • 2882

article-image-interacting-gnu-octave-operators
Packt
20 Jun 2011
6 min read
Save for later

Interacting with GNU Octave: Operators

Packt
20 Jun 2011
6 min read
GNU Octave Beginner's Guide Become a proficient Octave user by learning this high-level scientific numerical tool from the ground up The reader will benefit from the previous article on GNU Octave Variables. Basic arithmetic Octave offers easy ways to perform different arithmetic operations. This ranges from simple addition and multiplication to very complicated linear algebra. In this section, we will go through the most basic arithmetic operations, such as addition, subtraction, multiplication, and left and right division. In general, we should think of these operations in the framework of linear algebra and not in terms of arithmetic of simple scalars. Addition and subtraction We begin with addition. Time for action – doing addition and subtraction operations I have lost track of the variables! Let us start afresh and clear all variables first: octave:66> clear (Check with whos to see if we cleared everything). Now, we define four variables in a single command line(!) octave:67> a = 2; b=[1 2 3]; c=[1; 2; 3]; A=[1 2 3; 4 5 6]; Note that there is an important difference between the variables b and c; namely, b is a row vector, whereas c is a column vector. Let us jump into it and try to add the different variables. This is done using the + character: octave:68>a+a ans = 4 octave:69>a+b ans = 3 4 5 octave:70>b+b ans = 2 4 6 octave:71>b+c error: operator +: nonconformant arguments (op1 is 1x3, op2 is 3x1) It is often convenient to enter multiple commands on the same line. Try to test the difference in separating the commands with commas and semicolons. What just happened? The output from Command 68 should be clear; we add the scalar a with itself. In Command 69, we see that the + operator simply adds the scalar a to each element in the b row vector. This is named element-wise addition. It also works if we add a scalar to a matrix or a higher dimensional array. Now, if + is applied between two vectors, it will add the elements together element-wise if and only if the two vectors have the same size, that is, they have same number of rows or columns. This is also what we would expect from basic linear algebra. From Command 70 and 71, we see that b+b is valid, but b+c is not, because b is a row vector and c is a column vector—they do not have the same size. In the last case, Octave produces an error message stating the problem. This would also be a problem if we tried to add, say b with A: octave:72>b+A error: operator +: nonconformant arguments (op1 is 1x3, op2 is 2x3) From the above examples, we see that adding a scalar to a vector or a matrix is a special case. It is allowed even though the dimensions do not match! When adding and subtracting vectors and matrices, the sizes must be the same. Not surprisingly, subtraction is done using the - operator. The same rules apply here, for example: octave:73> b-b ans = 0 0 0 is fine, but: octave:74> b-c error: operator -: nonconformant arguments (op1 is 1x3, op2 is 2x3) produces an error. Matrix multiplication The * operator is used for matrix multiplication. Recall from linear algebra that we cannot multiply any two matrices. Furthermore, matrix multiplication is not commutative. For example, consider the two matrices: The matrix product AB is defined, but BA is not. If A is size n x k and B has size k x m, the matrix product AB will be a matrix with size n x m. From this, we know that the number of columns of the "left" matrix must match the number of rows of the "right" matrix. We may think of this as (n x k)(k x m) = n x m. In the example above, the matrix product AB therefore results in a 2 x 3 matrix: Time for action – doing multiplication operations Let us try to perform some of the same operations for multiplication as we did for addition: octave:75> a*a ans = 4 octave:76> a*b ans = 2 4 6 octave:77> b*b error: operator *: nonconformant arguments (op1 is 1x3, op2 is 1x3) octave:78> b*c ans = 14 What just happened? From Command 75, we see that * multiplies two scalar variables just like standard multiplication. In agreement with linear algebra, we can also multiply a scalar by each element in a vector as shown by the output from Command 76. Command 77 produces an error—recall that b is a row vector which Octave also interprets as a 1 x 3 matrix, so we try to perform the matrix multiplication (1 x 3)(1 x 3), which is not valid. In Command 78, on the other hand, we have (1 x 3)(3 x 1) since c is a column vector yielding a matrix with size 1 x 1, that is, a scalar. This is, of course, just the dot product between b and c. Let us try an additional example and perform the matrix multiplication between A and B discussed above. First, we need to instantiate the two matrices, and then we multiply them: octave:79> A=[1 2; 3 4]; B=[1 2 3; 4 5 6]; octave:80> A*B ans = 9 12 15 19 26 33 octave:81> B*A error: operator *: nonconformant arguments (op1 is 2x3, op2 is 2x2) Seems like Octave knows linear algebra! Element-by-element, power, and transpose operations If the sizes of two arrays are the same, Octave provides a convenient way to multiply the elements element-wise. For example, for B: octave:82> B.*B ans = 1 4 9 16 25 36 Notice that the period (full stop) character precedes the multiplication operator. The period character can also be used in connection with other operators. For example: octave:83> B.+B ans = 2 4 6 8 10 12 which is the same as the command B+B. If we wish to raise each element in B to the power 2.1, we use the element-wise power operator.ˆ: octave:84> B.^2.1 ans = 1.0000 4.2871 10.0451 18.3792 29.3655 43.0643 You can perform element-wise power operation on two matrices as well (if they are of the same size, of course): octave:85> B.^B ans = 1 4 27 256 3125 46656 If the power is a real number, you can use ˆ instead of .ˆ; that is, instead of Command 84 above, you can use: octave:84>Bˆ2.1 Transposing a vector or matrix is done via the 'operator. To transpose B, we simply type: octave:86> B' ans = 1 4 2 5 3 6 Strictly, the ' operator is a complex conjugate transpose operator. We can see this in the following examples: octave:87> B = [1 2; 3 4] + I.*eye(2) B = 1 + 1i 2 + 0i 3 + 0i 4 + 1i octave:88> B' ans = 1 - 1i 3 - 0i 2 - 0i 4 - 1i Note that in Command 87, we have used the .* operator to multiply the imaginary unit with all the elements in the diagonal matrix produced by eye(2). Finally, note that the command transpose(B)or the operator .' will transpose the matrix, but not complex conjugate the elements.
Read more
  • 0
  • 0
  • 17820

article-image-facelets-templating-jsf-20
Packt
20 Jun 2011
7 min read
Save for later

Facelets Templating in JSF 2.0

Packt
20 Jun 2011
7 min read
One advantage that Facelets has over JSP is its templating mechanism. Templates allow us to specify page layout in one place, then we can have template clients that use the layout defined in the template. Since most web applications have consistent layout across pages, using templates makes our applications much more maintainable, since changes to the layout need to be made in a single place. If at one point we need to change the layout for our pages (add a footer, or move a column from the left side of the page to the right side of the page, for example), we only need to change the template, and the change is reflected in all template clients. NetBeans provides very good support for facelets templating. It provides several templates "out of the box", using common web page layouts. We can then select from one of several predefined templates to use as a base for our template or simply to use it "out of the box". NetBeans gives us the option of using HTML tables or CSS for layout. For most modern web applications, CSS is the preferred approach. For our example we will pick a layout containing a header area, a single left column, and a main area. After clicking on Finish, NetBeans automatically generates our template, along with the necessary CSS files. The automatically generated template looks like this: <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="./resources/css/default.css" rel="stylesheet" type="text/css" /> <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" /> <title>Facelets Template</title> </h:head> <h:body> <div id="top" class="top"> <ui:insert name="top">Top</ui:insert> </div> <div> <div id="left"> <ui:insert name="left">Left</ui:insert> </div> <div id="content" class="left_content"> <ui:insert name="content">Content</ui:insert> </div> </div> </h:body> </html> As we can see, the template doesn't look much different from a regular Facelets file. Adding a Facelets template to our project We can add a Facelets template to our project simply by clicking on File | New File, then selecting the JavaServer Faces category and the Facelets Template file type. Notice that the template uses the following namespace: Java EE 6 Development with NetBeans 7" href="http://java.sun.com" target="_blank">http://java.sun.com/jsf/facelets. This namespace allows us to use the <ui:insert> tag, the contents of this tag will be replaced by the content in a corresponding <ui:define> tag in template clients. Using the template To use our template, we simply need to create a Facelets template client, which can be done by clicking on File | New File, selecting the JavaServer Faces category and the Facelets Template Client file type. After clicking on Next >, we need to enter a file name (or accept the default), and select the template that we will use for our template client. After clicking on Finish, our template client is created. <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="./template.xhtml"> <ui:define name="top"> top </ui:define> <ui:define name="left"> left </ui:define> <ui:define name="content"> content </ui:define> </ui:composition> </body> </html> As we can see, the template client also uses the Java EE 6 Development with NetBeans 7" href="http://java.sun.com" target="_blank">http://java.sun.com/jsf/facelets" namespace. In a template client, the <ui:composition> tag must be the parent tag of any other tag belonging to this namespace. Any markup outside this tag will not be rendered; the template markup will be rendered instead. The <ui:define> tag is used to insert markup into a corresponding <ui:insert> tag in the template. The value of the name attribute in <ui:define> must match the corresponding <ui:insert> tag in the template. After deploying our application, we can see templating in action by pointing the browser to our template client URL. Notice that NetBeans generated a template that allows us to create a fairly elegant page with very little effort on our part. Of course, we should replace the markup in the <ui:define> tags to suit our needs. Here is a modified version of our template, adding markup to be rendered in the corresponding places in the template: <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="./template.xhtml"> <ui:define name="top"> <h2>Welcome to our Site</h2> </ui:define> <ui:define name="left"> <h3>Links</h3> <ul> <li> <h:outputLink value="http://www.packtpub.com"> <h:outputText value="Packt Publishing"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.ensode.net"> <h:outputText value="Ensode.net"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.ensode.com"> <h:outputText value="Ensode Technology, LLC"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.netbeans.org"> <h:outputText value="NetBeans.org"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.glassfish. org"> <h:outputText value="GlassFish.org"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.oracle.com/technetwork/ java/javaee/overview/index.html"> <h:outputText value="Java EE 6"/> </h:outputLink> </li> <li><h:outputLink value="http://www.oracle.com/ technetwork/java/index.html"> <h:outputText value="Java"/> </h:outputLink></li> </ul> </ui:define> <ui:define name="content"> <p> In this main area we would put our main text, images, forms, etc. In this example we will simply use the typical filler text that web designers love to use. </p> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc venenatis, diam nec tempor dapibus, lacus erat vehicula mauris, id lacinia nisi arcu vitae purus. Nam vestibulum nisi non lacus luctus vel ornare nibh pharetra. Aenean non lorem lectus, eu tempus lectus. Cras mattis nibh a mi pharetra ultricies. In consectetur, tellus sit amet pretium facilisis, enim ipsum consectetur magna, a mattis ligula massa vel mi. Maecenas id arcu a erat pellentesque vestibulum at vitae nulla. Nullam eleifend sodales tincidunt. Donec viverra libero non erat porta sit amet convallis enim commodo. Cras eu libero elit, ac aliquam ligula. Quisque a elit nec ligula dapibus porta sit amet a nulla. Nulla vitae molestie ligula. Aliquam interdum, velit at tincidunt ultrices, sapien mauris sodales mi, vel rutrum turpis neque id ligula. Donec dictum condimentum arcu ut convallis. Maecenas blandit, ante eget tempor sollicitudin, ligula eros venenatis justo, sed ullamcorper dui leo id nunc. Suspendisse potenti. Ut vel mauris sem. Duis lacinia eros laoreet diam cursus nec hendrerit tellus pellentesque. </p> </ui:define> </ui:composition> </body> After making the above changes, our template client now renders as follows: As we can see, creating Facelets templates and template clients with NetBeans is a breeze.
Read more
  • 0
  • 0
  • 2709

article-image-python-testing-installing-robot-framework
Packt
20 Jun 2011
2 min read
Save for later

Python Testing: Installing the Robot Framework

Packt
20 Jun 2011
2 min read
How to do it... Be sure to activate your virtualenv sandbox. Install by typing: easy_install robotframework. Using any type of window navigator, go to <virtualenv root>/build/robotframework/doc/quickstart and open quickstart.html with your favorite browser. This is not only a guide but also a runnable test suite. Switch to your virtualenv's build directory for Robot Framework: cd <virtualenv root>/build/robotframework/doc/quickstart. Run the Quick Start manual through pybot to verify installation: pybot quickstart.html. Inspect the generated report.html, log.html, and output.xml files generated by the test run. Install the Robot Framework Selenium library to allow integration with Selenium by first downloading: http://robotframework.org/SeleniumLibrary/. Unpack the tarball. Switch to the directory: cd robotframework-seleniumlibrary-2.5. Install the package: python setup.py install. Switch to the demo directory: cd demo. Start up the demo web app: python rundemo.py demoapp start. Start up the Selenium server: python rundemo.py selenium start. Run the demo tests: pybot login_tests. Shutdown the demo web app: python rundemo.py demoapp stop. Shutdown the Selenium server: python rundemo.py selenium stop. Inspect the generated report.html, log.html, output.xml, and selenium_log.txt files generated by the test run. Summary With this recipe, we have installed the Robot Framework and one third-party library that integrates Robot with Selenium. Further resources on this subject: Inheritance in Python Python Testing: Mock Objects Python: Unit Testing with Doctest Tips & Tricks on MySQL for Python Testing Tools and Techniques in Python
Read more
  • 0
  • 0
  • 7545
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-managing-citrix-policies
Packt
20 Jun 2011
7 min read
Save for later

Managing Citrix policies

Packt
20 Jun 2011
7 min read
Understanding Citrix policies In the Active Directory, a Group Policy contains two categories (also called nodes): Computer Configuration and User Configuration settings. The Computer Configuration node contains policy settings applied to computers, XenApp servers, when we use GPO to manage servers The User Configuration node contains settings applied to users accessing the machine, the XenApp server in our case, regardless of where they log on Citrix policies also have same categories: computer and user. Computer policy settings in Citrix applied to XenApp servers. When the server is rebooted, these policies are applied to the server. User policy settings are used for the duration of the session and are applied to user sessions. Policy settings changes can also take effect when XenApp re-evaluates policies every 90 minutes. Citrix policies are the preferred way to manage session settings or user access and the most effective method of controlling connection, security, and bandwidth settings on XenApp farms. We can create and assign Citrix policies to users, groups, machines, or connection types and each policy can contain one or several settings. Using policies allows us to turn on/off settings like: ICA session settings, like Auto Client Reconnect, Keep Alive, Session Reliability, or Multimedia configuration Licensing configuration, like license server hostname or port Mapping of local drivers, printer, and ports Server settings, like Connections Settings, Reboot Behavior, Memory/CPU Management Shadowing options and permissions Working with Citrix policies A policy is basically a collection of settings or rules. Citrix policies include the user, server, and environment settings that will affect XenApp sessions when the policy is enforced. Policy settings can be enabled, disabled, or not configured. For some policy settings, we can enter a value or we can choose a value from a list when we add the setting to a policy. We can set some policies to one of the following conditions to enable or permit a policy setting: Enabled or Allowed and we can use Disabled or Prohibited to turn off or disallow a policy setting. Also, we can limit configuration of the setting by selecting Use default value. Selecting this option disables configuration of the setting and allows only the setting's default value to be used when the policy is enforced. If we create more than one policy in our environment, we need to prioritize the policies. The best way to track applied settings is to run a Resulting Set of Policies Logging report from the Group Policy Management Console or the Citrix Policy Modeling Wizard. These reports will show all Citrix settings configured via a policy, and which Group Policy Object, including the farm GPO, has actually won the merging calculation. We are going to talk about this in detail later. Usually, Citrix policies will override the same or similar settings applied to the farm, specific XenApp servers, or on the client machine, except for the highest encryption setting and the most restrictive shadowing setting, which always overrides other rules or settings. Best practices for creating Citrix policies The following is a list of recommendations when configuring policy settings: Reduce the amount of policies: Avoid creating multiple policies for different groups of users. Create one policy and apply filters to it. Disable unused policies: Unused policies waste processing resources. If we are using Active Directory Group Policies, we can disable the unused part of the policy (Computer or User part). Assign policies to groups: If we assign policies to groups rather than a user, management is easy and can reduce processing time. Remote Desktop Session Host Configuration settings are similar to Citrix policy settings in a few ways. We need to avoid using Remote Desktop Session Host Configuration to reduce overlapping of settings. We can use Remote Desktop Session Host Configuration (formerly known as Terminal Services Configuration on Windows Server 2003) to configure settings for new connections, modify the settings of existing connections, and delete connections. We can configure settings on a per connection basis or for the server as a whole. Guidelines for working with policies The process for configuring policies is as follows: Create and give a name to the policy: We need to create and provide a name for the new policy. Configure policy settings: We need to choose if we are going to create a User Configuration or Computer Configuration policy and then set the policies. Apply the policy to connections using filters: Using filters we can choose to apply the policy to a specific group of users or computers. Prioritize the policy: In the final (and optional) step, we will assign priority so that policies will override or take precedence over other policies. Working with management consoles In previous versions of Citrix XenApp, Citrix Presentation Server and Citrix MetaFrame policies were stored on the IMA and we managed Citrix policies from the Citrix Management Console. Starting with XenApp 6, policies are stored on the Active Directory and we can manage Citrix policies through the Group Policy Management Console or Local Group Policy Editor in Windows or the Delivery Services Console in XenApp servers. Choosing the right console depends on our network environment and permissions. Using the Group Policy Management Console The Group Policy Management Console (shown in the following screenshot) allows us to view or create Active Directory policies. It also enables us to view the resulting policies applied to users or computers, which is very useful for troubleshooting (more about this is discussed later). If our network environment is based on the Active Directory and we have the appropriate permissions to manage Group Policies (GPO), using the Group Policy Management Console to create policies for our farm is the preferred option. The main reason to use the Group Policy Management Console over the Citrix Delivery Service Console is because Active Directory GPOs take precedence over the farm GPO (also known as IMA GPO). Using the Delivery Services Console The Citrix Delivery Services Console (shown in the following screenshot), formerly known as the Citrix Access Management Console, is a tool that integrates into the Microsoft Management Console (MMC) and enables us to execute management tasks, including creating and viewing Citrix Policies. If we don't have permissions to manage the Active Directory of our company or if our environment doesn't use the Active Directory, we need to use the Citrix Delivery Services Console to create policies for our farm. Policies are stored in a farm GPO in the Citrix data store. In the Citrix Delivery Services Console, we can view the policies configuration by clicking on the Policies node, then select either the Computer or User tabs in the middle pane. When we click on one of these two tabs, three more tabs will be displayed, as shown in the following screenshot. Summary: Shows the settings and filters configured for the selected policy Settings: Shows available and configured settings by category for the selected policy Filters: Shows the available and configured filters applied to the selected policy Using the Local Group Policy Editor If we don't want to use the Citrix Delivery Services Console, we don't have permissions to modify or create a GPO in the Active Directory, or we don't have an Active Directory domain (a NetWare network or workgroup, for example), we have another option. We can create a local GPO using the Local Group Policy Editor (shown in the following screenshot). If we type GPEDIT.MSC, from Start | Run, the Local Group Policy Editor will open. We can modify the local policy of a single server, so it is useful to create or edit a policy in one or maybe a couple of servers, for example, silos or test servers, but it is not useful for medium to large farms. The Local Group Policy will affect everyone who logs onto this machine—including users accessing via Citrix and administrators. We can access policies and their settings in the Local Group Policy Editor, by clicking the Citrix Policies node under User Configuration or the Computer Configuration in the tree pane, located on the left. Active Directory Group policies take precedence over farm GPO; and farm GPO takes precedence over Local Group policies.
Read more
  • 0
  • 0
  • 12943

article-image-how-create-new-jsf-project
Packt
20 Jun 2011
17 min read
Save for later

How to Create a New JSF Project

Packt
20 Jun 2011
17 min read
  Java EE 6 Development with NetBeans 7 Develop professional enterprise Java EE applications quickly and easily with this popular IDE       Introduction to JavaServer faces Before JSF existed, most Java web applications were typically developed using non-standard web application frameworks such as Apache Struts, Tapestry, Spring Web MVC, or many others. These frameworks are built on top of the Servlet and JSP standards, and automate a lot of functionality that needs to be manually coded when using these APIs directly. Having a wide variety of web application frameworks available, often resulted in "analysis paralysis", that is, developers often spend an inordinate amount of time evaluating frameworks for their applications. The introduction of JSF to the Java EE specification resulted in having a standard web application framework available in any Java EE compliant application server. We don't mean to imply that other web application frameworks are obsolete or that they shouldn't be used at all. However, a lot of organizations consider JSF the "safe" choice since it is part of the standard and should be well supported for the foreseeable future. Additionally, NetBeans offers excellent JSF support, making JSF a very attractive choice. Strictly speaking, JSF is not a web application framework per se, but a component framework. In theory, JSF can be used to write applications that are not web-based, however, in practice JSF is almost always used for this purpose. In addition to being the standard Java EE component framework, one benefit of JSF is that it provides good support for tools vendors, allowing tools such as NetBeans to take advantage of the JSF component model with drag and drop support for components.   Developing our first JSF application From an application developer's point of view, a JSF application consists of a series of XHTML pages containing custom JSF tags, one or more JSF managed beans, and an optional configuration file named faces-config.xml. faces-config.xml used to be required in JSF 1.x, however, in JSF 2.0, some conventions were introduced that reduce the need for configuration. Additonally, a lot of JSF configuration can be specified using annotations, reducing, and in some cases, eliminating the need for this XML configuration file. Creating a new JSF project To create a new JSF project, we need to go to File | New Project, select the Java Web project category, and Web Application as the project type. After clicking Next>, we need to enter a project name, and optionally change other information for our project, although NetBeans provides sensible defaults. On the next page in the wizard, we can select the server, Java EE version, and context path of our application. In our example we will simply pick the default values. On the next page of the new project wizard, we can select what frameworks our web application will use. Unsurprisingly, for JSF applications we need to select the JavaServer Faces framework. When clicking on Finish, the wizard generates a skeleton JSF project for us, consisting of a single facelet file called index.xhtml, a web.xml configuration file. web.xml is the standard, optional configuration file needed for Java web applications, this file became optional in version 3.0 of the Servlet API, which was introduced with Java EE 6. In many cases, web.xml is not needed anymore, since most of the configuration options can now be specified via annotations. For JSF applications, however, it is a good idea to add one, since it allows us to specify the JSF project stage. <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> As we can see, NetBeans automatically sets the JSF project stage to Development, setting the project stage to development configures JSF to provide additional debugging help not present in other stages. For example, one common problem when developing a page is that while a page is being developed, validation for one or more of the fields on the page fails, but the developer has not added an <h:message> or <h:messages> tag to the page. When this happens and the form is submitted, the page seems to do nothing, or page navigation doesn't seem to be working. When setting the project stage to Development, these validation errors will automatically be added to the page, without the developer having to explicitly add one of these tags to the page (we should, of course, add the tags before releasing our code to production, since our users will not see the automatically generated validation errors). The following are the valid values for the javax.faces.PROJECT_STAGE context parameter for the faces servlet: Development Production SystemTest UnitTest The Development project stage adds additional debugging information to ease development. The Production project stage focuses on performance. The other two valid values for the project stage (SystemTest and UnitTest), allow us to implement our own custom behavior for these two phases. The javax.faces.application.Application class has a getProjectStage() method that allows us to obtain the current project stage. Based on the value of this method, we can implement the code that will only be executed in the appropriate stage. The following code snippet illustrates this: public void someMethod() { FacesContext facesContext = FacesContext.getCurrentInstance(); Application application = facesContext.getApplication(); ProjectStage projectStage = application.getProjectStage(); if (projectStage.equals(ProjectStage.Development)) { //do development stuff } else if (projectStage.equals(ProjectStage.Production)) { //do production stuff } else if (projectStage.equals(ProjectStage.SystemTest)) { // do system test stuff } else if (projectStage.equals(ProjectStage.UnitTest)) { //do unit test stuff } } As illustrated in the snippet above, we can implement the code to be executed in any valid project stage, based on the return value of the getProjectStage() method of the Application class. When creating a Java Web project using JSF, a facelet is automatically generated. The generated facelet file looks like this: <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <h:head> <title>Facelet Title</title> </h:head> <h:body> Hello from Facelets </h:body> </html> As we can see, a facelet is nothing but an XHTML file using some facelets-specific XML name spaces. In the automatically generated page above, the following namespace definition allows us to use the "h" (for HTML) JSF component library: The above namespace declaration allows us to use JSF specific tags such as <h:head> and <h:body> which are a drop in replacement for the standard HTML/XHTML <head> and <body> tags, respectively. The application generated by the new project wizard is a simple, but complete JSF web application. We can see it in action by right-clicking on our project in the project window and selecting Run. At this point the application server is started (if it wasn't already running), the application is deployed and the default system browser opens, displaying our application's default page. Modifying our page to capture user data The generated application, of course, is nothing but a starting point for us to create a new application. We will now modify the generated index.xhtml file to collect some data from the user. The first thing we need to do is add an <h:form> tag to our page. The <h:form> tag is equivalent to the <form> tag in standard HTML pages. After typing the first few characters of the <h:form> tag into the page, and hitting Ctrl+Space, we can take advantage of NetBeans' excellent code completion. After adding the <h:form> tag and a number of additional JSF tags, our page now looks like this: <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <h:head> <title>Registration</title> <h:outputStylesheet library="css" name="styles.css"/> </h:head> <h:body> <h3>Registration Page</h3> <h:form> <h:panelGrid columns="3" columnClasses="rightalign,leftalign,leftalign"> <h:outputLabel value="Salutation: " for="salutation"/> <h:selectOneMenu id="salutation" label="Salutation" value="#{registrationBean.salutation}" > <f:selectItem itemLabel="" itemValue=""/> <f:selectItem itemLabel="Mr." itemValue="MR"/> <f:selectItem itemLabel="Mrs." itemValue="MRS"/> <f:selectItem itemLabel="Miss" itemValue="MISS"/> <f:selectItem itemLabel="Ms" itemValue="MS"/> <f:selectItem itemLabel="Dr." itemValue="DR"/> </h:selectOneMenu> <h:message for="salutation"/> <h:outputLabel value="First Name:" for="firstName"/> <h:inputText id="firstName" label="First Name" required="true" value="#{registrationBean.firstName}" /> <h:message for="firstName" /> <h:outputLabel value="Last Name:" for="lastName"/> <h:inputText id="lastName" label="Last Name" required="true" value="#{registrationBean.lastName}" /> <h:message for="lastName" /> <h:outputLabel for="age" value="Age:"/> <h:inputText id="age" label="Age" size="2" value="#{registrationBean.age}"/> <h:message for="age"/> <h:outputLabel value="Email Address:" for="email"/> <h:inputText id="email" label="Email Address" required="true" value="#{registrationBean.email}"> </h:inputText> <h:message for="email" /> <h:panelGroup/> <h:commandButton id="register" value="Register" action="confirmation" /> </h:panelGrid> </h:form> </h:body> </html> The following screenshot illustrates how our page will be rendered at runtime: All JSF input fields must be inside an <h:form> tag. The <h:panelGrid> helps us to easily lay out JSF tags on our page. It can be thought of as a grid where other JSF tags will be placed. The columns attribute of the <h:panelGrid> tag indicates how many columns the grid will have, each JSF component inside the <h:panelGrid> component will be placed in an individual cell of the grid. When the number of components matching the value of the columns attribute (three in our example) has been placed inside <h:panelGrid>, a new row is automatically started. The following table illustrates how tags will be laid out inside an <h:panelGrid> tag: Each row in our <h:panelGrid> consists of an <h:outputLabel> tag, an input field, and an <h:message> tag. The columnClasses attribute of <h:panelGrid> allows us to assign CSS styles to each column inside the panel grid, its value attribute must consist of a comma separated list of CSS styles (defined in a CSS stylesheet). The first style will be applied to the first column, the second style will be applied to the second column, the third style will be applied to the third column, so on and so forth. Had our panel grid had more than three columns, then the fourth column would have been styled using the first style in the columnClasses attribute, the fifth column would have been styled using the second style in the columnClasses attribute, so on and so forth. If we wish to style rows in an <h:panelGrid>, we can do so with its rowClasses attribute, which works the same way that the columnClasses works for columns. Notice the <h:outputStylesheet> tag inside <h:head> near the top of the page, this is a new tag that was introduced in JSF 2.0. One new feature that JSF 2.0 brings to the table is standard resource directories. Resources such as CSS stylesheets, JavaScript files, images, and so on, can be placed under a top level directory named resources, and JSF tags will have access to those resources automatically. In our NetBeans project, we need to place the resources directory under the Web Pages folder. We then need to create a subdirectory to hold our CSS stylesheet (by convention, this directory should be named css), then we place our CSS stylesheet(s) on this subdirectory. The value of the library attribute in <h:outputStylesheet> must match the directory where our CSS file is located, and the value of its name attribute must match the CSS file name. In addition to CSS files, we should place any JavaScript files in a subdirectory called javascript under the resources directory. The file can then be accessed by the <h:outputScript> tag using "javascript" as the value of its library attribute and the file name as the value of its name attribute. Similarly, images should be placed in a directory called images under the resources directory. These images can then be accessed by the JSF <h:graphicImage> tag, where the value of its library attribute would be "images" and the value of its name attribute would be the corresponding file name. Now that we have discussed how to lay out elements on the page and how to access resources, let's focus our attention on the input and output elements on the page. The <h:outputLabel> tag generates a label for an input field in the form, the value of its for attribute must match the value of the id attribute of the corresponding input field. <h:message> generates an error message for an input field, the value of its for field must match the value of the id attribute for the corresponding input field. The first row in our grid contains an <h:selectOneMenu>. This tag generates an HTML <select> tag on the rendered page. Every JSF tag has an id attribute, the value for this attribute must be a string containing a unique identifier for the tag. If we don't specify a value for this attribute, one will be generated automatically. It is a good idea to explicitly state the ID of every component, since this ID is used in runtime error messages. Affected components are a lot easier to identify if we explicitly set their IDs. When using <h:label> tags to generate labels for input fields, or when using <h:message> tags to generate validation errors, we need to explicitly set the value of the id tag, since we need to specify it as the value of the for attribute of the corresponding <h:label> and <h:message> tags. Every JSF input tag has a label attribute. This attribute is used to generate validation error messages on the rendered page. If we don't specify a value for the label attribute, then the field will be identified in the error message by its ID. Each JSF input field has a value attribute, in the case of <h:selectOneMenu>, this attribute indicates which of the options in the rendered <select> tag will be selected. The value of this attribute must match the value of the itemValue attribute of one of the nested <f:selectItem> tags. The value of this attribute is usually a value binding expression, that means that the value is read at runtime from a JSF managed bean. In our example, the value binding expression #{registrationBean.salutation} is used. What will happen is at runtime JSF will look for a managed bean named registrationBean, and look for an attribute named salutation on this bean, the getter method for this attribute will be invoked, and its return value will be used to determine the selected value of the rendered HTML <select> tag. Nested inside the <h:selectOneMenu> there are a number of <f:selectItem> tags. These tags generate HTML <option> tags inside the HTML <select> tag generated by <h:selectOneMenu>. The value of the itemLabel attribute is the value that the user will see while the value of the itemValue attribute will be the value that will be sent to the server when the form is submitted. All other rows in our grid contain <h:inputText> tags, this tag generates an HTML input field of type text, which accept a single line of typed text as input. We explicitly set the id attribute of all of our <h:inputText> fields, this allows us to refer to them from the corresponding <h:outputLabel> and <h:message> fields. We also set the label attribute for all of our <h:inputText> tags, this results in more user-friendly error messages. Some of our <h:inputText> fields require a value, these fields have their required attribute set to true, each JSF input field has a required attribute, if we need to require the user to enter a value for this attribute, then we need to set this attribute to true. This attribute is optional, if we don't explicitly set a value for it, then it defaults to false. In the last row of our grid, we added an empty <h:panelGroup> tag. The purpose of this tag is to allow adding several tags into a single cell of an <h:panelGrid>. Any tags placed inside this tag are placed inside the same cell of the grid where <h:panelGrid> is placed. In this particular case, all we want to do is to have an "empty" cell in the grid so that the next tag, <h:commandButton>, is aligned with the input fields in the rendered page. <h:commandButton> is used to submit a form to the server. The value of its value attribute is used to generate the text of the rendered button. The value of its action attribute is used to determine what page to display after the button is pressed. In our example, we are using static navigation. When using JSF static navigation, the value of the action attribute of a command button is hard-coded in the markup. When using static navigation, the value of the action attribute of <h:commandButton> corresponds to the name of the page we want to navigate to, minus its .xhtml extension. In our example, when the user clicks on the button, we want to navigate to a file named confirmation.xhtml, therefore we used a value of "confirmation" for its action attribute. An alternative to static navigation is dynamic navigation. When using dynamic navigation, the value of the action attribute of the command button is a value binding expression resolving to a method returning a String in a managed bean. The method may then return different values based on certain conditions. Navigation would then proceed to a different page depending on the value of the method. As long as it returns a String, the managed bean method executed when using dynamic navigation can contain any logic inside it, and is frequently used to save data in a managed bean into a database. When using dynamic navigation, the return value of the method executed when clicking the button must match the name of the page we want to navigate to (again, minus the file extension). In earlier versions of JSF, it was necessary to specify navigation rules in facesconfig.xml, with the introduction of the conventions introduced in the previous paragraphs, this is no longer necessary.  
Read more
  • 0
  • 0
  • 14790

article-image-ejb-31-controlling-security-programmatically-using-jaas
Packt
17 Jun 2011
5 min read
Save for later

EJB 3.1: Controlling Security Programmatically Using JAAS

Packt
17 Jun 2011
5 min read
  EJB 3.1 Cookbook Build real world EJB solutions with a collection of simple but incredibly effective recipes The reader is advised to refer the initial two recipies from the previous article on the process of handling security using annotations. Getting ready Programmatic security is affected by adding code within methods to determine who the caller is and then allowing certain actions to be performed based on their capabilities. There are two EJBContext interface methods available to support this type of security: getCallerPrincipal and isCallerInRole. The SessionContext object implements the EJBContext interface. The SessionContext's getCallerPrincipal method returns a Principal object which can be used to get the name or other attributes of the user. The isCallerInRole method takes a string representing a role and returns a Boolean value indicating whether the caller of the method is a member of the role or not. The steps for controlling security programmatically involve: Injecting a SessionContext instance Using either of the above two methods to effect security How to do it... To demonstrate these two methods we will modify the SecurityServlet to use the VoucherManager's approve method and then augment the approve method with code using these methods. First modify the SecurityServlet try block to use the following code. We create a voucher as usual and then follow with a call to the submit and approve methods. out.println("<html>"); out.println("<head>"); out.println("<title>Servlet SecurityServlet</title>"); out.println("</head>"); out.println("<body>"); voucherManager.createVoucher("Susan Billings", "SanFrancisco", BigDecimal.valueOf(2150.75)); voucherManager.submit(); boolean voucherApproved = voucherManager.approve(); if(voucherApproved) { out.println("<h3>Voucher was approved</h3>"); } else { out.println("<h3>Voucher was not approved</h3>"); } out.println("<h3>Voucher name: " + voucherManager.getName() + "</h3>"); out.println("</body>"); out.println("</html>"); Next, modify the VoucherManager EJB by injecting a SessionContext object using the @Resource annotation. public class VoucherManager { ... @Resource private SessionContext sessionContext; Let's look at the getCallerPrincipal method first. This method returns a Principal object (java.security.Principal) which has only one method of immediate interest: getName. This method returns the name of the principal. Modify the approve method so it uses the SessionContext object to get the Principal and then determines if the name of the principal is "mary" or not. If it is, then approve the voucher. public boolean approve() { Principal principal = sessionContext.getCallerPrincipal(); System.out.println("Principal: " + principal.getName()); if("mary".equals(principal.getName())) { voucher.setApproved(true); System.out.println("approve method returned true"); return true; } else { System.out.println("approve method returned false"); return false; } } Execute the SecurityApplication using "mary" as the user. The application should approve the voucher with the output as shown in the following screenshot: Execute the application again with a user of "sally". This execution will result in an exception. INFO: Access exception The getCallerPrincipal method simply returns the principal. This frequently results in the need to explicitly include the name of a user in code. The hard coding of user names is not recommended. Checking against each individual user can be time consuming. It is more efficient to check to see if a user is in a role. The isCallerInRole method allows us to determine whether the user is in a particular role or not. It returns a Boolean value indicating whether the user is in the role specified by the method's string argument. Rewrite the approve method to call the isCallerInRole method and pass the string "manager" to it. If the return value returns true, approve the voucher. public boolean approve() { if(sessionContext.isCallerInRole("manager")) { voucher.setApproved(true); System.out.println("approve method returned true"); return true; } else { System.out.println("approve method returned false"); return false; } } Execute the application using both "mary" and "sally". The results of the application should be the same as the previous example where the getCallerPrincipal method was used. How it works... The SessionContext class was used to obtain either a Principal object or to determine whether a user was in a particular role or not. This required the injection of a SessionContext instance and adding code to determine if the user was permitted to perform certain actions. This approach resulted in more code than the declarative approach. However, it provided more flexibility in controlling access to the application. These techniques provided the developer with choices as to how to best meet the needs of the application. There's more... It is possible to take different actions depending on the user's role using the isCallerInRole method. Let's assume we are using programmatic security with multiple roles. @DeclareRoles ({"employee", "manager","auditor"}) We can use a validateAllowance method to accept a travel allowance amount and determine whether it is appropriate based on the role of the user. public boolean validateAllowance(BigDecimal allowance) { if(sessionContext.isCallerInRole("manager")) { if(allowance.compareTo(BigDecimal.valueOf(2500)) <= 0) { return true; } else { return false; } } else if(sessionContext.isCallerInRole("employee")) { if(allowance.compareTo(BigDecimal.valueOf(1500)) <= 0) { return true; } else { return false; } } else if(sessionContext.isCallerInRole("auditor")) { if(allowance.compareTo(BigDecimal.valueOf(1000)) <= 0) { return true; } else { return false; } } else { return false; } } The compareTo method compares two BigDecimal values and returns one of three values: -1 – If the first number is less than the second number 0 – If the first and second numbers are equal 1 – If the first number is greater than the second number The valueOf static method converts a number to a BigDecimal value. The value is then compared to allowance. Summary This article covered programmatic EJB security based upon the Java Authentication and Authorization Service (JAAS) API. Further resources on this subject: EJB 3.1: Introduction to Interceptors [Article] EJB 3.1: Working with Interceptors [Article] Hands-on Tutorial on EJB 3.1 Security [Article] EJB 3 Entities [Article] Developing an EJB 3.0 entity in WebLogic Server [Article] Building an EJB 3.0 Persistence Model with Oracle JDeveloper [Article] NetBeans IDE 7: Building an EJB Application [Article]
Read more
  • 0
  • 0
  • 3223

article-image-mastering-blender-25-basics
Packt
17 Jun 2011
13 min read
Save for later

Mastering the Blender 2.5 Basics

Packt
17 Jun 2011
13 min read
Blender 2.5 Character Animation Cookbook 50 great recipes for giving soul to your characters by building high-quality rigs Adjusting and tracking the timing Timing, by itself, is a subject that goes well beyond the scope of a simple recipe. It is, in fact, the main subject of a number of animation-related books. Strictly speaking, Timing in animation is how long it takes (in frames or seconds) between two Extreme poses. You can have your character in great poses, but if the timing between them is not right, your shot may be ruined. Maybe it is a difficult thing to master because there are no definite rules for it: everyone is born with a particular sense of timing. Despite that, it's enormously important to look at video and real life references to understand the timing for different actions. Imagine a tennis ball falling to the ground and bouncing. Think of the time between its first and second contact with the ground. Now replace it with a bowling ball and think of the time required for this bounce. You know, from your life experience, that the tennis ball bounces slower than the bowling ball. The timing between these two balls is different. The timing here (along with spacing, subject of the next recipe) is the main factor that makes us perceive the different nature and weight of each ball. The "rules" of timing can also be broken for comedic effect: something that purposely moves faster or slower than usual may get a laugh from the audience. We're going to see how different timings can change how we perceive a shot with the same poses. How to do it... Open the file 007-Timing.blend (Go to Support to get the code). It has our character Otto with three poses, making him look from one side to the other: (Move the mouse over the image to enlarge it.) Press Alt + A to play the animation. You may think the timing is acceptable for this head turn, but this method of checking the timing is not ideal. When you tell Blender to play the animation through Alt + A, you're relying in your computer's power to process all the information of your scene in real time. You'd probably end up seeing something slower than what you'll actually get after rendering the frames. When playing the animation inside the 3D view, you can see the actual playback frame rate on the top left corner of the window. If it's slower than the scene frame rate (in this case, 24 fps), it means that the rendered animation will be faster than what you're seeing. When adjusting the timing, we must be sure of the exact results of every keyframe set. Even a one-frame change can make a huge impact on the scene, but rendering a complex scene just to test the timing is out of the question, because it just takes too long to see the results. We need a quick way to check the timing precisely. Fortunately, Blender allows us to make a quick "render" of our 3D view, with only the OpenGL information. This is also called "playblast", and is exactly what we need. Take a look at the header of our 3D view and find the button with a clapperboard icon, as seen in the next screenshot: OpenGL stands for Open Graphics Library, and is a free cross-platform specification and API for writing 2D and 3D computer graphics. Not only are the objects inside Blender's 3D view made using this library, but also the user interface with all its buttons, icons, and text are drawn on the screen with OpenGL. From OpenGL version 2.0 it's possible to use GLSL, a high level shading language heavily used to create games and supported by Blender to enhance the way objects are displayed on the screen in real time. From Blender 2.5, GLSL is the default real time rendering method when the user selects the Textured viewport shading mode, but that option has to be supported by your graphics card. Click on that clapperboard button, and the active 3D view will be used for a quick OpenGL render of your scene. This preview rendering shares the Render panel settings in the Properties window, so the picture size, frame rate, output folder, file format, duration, and stamp will be the same. If you can't see the button in your 3D View header (it is available only in the header) it may be an issue of lack of space; you can click with the middle button (or the scroll wheel) of your mouse over the header and drag it to the sides to find it. After the OpenGL rendering is complete, press Esc to go back to your scene and press Ctrl + F11 to preview the animation with the correct frame rate to check the timing. Starting with the Blender 2.5 series, there's no built-in player in the program, so you have to specify one in the User Preferences window (Ctrl + Alt + U), on the File tab. This player can even be a previous version of Blender in the 2.4 series or any player you wish, such as DJV or Mplayer. With any of these options you must tell Blender the file path where the player is installed. Now that you can watch the animation with the correct frame rate, you'll notice that the head turns quite fast, since it only takes five frames to complete. This fast timing makes our action seem to happen after the character listens to an abrupt and loud noise coming from his left, so he has to turn his head quickly and look to see what happened. Let's suppose our character is watching a tennis match in Wimbledon, and his seat is in line with the net, at the middle of the court (yep, lucky guy). Watching the ball from the serve until it reaches the other side of the court should take longer than what we have just set up, so let's adjust our keyframes now. In the DopeSheet window, leave the first keyframe at frame 1. Select the last column of keyframes by holding Alt and right-clicking on any keyframe set at frame 5. Move (G) the column to frame 15 (hold Ctrl for snapping to the frames), so our action takes three times longer than the original. Another way of selecting a column of keyframes is through the DopeSheet Summary option on the window header. It creates an extra line above all channels. If you select the diamond on this line, all keyframes on that column will be selected. You can even collapse all channels and use only the DopeSheet Summary to move the keys along the timeline to make timing adjustments easily. Now, the Breakdown, or intermediate position between two Extreme poses. It doesn't have to be at the exact middle of our action. Actually, it's good to avoid symmetry not only in our models and poses, but in our motions too. Move (G) the Breakdown to frame 6, and you'll have something similar to the next screenshot: Now you can make another OpenGL render to preview the action with the new timing. You can choose to disable the layer where the armature is located, the second, by holding Shift and clicking over it, so you don't have the bones on the preview. Of course this is far from a finished shot: it's a good idea to make the character blink during the head turn, add some moving holds, animate the eyeballs, add some facial expressions, and so on. This rough example is only to show how drastically the timing can change the feel of an action. If you set the timing between the positions even higher, our character may seem like he's looking at something slower (someone on a bike, maybe?) moving in front of him. How it works... Along with good posing, the timing is crucial to make our actions vivid, believable, and with a sense of weight. The timing also is very important to help your audience understand what is happening in the scene, so it must be carefully adjusted. To have a precise view of how the timing is working in an action within Blender, it's best to use the OpenGL preview mode, since the usual Alt + A shortcut to preview the animation inside the 3D View can be misleading. There's more... Depending on the complexity of your scene, you can achieve the correct frame rate within the 3D view with Alt + A. You can disable the visibility of irrelevant objects or some modifiers to help speed up this real time processing, like lowering (or disabling) the Subdivision Surface modifier and hiding the armature and background layers. Spacing: favoring and easing poses The previous recipe shows us how to adjust the timing of our character's actions, which is something extremely important to make our audience not only understand what is happening on the screen, but also know the weight and forces involved in the motion. Since timing is closely related to spacing, there is often confusion between the two concepts. Timing in animation is the number of frames between two Extreme poses. Spacing is how the animated subject moves and shows variations of speed along these frames. Actions with the same timing and different spacing are perceived differently by the audience, and these principles combined are responsible for the feeling of weight of our actions. We're going to see how the spacing works and how we can create eases and favoring poses to enhance movements. How to do it... Open the file 007-Spacing.blend. It has our character Otto turning his head from right to left, just like in the timing recipe. We don't have a Breakdown position defined yet, and this action has a timing set to 15 frames. First, let's understand the most elementary type of spacing: linear, or even spacing. This is when the calculated intermediate positions between two keyframes have the same distance among them, without any kind of acceleration. This isn't something we're used to seeing in nature, thus it's not the default interpolation mode in Blender. To use it, select the desired keyframes in a DopeSheet or a Graph Editor window, press Shift + T, and choose the Linear interpolation mode. The curves between the keyframes will turn into straight lines, as you can see in the next screenshot showing the channels for the Head bone. If you preview the animation with Alt + A, you'll see that the movement is very mechanical and unappealing, something we don't see in nature. That's why this interpolation mode isn't the default one. Movements in nature all have some variation in speed, going from a resting state, accelerating to a peak velocity, then slowing down until another resting state. These variations of speed are called eases, and are represented with curved lines on the Graph Editor. When there is an increase in speed we have an ease out. When the movement slows down to a resting state, we have an ease in. This variation in speed is the default interpolation method in Blender, and you can enable it by selecting the desired keyframes in a DopeSheet or Graph Editor window, press Shift + T and select the Bezier interpolation mode. The next screenshot shows the same keyframes with easing: When we adjust the curve handles on the Graph Editor, we're actually defining the eases of that movement. When you insert keyframes in Blender, it automatically creates both eases: out and in (with same speeds). Since not all movements have the same variation of speed at their beginning and end, it's a good idea to change the handles on the Graph Editor. This difference of speed between the start and end keyframes is called favoring. When the Spacing between two poses have different eases, we say the movement "favors" one of the poses, notably the one which has the bigger ease. In the next screenshot, the curves for the Head bone were adjusted so the movement favors the second pose. Note that there is a softer curve near the second pose, while the first has sharper lines near it. This will make the head leave the first pose very quick and slowly settle into the second one. In order to create sharp angles with the handles in the Graph Editor window, you need to select the desired curve channels, press V and choose the Free handle type. Open the video file 007-Spacing.mov in a video player, which enables navigating through the frames (such as DJV), to watch the three actions at the same time. Although the timing of the action is unchanged, you can clearly notice how the interpolation changes the motion. In the next screenshot, you can see that at frame 8, the Favoring version has the face closer to the second pose: Now that you understand what spacing is, know the difference between the interpolation types, and can use eases to favor poses, let's add a Breakdown position. This action is pretty boring, since the head turn happens without any arcs. It's a good idea to tilt the head down a little during the turn, making an imaginary arc with the eyes. Especially during quick head turns, it's a good idea to make your character blink during the turn. Unless your character is following something with the eyes—such as in a tennis court in our example—a quick blink is useful to make a "scene cut" in our minds from one subject to the other. On the DopeSheet window, in the Action Editor, select the Favoring action. Go to frame 6, where the character looks to the camera. Select and rotate (R) the Head and Neck bones to front on their local X axis, as seen in the next screenshot, and insert a keyframe (I) for its rotation: Since Blender automatically creates symmetrical eases on each new keyframe, it's time to adjust our spacing for the Head and Neck bones on the Graph Editor window. If you play the animation with Alt + A, you'll notice that the motion goes very weird because of that automatic ease. The F-Curves on the X axis of each bone for this motion are not soft. Ideally, since this is a Breakdown position, the curves between it and its surrounding Extreme poses should be smooth, regardless of the favoring. Select the curve handles on frames 1 and 6, and move (G) them in order to soften the curve peak in that Breakdown position. The next screenshot shows the curves before and after editing. Notice how the peak curves at the Breakdown in the middle get smoother after editing: Now the action looks more natural, with a nice Breakdown and favoring created using the F-Curves. The file 007-Spacing-complete.blend has this finished example for your reference, in which you can play the animation with Alt + A to see the results. How it works... By understanding the principle of Spacing, you can create eases and favoring in order to create snappy and interesting motions. Just like visible shapes, the pace of motion in nature is often asymmetrical. To make your motions not only more interesting but also more believable and with accents to reinforce the purpose behind the movements, you should master Spacing. Be sure to check out the interpolation curves in your animations: interesting movements normally have different eases between two Extreme positions.
Read more
  • 0
  • 0
  • 2556
article-image-interacting-gnu-octave-variables
Packt
17 Jun 2011
8 min read
Save for later

Interacting with GNU Octave: Variables

Packt
17 Jun 2011
8 min read
GNU Octave Beginner's Guide Become a proficient Octave user by learning this high-level scientific numerical tool from the ground up          In the following, we shall see how to instantiate simple variables. By simple variables, we mean scalars, vectors, and matrices. First, a scalar variable with name a is assigned the value 1 by the command: octave:1> a=1 a = 1 That is, you write the variable name, in this case a, and then you assign a value to the variable using the equal sign. Note that in Octave, variables are not instantiated with a type specifier as it is known from C and other lower-level languages. Octave interprets a number as a real number unless you explicitly tell it otherwise. In Octave, a real number is a double-precision, floating-point number,which means that the number is accurate within the first 15 digits. Single precision is accurate within the first 6 digits. You can display the value of a variable simply by typing the variable name: octave:2>a a = 1 Let us move on and instantiate an array of numbers: octave:3 > b = [1 2 3] b = 1 2 3 Octave interprets this as the row vector: rather than a simple one-dimensional array. The elements (or the entries) in a row vector can also be separated by commas, so the command above could have been: octave:3> b = [1, 2, 3] b = 1 2 3 To instantiate a column vector: you can use: octave:4 > c = [1;2;3] c = 1 2 3 Notice how each row is separated by a semicolon. We now move on and instantiate a matrix with two rows and three columns (a 2 x 3 matrix): using the following command: octave:5 > A = [1 2 3; 4 5 6] A = 1 2 3 4 5 6 Notice that I use uppercase letters for matrix variables and lowercase letters for scalars and vectors, but this is, of course, a matter of preference, and Octave has no guidelines in this respect. It is important to note, however, that in Octave there is a difference between upper and lowercase letters. If we had used a lowercase a in Command 5 above, Octave would have overwritten the already existing variable instantiated in Command 1. Whenever you assign a new value to an existing variable, the old value is no longer accessible, so be very careful whenever reassigning new values to variables. Variable names can be composed of characters, underscores, and numbers. A variable name cannot begin with a number. For example, a_1 is accepted as a valid variable name, but 1_a is not. In this article, we shall use the more general term array when referring to a vector or a matrix variable. Accessing and changing array elements To access the second element in the row vector b, we use parenthesis: octave:6 > b(2) ans = 2 That is, the array indices start from 1. This is an abbreviation for "answer" and is a variable in itself with a value, which is 2 in the above example. For the matrix variable A, we use, for example: octave:7> A(2,3) ans = 6 to access the element in the second row and the third column. You can access entire rows and columns by using a colon: octave:8> A(:,2) ans = 2 5 octave:9 > A(1,:) ans = 1 2 3 Now that we know how to access the elements in vectors and matrices, we can change the values of these elements as well. To try to set the element A(2,3)to -10.1: octave:10 > A(2,3) = -10.1 A = 1.0000 2.0000 3.0000 4.0000 5.0000 -10.1000 Since one of the elements in A is now a non-integer number, all elements are shown in floating point format. The number of displayed digits can change depending on the default value, but for Octave's interpreter there is no difference—it always uses double precision for all calculations unless you explicitly tell it not to. You can change the displayed format using format short or format long. The default is format short. It is also possible to change the values of all the elements in an entire row by using the colon operator. For example, to substitute the second row in the matrix A with the vector b (from Command 3 above), we use: octave:11 > A(2,:) = b A = 1 2 3 1 2 3 This substitution is valid because the vector b has the same number of elements as the rows in A. Let us try to mess things up on purpose and replace the second column in A with b: octave:12 > A(:,2) = b error: A(I,J,...) = X: dimension mismatch Here Octave prints an error message telling us that the dimensions do not match because we wanted to substitute three numbers into an array with just two elements. Furthermore, b is a row vector, and we cannot replace a column with a row. Always read the error messages that Octave prints out. Usually they are very helpful. There is an exception to the dimension mismatch shown above. You can always replace elements, entire rows, and columns with a scalar like this: octave:13> A(:,2) = 42 A = 1 42 3 1 42 3 More examples It is possible to delete elements, entire rows, and columns, extend existing arrays, and much more. Time for action – manipulating arrays To delete the second column in A, we use: octave:14> A(:,2) = [] A = 1 3 1 3 We can extend an existing array, for example: octave:15 > b = [b 4 5] b = 1 2 3 4 5 Finally, try the following commands: octave:16> d = [2 4 6 8 10 12 14 16 18 20] d = 2 4 6 8 10 12 14 16 18 20 octave:17> d(1:2:9) ans = 2 6 10 14 18 octave:18> d(3:3:12) = -1 d = 2 4 -1 8 10 -1 14 16 -1 20 0 -1 What just happened? In Command 14, Octave interprets [] as an empty column vector and column 2 in A is then deleted in the command. Instead of deleting a column, we could have deleted a row, for example as an empty column vector and column 2 in A is then deleted in the command. octave:14> A(2,:)=[] On the right-hand side of the equal sign in Command 15, we have constructed a new vector given by [b 4 5], that is, if we write out b, we get [1 2 3 4 5] since b=[1 2 3]. Because of the equal sign, we assign the variable b to this vector and delete the existing value of b. Of course, we cannot extend b using b=[b; 4; 5] since this attempts to augment a column vector onto a row vector. Octave first evaluates the right-hand side of the equal sign and then assigns that result to the variable on the left-hand side. The right-hand side is named an expression. In Command 16, we instantiated a row vector d, and in Command 17, we accessed the elements with indices 1,3,5,7, and 9, that is, every second element starting from 1. Command 18 could have made you a bit concerned! d is a row vector with 10 elements, but the command instructs Octave to enter the value -1 into elements 3, 6, 9 and 12, that is, into an element that does not exist. In such cases, Octave automatically extends the vector (or array in general) and sets the value of the added elements to zero unless you instruct it to set a specific value. In Command 18, we only instructed Octave to set element 12 to -1, and the value of element 11 will therefore be given the default value 0 as seen from the output. In low-level programming languages, accessing non-existing or non-allocated array elements may result in a program crash the first time it is running2. This will be the best case scenario. In a worse scenario, the program will work for years, but then crash all of a sudden, which is rather unfortunate if it controls a nuclear power plant or a space shuttle. As you can see, Octave is designed to work in a vectorized manner. It is therefore often referred to as a vectorized programming language. Complex variables Octave also supports calculations with complex numbers. As you may recall, a complex number can be written as z = a + bi, where a is the real part, b is the imaginary part, and i is the imaginary unit defined from i2 = –49491. To instantiate a complex variable, say z = 1 + 2i, you can type: octave:19> z = 1 + 2I z = 1 + 2i When Octave starts, the variables i, j, I, and J are all imaginary units, so you can use either one of them. I prefer using I for the imaginary unit, since i and j are often used as indices and J is not usually used to symbolize i. To retrieve the real and imaginary parts of a complex number, you use: octave:20> real(z) ans = 1 octave:21>imag(z) ans = 2 You can also instantiate complex vectors and matrices, for example: octave:22> Z = [1 -2.3I; 4I 5+6.7I] Z = 1.0000 + 0.0000i 0.0000 - 2.3000i 0.0000 + 4.0000i 5.0000 + 6.7000i Be careful! If an array element has non-zero real and imaginary parts, do not leave any blanks (space characters) between the two parts. For example, had we used Z=[1 -2.3I; 4I 5 + 6.7I] in Command 22, the last element would be interpreted as two separate elements (5 and 6.7i). This would lead to dimension mismatch. The elements in complex arrays can be accessed in the same way as we have done for arrays composed of real numbers. You can use real(Z) and imag(Z) to print the real and imaginary parts of the complex array Z. (Try it out!)
Read more
  • 0
  • 0
  • 6095

article-image-designing-xenapp-6-farm
Packt
16 Jun 2011
13 min read
Save for later

Designing a XenApp 6 Farm

Packt
16 Jun 2011
13 min read
XenApp 6 Farm terminology and concepts Now is the moment to define the terminology we are going to use. If you are new in the Citrix world, please pay attention to this section. Multi-user environment is when applications are published on servers running remote desktop services and/or XenApp accessed by multiple users simultaneously. XenApp server is the main software component of the Citrix application delivery infrastructure. The objective of XenApp servers is to deliver applications to user devices. XenApp application servers are the farm servers that host published applications. XenApp infrastructure servers are the farm servers that host services such as a license server or web interface. Usually, they do not host published applications. Remote desktop services (RDS), formerly known as Terminal Services, is one of the components of Microsoft Windows that allows a user to access applications and data on a remote computer over a network. We need to install this component (and appropriate licenses) to setup and run XenApp servers. XenApp extends the functionality of Microsoft Remote Desktop Services, adding flexibility, manageability, security, and performance to RDS. Applications can be made available by installing in the server or streaming to the client. XenApp 6 supports only Windows 32-bit or Windows 64-bit applications. Running 16-bit applications is NOT supported. XenApp offers three methods for delivering applications to user devices, servers, and virtual desktops: Server-side application virtualization: Applications run on the XenApp servers. XenApp shows the application interface on the user device or client, and transmits user actions from the device, such as keystrokes and mouse actions, back to the application. Client-side application virtualization: XenApp streams applications on demand to the user device from the XenApp farm and runs the application on the user device. VM hosted application virtualization: Challenging applications or those requiring specific operating systems run inside a desktop on the XenApp server. XenApp shows the application interface on the user device or client, and transmits user actions from the device, such as keystrokes and mouse actions, back to the application. XenApp server farm is a logical collection or group of XenApp servers that can be managed as a single entity. Usually, Citrix define three types of farms: Design validation farm: Design validation farm is set up in a laboratory, typically as the design or blueprint for the production farm. Usually, the preferred method to build a design validation farm today is using virtual machines. Pilot farm: Pilot farm is a preproduction farm used to test a farm design and applications before deploying the farm across the company. The pilot must include users from the entire organization and role. These users should access the farm for their everyday needs. Production farm: Production farm is in regular use and accessed by all users in the organization. Farm Architecture defines the plan for the design of the server farm and zones based on current requirements and future expansion plans. Farm architecture requires a strong understanding of the network topology, scalability, failover, and geographic location of the sites and users in the company. Zones: Zones are used to control the aggregation and replication of data in the farm. A farm should be divided into zones based upon the network topology, where major geographic regions are assigned to separate zones. Each zone elects a data collector, which aggregates dynamic data from the servers in its zone and replicates the data to the data collectors in the other zones. Worker group: A worker group is a new feature introduced on XenApp 6. It is a collection of XenApp servers in the same farm. Worker groups allow a set of similar servers to be grouped together and managed as one. Worker groups are closely related to the concept of application silos (silos usually are servers dedicated to run critical or resource-intensive applications). All servers in the worker group share the same list of published applications and identical XenApp server settings. Data collector: A collector stores information about servers and published applications inside a group and acts as a gateway between data collectors in other groups. In large XenApp server farm environments, it is a good idea to have a dedicated server and restrict it from delivering applications. A dedicated data collector improves load balancing decisions and reduces session logon time. User device is where the client software is installed to access data anywhere: Citrix Receiver: Citrix Receiver is the first universal client for IT service delivery. Users can use any device—it runs on smartphones, laptops, desktops, and netbooks (PC or Mac). With Citrix Receiver installed on a device, IT can deliver applications and desktops as an on-demand service with no need to manage, own, or care about the physical device or its location. Citrix Receiver is a lightweight software client with an extensible browser-like "plugin" architecture that communicates with head-end infrastructure in the Citrix Delivery Center product family including XenApp and XenDesktop. Citrix Receiver was formerly known as Citrix ICA Client. Citrix Dazzle and the self-service storefront: Citrix Dazzle, the self-service enterprise application storefront, offers a personal and easy-to-use interface for subscribing to applications. Administrators can distribute the Dazzle plug-in using Citrix Receiver, and users can choose their published application subscriptions. Dazzle also downloads and pre-caches streamed applications. The self-service storefront is available for both Windows and Mac users. Merchandising Server provides easy management, setup, and distribution of Citrix Receiver and related plugins and updates. Users simply point any browser to the setup site included with Merchandising Server, and within two clicks, the setup process starts. Merchandising Server software is delivered as a virtual appliance for Citrix XenServer or VMware. Infrastructure server Infrastructure servers are farm servers that host services such as license server or web interface. Usually, they do not host published applications. XenApp farms have two types of infrastructure servers: Virtualization infrastructure consists of the XenApp servers that deliver virtualized applications and VM hosted applications and roles that support sessions and administration, such as the data store, data collector, Citrix XML broker, Citrix License Server, configuration logging database (optional), load testing services database (optional), service monitoring agents, and so on. Access Infrastructure consists of roles such as the web interface, secure gateway (optional), and access gateway (optional) that provide access to users. In small deployments, we can group one or more roles together. In large deployments, we provide services on one or multiple dedicated servers. Virtualization infrastructure Virtualization infrastructure represents a series of servers that control and monitor application environments. Now, we will see different types of infrastructure servers: Citrix licensing: A Citrix License Server is required for all XenApp deployments. Install the license server on either a shared or standalone server, depending on your farm's size. After we install the license server, we need to download the appropriate license files from the MyCitrix.com website and install them in the license server. We can share a license server with multiple Citrix products. Data store database: Data store database is a repository of persistent farm information, including server's information, published applications, administrators, printers, and so on. We can host the data store database on a SQL Server Express database running on one of our XenApp servers in a small farm, use a dedicated SQL Server, or an Oracle database server in medium to large farms. Citrix XML Broker acts as an intermediary between the web interface and other servers in the farm. When a user logs in to the web interface, the XML Broker receives the user's credentials from the web interface and queries the server farm for a list of published applications that the user has permission to access. The XML Broker obtains this application set from the IMA (Independent Management Architecture) system and returns it to the web interface. Citrix XML Service: The XML Broker is a component of the Citrix XML Service. By default, the XML Service is installed on every server during XenApp setup. However, only the XML Service on the server specified in the web interface acts as the broker. In a small farm, the XML Broker runs on a server with multiple infrastructure functions. In a large farm, the XML Broker might be configured on one or more dedicated servers. Configuring a dedicated XML server is a simple task, we need to set up a dedicated XenApp server without any published applications. Single sign-on (optional): Single sign-on provides password management for published applications. Single sign-on can use Active Directory or a NTFS share to store password information. Single sign-on was formerly known as password manager and requires a Platinum license. Installation and configuration of single sign-on is out the scope of this article. Service monitoring (optional) is based on CitrixEdgesight and enables the administrator to collect, monitor, and report server resource metrics to estimate servers required to deploy a XenApp farm or to analyze the load of production servers. This feature requires a Platinum license. Installation and configuration of Edgesight is out the scope of this article. Provisioning Services (optional) assist administrators to manage the entire XenApp farm of application hosting servers, both physical and virtual, using one or multiple standardized server image. PVS can rollback to a previous working image in the time it takes to reboot. This feature requires a Platinum license. Installation and configuration of Provisioning Services is out the scope of this article. SmartAuditor (optional) allows an administrator to record the onscreen activity of any user's session, over any type of connection, from any server running XenApp. SmartAuditor uses policies to record, catalog, and archive sessions for retrieval and playback. This feature requires a Platinum license. Installation and configuration of SmartAuditor is out the scope of this article. Power and Capacity Management (optional) enables administrators to reduce power consumption and manage server capacity by dynamically scaling the number of online servers or powering on/off servers based on specific times. This feature requires a Platinum license. Installation and configuration of Power and Capacity Management is out the scope of this article. Access Infrastructure Access Infrastructure represents a series of servers deployed within the local network or the DMZ to provide access to different types of users (local or remote) to resources published on XenApp servers. XenApp farms have three types of access infrastructure servers: Web interface provides users with access to resources published on one or multiple XenApp farms through a standard web browser or through the Citrix Online Plug-in. Access Gateway (optional) is a universal SSL VPN appliance that can be used to secure client connections to XenApp farms and provide secure access to other internal network resources. XenApp Platinum Edition licenses include a universal Access Gateway license, which can be used with any Access Gateway edition. The Access Gateway appliance, also known as Netscaler, must be purchased separately. Secure Gateway (optional) assists administrators to secure access to enterprise network computers running XenApp and provides a secure Internet gateway between XenApp farms and client devices. The Secure Gateway transparently encrypts and authenticates all user connections to help protect against data tampering and theft. All data traversing the Internet between a remote workstation and the Secure Gateway is encrypted using the Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocol. The Secure Gateway is an application that runs as a service on a server that is deployed in the demilitarized zone (DMZ). Designing a basic XenApp architecture Let's take a look at the Brick Unit Constructions, a small construction company near Washington DC established in 1973 by John Charles Empire. The HQ of the company is located near Frederick in Maryland. The company had around 120 users working there. Currently, they have 17 sites under construction around the state located in a 150 miles radius from HQ. Each of these sites has 10 to 25 computers, accessing applications installed on the site server or in each user computer. So we have around 400 users between HQ and construction sites. Almost 20 percent of all these users utilize laptops, work on a few projects at the same time, and travel between sites. All these sites are connected in a MPLS network between HQ and sites using T1 links. Managing the software installed on computers and other devices in the field is a nightmare for the small IT department of the company and their manager, William Empire, son of John Charles. Usually, the projects are short-term, between 6 months to 2 years. When the project is completed, IT needs to take a full backup of every machine and the server and reassign them to a new project. None of these sites has its own IT personnel, so the management of these servers and computers (backups, installing new applications, printers, and so on) is centralized from HQ, making the administration very complicated. Users with laptops are having issues with printers and access to files located on different servers. William wants to resolve this issue by moving all data in remote file servers to a centralized file server on a NAS (Network Attached Storage) device, and migrate all printer queues located on remote sites to a new printer server on HQ. The migration of printers will help him to clean up print server drivers and check the compatibility of the current printers with Citrix. The other issue these users are having is related to an in-house developed financial application installed on construction sites servers. Users must have these applications installed multiple times (one per site). The following diagram is the Brick Unit Construction's current infrastructure: William is concerned about the following: Deciding whether he would want to run XenApp on virtual machines or physical servers Budget: The cost of all Terminal Server and Citrix licenses will require a large expenditure Virtual machines will provide a lot of benefits, but will require a large investment in a SAN (Storage Area Network), the increase of memory RAM of existing servers, and the cost of the virtualization server software William's idea is to move all applications installed on a client's machine or servers in remote sites to a XenApp farm, migrate all data in these sites to the HQ file, print servers, remove servers from field, and reuse them (these servers are pretty new) to build more XenApp servers or virtualization hosts to run XenApp on virtual machines. Moving all applications to XenApp will help IT to reduce the license cost of applications and simplify the deployment of new versions. Centralizing all data in a NAS file server will help to reduce backup costs (hardware and software) and simplify administration. Also, it will reduce the time to restore information. Currently, the most popular option to implement XenApp 6 is using virtual machines and William decided to use it for the deployment of Brick Unit's farm.
Read more
  • 0
  • 0
  • 3292

article-image-hands-tutorial-ejb-31-security
Packt
15 Jun 2011
9 min read
Save for later

Hands-on Tutorial on EJB 3.1 Security

Packt
15 Jun 2011
9 min read
EJB 3.1 Cookbook Security is an important aspect of many applications. Central to EJB security is the control of access to classes and methods. There are two approaches to controlling access to EJBs. The first, and the simplest, is through the use of declarative annotations to specify the types of access permitted. The second approach is to use code to control access to the business methods of an EJB. This second approach should not be used unless the declarative approach does not meet the needs of the application. For example, access to a method may be denied during certain times of the day or during certain maintenance periods. Declarative security is not able to handle these types of situations. In order to incorporate security into an application, it is necessary to understand the Java EE environment and its terminology. The administration of security for the underlying operating system is different from that provided by the EE server. The EE server is concerned with realms, users and groups. The application is largely concerned with roles. The roles need to be mapped to users and groups of a realm for the application to function properly. A realm is a domain for a server that incorporates security policies. It possesses a set of users and groups which are considered valid users of an application. A user typically corresponds to an individual while a group is a collection of individuals. Group members frequently share a common set of responsibilities. A Java EE server may manage multiple realms. An application is concerned with roles. Access to EJBs and their methods is determined by the role of a user. Roles are defined in such a manner as to provide a logical way of deciding which users/groups can access which methods. For example, a management type role may have the capability to approve a travel voucher whereas an employee role should not have that capability. By assigning certain users to a role and then specifying which roles can access which methods, we are able to control access to EJBs. The use of groups makes the process of assigning roles easier. Instead of having to map each individual to a role, the user is assigned to a group and the group is mapped to a role. The business code does not have to check every individual. The Java EE server manages the assignment of users to groups. The application needs only be concerned with controlling a group's access. A group is a server level concept. Roles are application level. One group can be associated with multiple applications. For example, a student group may use a student club and student registration application while a faculty group might also use the registration application but with more capability. A role is simply a name for a set of capabilities. For example, an auditor role may be to review and certify a set of accounts. This role would require read access to many, if not all, of the accounts. However, modification privileges may be restricted. Each application has its own set of roles which have been defined to meet the security needs of the application. The EE server manages realms consisting of users, groups, and resources. The server will authenticate users using Java's underlying security features. The user is then referred to as a principal and has a credential containing the user's security attributes. During the deployment of an application, users and groups are mapped to roles of the application using a deployment descriptor. The configuration of the deployment descriptor is normally the responsibility of the application deployer. During the execution of the application, the Java Authentication and Authorization Service (JAAS) API authenticates a user and creates a principal representing the user. The principal is then passed to an EJB. Security in a Java EE environment can be viewed from different perspectives. When information is passed between clients and servers, transport level security comes into play. Security at this level can include Secure HTTP (HTTPS) and Secure Sockets Layer (SSL). Messages can be sent across a network in the form of Simple Object Access Protocol (SOAP) messages. These messages can be encrypted. The EE container for EJBs provides application level security which is the focus of the chapter. Most servers provide unified security support between the web container and the EJB container. For example, calls from a servlet in a web container to an EJB are handled automatically resulting in a flexible security mechanism. Most of the recipes presented in this article are interrelated. If your intention is to try out the code examples, then make sure you cover the first two recipes as they provide the framework for the execution of the other recipes. In the first recipe, Creating the SecurityApplication, we create the foundation application for the remaining recipes. In the second recipe, Configuring the server to handle security, the basic steps needed to configure security for an application are presented. The use of declarative security is covered in the Controlling security using declarations recipe while programmatic security is discussed in the next article on Controlling security programmatically. The Understanding and declaring roles recipe examines roles in more detail and the Propagating identity recipe talks about how the identity of a user is managed in an application. Creating the SecurityApplication In this article, we will create a SecurityApplication built around a simple Voucher entity to persist travel information. This is a simplified version of an application that allows a user to submit a voucher and for a manager to approve or disapprove it. The voucher entity itself will hold only minimal information. Getting ready The illustration of security will be based on a series of classes: Voucher – An entity holding travel-related information VoucherFacade – A facade class for the entity AbstractFacade – The base class of the VoucherFacade VoucherManager – A class used to manage vouchers and where most of the security techniques will be demonstrated SecurityServlet – A servlet used to drive the demonstrations All of these classes will be members of the packt package in the EJB module except for the servlet which will be placed in the servlet package of the WAR module. How to do it... Create a Java EE application called SecurityApplication with an EJB and a WAR module. Add a packt package to the EJB module and an entity called Voucher to the package. Add five private instance variables to hold a minimal amount of travel information: name, destination, amount, approved, and an id. Also, add a default and a three argument constructor to the class to initialize the name, destination, and amount fields. The approved field is also set to false. The intent of this field is to indicate whether the voucher has been approved or not. Though not shown below, also add getter and setter methods for these fields. You may want to add other methods such as a toString method if desired. @Entity public class Voucher implements Serializable { private String name; private String destination; private BigDecimal amount; private boolean approved; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; public Voucher() { } public Voucher(String name, String destination, BigDecimal amount) { this.name = name; this.destination = destination; this.amount = amount; this.approved = false; } ... } Next, add an AbstractFacade class and a VoucherFacade class derived from it. The VoucherFacade class is shown below. As with other facade classes found in previous chapters, the class provides a way of accessing an entity manager and the base class methods of the AbstractFacade class. @Stateless public class VoucherFacade extends AbstractFacade<Voucher> { @PersistenceContext(unitName = "SecurityApplication-ejbPU") private EntityManager em; protected EntityManager getEntityManager() { return em; } public VoucherFacade() { super(Voucher.class); } } Next, add a stateful EJB called VoucherManager. Inject an instance of the VoucherFacade class using the @EJB annotation. Also add an instance variable for a Voucher. We need a createVoucher method that accepts a name, destination, and amount arguments, and then creates and subsequently persists the Voucher. Also, add get methods to return the name, destination, and amount of the voucher. @Stateful public class VoucherManager { @EJB VoucherFacade voucherFacade; Voucher voucher; public void createVoucher(String name, String destination, BigDecimal amount) { voucher = new Voucher(name, destination, amount); voucherFacade.create(voucher); } public String getName() { return voucher.getName(); } public String getDestination() { return voucher.getDestination(); } public BigDecimal getAmount() { return voucher.getAmount(); } ... } Next add three methods: submit – This method is intended to be used by an employee to submit a voucher for approval by a manager. To help explain the example, display a message showing when the method has been submitted. approve – This method is used by a manager to approve a voucher. It should set the approved field to true and return true. reject – This method is used by a manager to reject a voucher. It should set the approved field to false and return false. @Stateful public class VoucherManager { ... public void submit() { System.out.println("Voucher submitted"); } public boolean approve() { voucher.setApproved(true); return true; } public boolean reject() { voucher.setApproved(false); return false; } } To complete the application framework, add a package called servlet to the WAR module and a servlet called SecurityServlet to the package. Use the @EJB annotation to inject a VoucherManager instance field into the servlet. In the try block of the processRequest method, add code to create a new voucher and then use the submit method to submit it. Next, display a message indicating the submission of the voucher. public class SecurityServlet extends HttpServlet { @EJB VoucherManager voucherManager; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { voucherManager.createVoucher("Susan Billings", "SanFrancisco", BigDecimal.valueOf(2150.75)); voucherManager.submit(); out.println("<html>"); out.println("<head>"); out.println("<title>Servlet SecurityServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h3>Voucher was submitted</h3>"); out.println("</body>"); out.println("</html>"); } finally { out.close(); } } ... } Execute the SecurityServlet. Its output should appear as shown in the following screenshot: How it works... In the Voucher entity, notice the use of BigDecimal for the amount field. This java.math package class is a better choice for currency data than float or double. Its use avoids problems which can occur with rounding. The @GeneratedValue annotation, used with the id field, is for creating an entity facade. In the VoucherManager class, notice the injection of the stateless VoucherFacade session EJB into a stateful VoucherManager EJB. Each invocation of a VoucherFacade method may result in the method being executed against a different instance of VoucherManager. This is the correct use of a stateless session EJB. The injection of a stateful EJB into a stateless EJB is not recommended.  
Read more
  • 0
  • 0
  • 2977
article-image-customization-using-adf-meta-data-services
Packt
15 Jun 2011
8 min read
Save for later

Customization using ADF Meta Data Services

Packt
15 Jun 2011
8 min read
Oracle ADF Enterprise Application Development—Made Simple Successfully plan, develop, test and deploy enterprise applications with Oracle ADF      Why customization? The reason ADF has customization features built-in is because Oracle Fusion Applications need them. Oracle Fusion Applications is a suite of programs capable of handling every aspect of a large organization—personnel, finance, project management, manufacturing, logistics, and much more. Because organizations are different, Oracle has to offer a way for each customer organization to fit Oracle Fusion Applications to their requirements. This customization functionality can also be very useful for organizations that do not use Oracle Fusion Applications. If you have two screens that work with the same data, but one of the screens must show more fields than the other, you can create one screen with all the fields and use customization to create another version of the same screen with fewer fields for other users. For example, the destination management application might have a data entry screen showing all details of a task to a dispatcher, but only the relevant details to an airport transfer guide: Companies such as DMC Solutions that produce software for sale realize additional benefit from the customization features in ADF. DMC Solu a base application, sell it to different customers and customize each in application to that customer without changing the base application. How does an ADF customization work? More and more Oracle products are using something called Meta Data Services to store metadata. Metadata is data that describes other pieces of information—where it came from, what it means, or how it is intended to be used. An image captured by a digital camera might include metadata about where and when the picture was taken, which camera settings were used, and so on. In the case of an ADF application, the metadata describes how the application is intended to be used. There are three kinds of customizations in ADF: Seeded customizations:They are customizations defined in advance (before the user runs the application) by customization developers. User customizations(sometimes called personalizations): They are changes to aspects of the user interface by application end users. The ADF framework offers a few user customization features, but you need additional software such as Oracle WebCenter for most user customizations. User customizations are outside the scope of this article. Design time at runtime:They are advanced customization of the application by application administrators and/or properly authorized end users. This requires that application developers have prepared the possible customizations as part of application development—it is complicated to program using only ADF, but Oracle WebCenter provides advanced components that make this easier. This is outside the scope of this article. Your customization metadata is stored in either files or a database repository. If you are only planning to use seeded customizations, a file-based repository is fine. However, if you plan to allow user customizations or design time at runtime, you should set up your production server to store customizations in a metadata database. Refer to the Fusion Middleware Administrator's Guide for information about setting up a metadata database. Applying the customization layers When an ADF application is customized, the ADF framework applies one or more customization layers on top of the base application. Each layer has a value, and customizations are assigned to a specific customization layer and value. The concept of multiple layers makes it possible to apply, for example: Industry customization (customizing the application for example, the travel industry: industry=travel) Organization customization (customizing the application for a specific travel company: org=xyztravel) Site customization (customizing the application for the Berlin office) Role-based customization (customizing the application for casual, normal, and advanced users) The XDM application that DMC Solution is building could be customized in one way for ABC Travel and in another way for XYZ Travel, and XYZ Travel might decide to further customize the application for different types of users: You can have as many layers as you need—Oracle Fusion Applications is reported to use 12 layers, but your applications are not likely to be that complex. For each customization layer, the developer of the base application must provide a customization class that will be executed at runtime, returning a value for each customization layer. The ADF framework will then apply the customizations that the customization developer has specified for that layer/value combination. This means that the same application can look in many different ways, depending on the values returned by the customization classes and the customizations registered:     Org layer value Role layer value Result qrstravel any Base application, because there are no customizations defined for QRS Travel abctravel any The application customized for ABC Travel, because there are no role layer customizations for ABC Travel, the value of the role layer does not change the application xyztravel normal The application customized for XYZ Travel and further customized for normal users in XYZ Travel xyztravel superuser The application customized for XYZ Travel and further customized for super users in XYZ Travel Making an application customizable To make an application customizable, you need to do three things: Develop a customization class for each layer of customization. Enable seeded customization in the application. Link the customization class to the application. The customization developer, who will be developing the customizations, will additionally have to set up JDeveloper correctly so that all customization levels can be accessed. This setup is described later in the article. Developing the customization classes For each layer of customization, you need to develop a customization class with a specific format—technically, it has to extend the Oracle-supplied abstract class oracle.mds.cust.CustomizationClass. A customization class has a name (returned by the getName() method) and a value (returned by the getValue() method). At runtime, the ADF framework will execute the customization classes for all layers to determine the customization value at each level. Additionally, the customization class has to return a short unique prefix to use for all customized items, and a cache hint telling ADF if this is a static or dynamic customization. Building the classes Your customization classes should go in your Common Code workspace. A customization class is a normal Java class, that is, it is created with File | New | General | Java Class. In the Create Java Class dialog, give your class a name (OrgLayerCC) and place it into a customization package (for example, com.dmcsol. xdm.customization). Choose to extend oracle.mds.cust.CustomizationClass and check the Implement Abstract Methods checkbox: Create a similar class called RoleLayerCC. Implementing the methods Because you asked the JDeveloper to implement the abstract methods, your classes already contain three methods: getCacheHint() getName() getValue(RestrictedSession, MetadataObject) The getCacheHint() method must return an oracle.mds.cust.CacheHint constant that tells ADF if the value of this layer is static (common for all users) or dynamic (depending on the user). The normal values here are ALL_USERS for static customizations or MULTI_USER for customizations that apply to multiple users. In the XDM application, you will use: ALL_USERS for OrgLevelCC, because this customization layer will apply to all users in the organization MULTI_USER for RoleLevelCC, because the role-based customization will apply to multiple users, but not necessarily to all Refer to the chapter on customization with MDS in Fusion Developer's Guide for Oracle Application Development Framework for information on other possible values. The getName() method simply returns the the name of the customization layer. The getValue() method must return an array of String objects. It will normally make most sense to return just one value—the application is running for exactly one organization, you are either a normal user or a super user. For advanced scenarios, it is possible to return multiple values, in such a case multiple customizations will be applied at the same layer. Each customization that a customization developer defines will be tied to a specific layer and value—there might be a customization that happens when org has the value xyztravel. For the OrgLayerCC class, the value is static and is defined when DMC Solutions installs the application for XYZ Travel—for example, in a property file. For the RoleLayerCC class , the value is dynamic, depending on the current user, and can be retrieved from the ADF security context. The OrgLayerCC class could look like the following: package com.dmcsol.xdm.customization; import ... public class RoleLayerCC extends CustomizationClass { public CacheHint getCacheHint() { return CacheHint.MULTI_USER; } public String getName() { return "role"; } public String[] getValue(RestrictedSession restrictedSession, MetadataObject metadataObject) { String[] roleValue = new String[1]; SecurityContext sec = ADFContext.getCurrent(). getSecurityContext(); if (sec.isUserInRole("superuser")) { roleValue[0] = "superuser"; } else { roleValue[0] = "normal"; } return roleValue; } } The GetCacheHint() method returns MULTI_USER because this is a dynamic customization—it will return different values for different users. The GetName() method simply returns the name of the layer. The GetValue() method uses oracle.adf.share.security.SecurityContext to look up if the user has the super user role and returns the value superuser or normal. Deploying the customization classes Because you place your customization class in the Common Code project, you need to deploy the Common Code project to an ADF library and have the build/ configuration manager copy it to your common library directory.
Read more
  • 0
  • 0
  • 3281

article-image-overview-joomla-virtuemart
Packt
15 Jun 2011
12 min read
Save for later

An overview of Joomla! and VirtueMart

Packt
15 Jun 2011
12 min read
Navigating through the Joomla! and VirtueMart directories You should have a Joomla! and VirtueMart e-commerce site installed somewhere. If not, you should now install one first before reading on. From this point onward, we will assume that you can access a Joomla! VirtueMart site and can freely browse its content, either on your local computer using the file manager of your operating system or in a web server somewhere using an FTP client program. To work on the exercises, you should also be able to edit each of the files. OK. Let's start our study by navigating through the Joomla! directories. If you look at the root of your Joomla! site, you will be amazed how large the Joomla! project is. There are totally close to 5,000 files under some 350 directories! It would be difficult to find your way through this vast structure of files if there are no hints at all. Fortunately, Joomla! has a very good directory structure and will be easy to follow once you know its basic organization. Knowing your way through this vast structure is very important when embarking on any VirtueMart customization project of considerable size. The good news is that usually we only need to know a very small fraction of those 350 directories and 5,000 files. In the Joomla! root, the most important directories we need to know are the administrator, components, modules, and plugins directories (This does not mean that the other directories are not important. We highlight these few directories just because they are the directories we will reference from time-to-time) You will probably recognize that the last three of these shortlisted directories correspond to the three major extension types of Joomla! So within these directories, we will expect to see a series of subdirectories, each of which corresponds to an extension installed in the Joomla! framework. This is exactly the case, except for the plugins where the directories are arranged in terms of their type instead of their source. Let's take a closer look at one of the most important components that comes with Joomla!. Navigate to the components directory and open the subdirectory com_content. The com_content component is the one that manages articles we created in Joomla!. You have probably been using a lot of this component. Within this directory, you will find a number of files and a few subdirectories. We notice there is a file named controller.php and two subdirectories named models and views. We will have more to say on these in a moment. Let's move back to the root directory and take a look at the last important directory mentioned above. This administrator directory mimics the root directory in many respects. We see that most of the subdirectories we found in the root have a corresponding subdirectory within the administrator directory. For example, we find subdirectories named components and modules within the administrator as well. As we know, there are two main sections of a Joomla! website, also known as the frontend and the backend. The root directory and administrator directory are respectively the location where the frontend and backend files are located. While this dividing line is not rigid, we can use this as a guide when we want to locate a frontend or backend file. Since both the root and the administrator directories contain a subdirectory called components, to avoid ambiguity, we will refer to them as the root components and administrator components directory, respectively. Now, let's work our way a little bit down the directory tree to see how VirtueMart fits into this framework. Within the root components directory, you will see a subdirectory called com_virtuemart. Yes, this is the location where you can find all the files used by VirtueMart for the frontend. Under the com_virtuemart directory, among some other files and subdirectories, you will notice a themes subdirectory. You will find each of the VirtueMart themes you have installed there. The themes directory is the major work area. From now on, we will refer to the com_virtuemart directory under the root components directory as the root VirtueMart directory or the frontend VirtueMart directory. Within the administrator components directory, there is also a subdirectory called com_virtuemart where the backend VirtueMart files are located. Under this main directory, there are four subdirectories named as classes, html, languages, and sql. Obviously, these directories will contain, respectively, the class files, HTML files, language files, and SQL (also known as database) files. Actually, the classes and html directories have a deeper meaning than their names suggest, as we shall see in a moment. Structure of the Joomla! URL path Before leaving our high-level exploration of the Joomla! tree structure, let's digress a little bit to study how a Joomla! URL is built up. While the Joomla! directory structure is so complicated, the URL used to access the site is much simpler. Most of the time, the URL just starts with index.php?. (If you have a Search Engine Friendly or SEF system enabled, you should turn it off during the development and testing of your customization, or at least turn it off mentally while we are talking about the URL. You can turn off SEF in the Joomla! Configuration page.) For example, if we want to access the VirtueMart (frontend) home page, we can use the following URL: http://your_joomla_live_site/index.php?option=com_virtuemart Similarly, the URL http://your_joomla_live_site/administrator/index.php?option=com_virtuemart will bring up the VirtueMart backend control panel, if you're already logged in. All other Joomla! URL, in fact, work in the same way, although many times you see some additional parameters as well. (Don't forget to replace your_joomla_live_site in the above URL with your domain name and the Joomla! root directory, in case the site is not installed in the root.) Actually, the index.php script is the main entry into your Joomla! site. All major requests to the frontend start from here (major requests only since there are some other entry points as well, but they don't bother us at this point). Similarly, all major requests to the backend start from the file administrator/index.php. Restricting the entry point to the site makes it very easy to control authorized and unauthorized accesses. For example, if we want to put the site offline, we can simply change a configuration in Joomla! and all components will be offline as well. We don't need to change each page or even each component one-by-one. Understanding the structure of the Joomla! URL is pretty useful during the development and debugging process. Sometimes we may need to work on a partly live site in which the Joomla! site is already working, but the VirtueMart shop is still under construction. In such cases, it is common to unpublish the menu items for the shop so that the shop is still hidden from the public. The fact that the menu item is hidden actually means the shop is less accessible but not inaccessible. If we want to test the VirtueMart shop, we can still type the URL on the browser by ourselves. Using the URL http://your_joomla_live_site/index.php?option=com_virtuemart we can bring up the VirtueMart home page. We will learn some more tricks in testing individual shop pages along the way of our study of VirtueMart themes and templates. One simple application of what we learnt about the URL can be used when customizing Joomla!. When working with VirtueMart projects, we will need to go to the VirtueMart backend from time-to-time to modify the VirtueMart settings. As we all know, after logging in, what we have on the browser window is the control panel page. We will need to point to the components/virtuemart menu before we can open the VirtueMart backend home. This is not a complicated task, but will be very tedious if repeated every time we log back into the site. Can we make Joomla! smarter, to open the VirtueMart home by default when we log on? Yes, we can. The trick actually relates to what we talked about so far. If you want to customize Joomla! to open the VirtueMart backend by default, you can stay with me for the following warm-up exercise. I understand some of you may not want to change the default login page. Exercise 1.1: Making the Joomla! backend default to VirtueMart Open your favorite text editor. Navigate to the Joomla! site root. Open the file administrator/includes/helper.php. At around line 44 (the actual line may vary from version-to-version), change the code $option = 'com_cpanel'; to $option = 'com_virtuemart'; Save the file. Open your browser and log in to your Joomla! site. Alas, you should see the VirtueMart control panel instead of the Joomla! control panel. This simple exercise demonstrated that sometimes a useful change does not need complex coding. What we need is a little knowledge of how things work. I bet you probably understand what we have done above without explanation. After login, Joomla! will automatically go to the default component, hardcoded in the file helper.php. For standard Joomla!, this will be the com_cpanel component. In Exercise 1.1, we have changed this default backend component from com_cpanel to com_virtuemart. Instead of VirtueMart, we can certainly change the default to other components such as community builder or MOSET. Joomla! 1.5 presentation framework Since VirtueMart is a Joomla! component, it cannot exist outside Joomla!. So before diving into the detail of the VirtueMart engine, it pays to take a brief look at how Joomla! actually works. While an understanding of the presentation framework of Joomla! and VirtueMart may be useful for themes and templates development, it is not essential for the actual customization design. Joomla! emerged from version 1.0 and later developed into 1.5. In this upgrade, Joomla! has been basically rewritten from the ground up. A presentation structure called Model-View-Controller or MVC has been adopted in Joomla! 1.5. While a detailed explanation of the MVC structure is out of the scope, a basic understanding of its working will help us understand why and how VirtueMart 1.1 behaves in the way it is right now. Joomla! is a web application. Each page of Joomla! is in fact a text file consisting of HTML code. Depending on the detail parameters of a web request, Joomla! will generate a dynamic HTML page by combining data stored in the database and site configuration data stored in various PHP files. In the early history of dynamic web pages, program code were written in a way that HTML tags are mixed with presentation logic in one place. The spaghetti code, as it is sometimes called, makes maintenance and extension of the coding very difficult. As the basic structure of a dynamic web page is better understood, more and more new coding patterns emerge to make the life of a web developer easier. The MVC presentation framework is one of those patterns that have been proposed to build computer applications. This framework has gradually become the standard pattern for building web applications and has been adopted by many open source web projects. Models In the MVC presentation framework , the job of building a web page is divided into three main tiers. The backend tier is the data that is stored in the database (strictly speaking, there is no prescribed data storage format though a database is a natural way to manage the data). We need to grab data needed to build the web page. This tier of the job is done by the Model, which describes how data is stored and how data can be retrieved from the data server. Views The frontend tier determines what and how data is presented on the browser. This is the job of the View. For a given dataset from a Model, there can be many different ways to present the data. Let's say, we have a set of statistical data, for example. We can present this data as a bar graph or a pie chart. Each of these presentations is called a View of the same Model. Controllers Now statistical data is just a set of numbers. How can we convert them into a bar graph or a pie chart? That is exactly how the Controller comes into place. A Controller is a routine specifying how to convert the Model into various Views. One major advantage of this separation of data (Model) and presentation (View) makes changes to the application much easier. We can change the presentation independent of the underlying data and vice versa. So, in the Joomla! 1.5 world, we will have a set of Models which interface with the database, a set of Views to tell the browser how to present the data, and a set of Controllers that control how to convert the Model into the View. According to the best practice, all Joomla! 1.5 components should follow this same structure. Thus, each Joomla! 1.5 component should have two subdirectories called models and views. Also, the root directory will contain a controller.php which extends the Joomla! controller's capability. This structure is revealed as we look at the contents of a Joomla! component which we had done previously. However, because of historical reasons and others, not all components follow this best practice. VirtueMart is one of those exceptions.
Read more
  • 0
  • 0
  • 2280
Modal Close icon
Modal Close icon