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-java-7-managing-files-and-directories
Packt
24 Feb 2012
12 min read
Save for later

Java 7: Managing Files and Directories

Packt
24 Feb 2012
12 min read
(For more resources on Java, see here.) Introduction It is often necessary to perform file manipulations, such as creating files, manipulating their attributes and contents, or removing them from the filesystem. The addition of the java.lang.object.Files class in Java 7 simplifies this process. This class relies heavily on the use of the new java.nio.file.Path interface. The methods of the class are all static in nature, and generally assign the actual file manipulation operations to the underlying filesystem. Many of the operations described in this chapter are atomic in nature, such as those used to create and delete files or directories. Atomic operations will either execute successfully to completion or fail and result in an effective cancellation of the operation. During execution, they are not interrupted from the standpoint of a filesystem. Other concurrent file operations will not impact the operation. To execute many of the examples in this chapter, the application needs to run as administrator. To run an application as administrator under Windows, right-click on the Command Prompt menu and choose Run as administrator. Then navigate to the appropriate directory and execute using the java.exe command. To run as administrator on a UNIX system, use the sudo command in a terminal window followed by the java command. Basic file management is covered in this chapter. The methods required for the creation of files and directories are covered in the Creating Files and Directories recipe. This recipe focuses on normal files. The creation of temporary files and directories is covered in the Managing temporary files and directories recipe and the creation of linked files is covered in the Managing symbolic links recipe. The options available for copying files and directories are found in the Controlling how a file is copied recipe. The techniques illustrated there provide a powerful way of dealing with file replication. Moving and deleting files and directories are covered in the Moving a file or directory and Deleting files and directories recipes, respectively. The Setting time-related attributes of a file or directory recipe illustrates how to assign time attributes to a file. Related to this effort are other attributes, such as file ownership and permissions. File ownership is addressed in the Managing file ownership recipe. File permissions are discussed in two recipes: Managing ACL file permissions and Managing POSIX file permissions. Creating files and directories The process of creating new files and directories is greatly simplified in Java 7. The methods implemented by the Files class are relatively intuitive and easy to incorporate into your code. In this recipe, we will cover how to create new files and directories using the createFile and createDirectory methods. Getting ready In our example, we are going to use several different methods to create a Path object that represents a file or directory. We will do the following: Create a Path object. Create a directory using the Files class' createDirectory method. Create a file using the Files class' createFile method. The FileSystem class' getPath method can be used to create a Path object, as can the Paths class' get method. The Paths class' static get method returns an instance of a Path based on a string sequence or a URI object. The FileSystem class' getPath method also returns a Path object, but only uses a string sequence to identify the file. How to do it... Create a console application with a main method. In the main method, add the following code that creates a Path object for the directory /home/test in the C directory. Within a try block, invoke the createDirectory method with your Path object as the parameter. This method will throw an IOException if the path is invalid. Next, create a Path object for the file newFile.txt using the createFile method on this Path object, again catching the IOException as follows: try{ Path testDirectoryPath = Paths.get("C:/home/test"); Path testDirectory = Files.createDirectory(testDirectoryPath); System.out.println("Directory created successfully!"); Path newFilePath = FileSystems.getDefault(). getPath("C:/home/test/newFile.txt"); Path testFile = Files.createFile(newFilePath); System.out.println("File created successfully!");}catch (IOException ex){ ex.printStackTrace();} Execute the program. Your output should appear as follows: Directory created successfully! File created successfully! Verify that the new file and directory exists in your filesystem. Next, add a catch block prior to the IOException after both methods, and catch a FileAlreadyExistsException: }catch (FileAlreadyExistsException a){System.out.println("File or directory already exists!");}catch (IOException ex){ ex.printStackTrace();} When you execute the program again, your output should appear as follows: File or directory already exists! How it works... The first Path object was created and then used by the createDirectory method to create a new directory. After the second Path object was created, the createFile method was used to create a file within the directory, which had just been created. It is important to note that the Path object used in the file creation could not be instantiated before the directory was created, because it would have referenced an invalid path. This would have resulted in an IOException. When the createDirectory method is invoked, the system is directed to check for the existence of the directory first, and if it does not exist, create it. The createFile method works in a similar fashion. The method fails if the file already exists. We saw this when we caught the FileAlreadyExistsException. Had we not caught that exception, an IOException would have been thrown. Either way, the existing file would not be overwritten. There's more... The createFile and createDirectory methods are atomic in nature. The createDirectories method is available to create directories, as discussed next. All three methods provide the option to pass file attribute parameters for more specific file creation. Using the createDirectories method to create a hierarchy of directories The createDirectories method is used to create a directory and potentially other intermediate directories. In this example, we build upon the previous directory structure by adding a subtest and a subsubtest directory to the test directory. Comment out the previous code that created the directory and file and add the following code sequence: Path directoriesPath = Paths. get("C:/home/test/subtest/subsubtest"); Path testDirectory = Files.createDirectories(directoriesPath); Verify that the operation succeeded by examining the resulting directory structure. See also Creating temporary files and directories is covered in the Managing temporary files and directories recipe. The creation of symbolic files is illustrated in the Managing symbolic links recipe. Controlling how a file is copied The process of copying files is also simplified in Java 7, and allows for control over the manner in which they are copied. The Files class' copy method supports this operation and is overloaded providing three techniques for copying those which differ by their source or destination. Getting ready In our example, we are going to create a new file and then copy it to another target file. This process involves: Creating a new file using the createFile method. Creating a path for the destination file. Copying the file using the copy method. How to do it... Create a console application with a main method. In the main method, add the following code sequence to create a new file. Specify two Path objects, one for your initial file and one for the location where it will be copied. Then add the copy method to copy that file to the destination location as follows: Path newFile = FileSystems.getDefault(). getPath("C:/home/docs/newFile.txt"); Path copiedFile = FileSystems.getDefault(). getPath("C:/home/docs/copiedFile.txt"); try{ Files.createFile(newFile); System.out.println("File created successfully!"); Files.copy(newFile, copiedFile); System.out.println("File copied successfully!");}catch (IOException e){ System.out.println("IO Exception.");} Execute the program. Your output should appear as follows: File created successfully! File copied successfully! When you execute the program again, your output should appear as follows: File copied successfully! How it works... The createFile method created your initial file, and the copy method copied that file to the location specified by the copiedFile variable. If you were to attempt to run that code sequence twice in a row, you would have encountered an IOException, because the copy method will not, by default, replace an existing file. The copy method is overloaded. The second form of the copy method used the java.lang.enum.StandardCopyOption enumeration value of REPLACE_EXISTING, which allowed the file to be replaced. The three enumeration values for StandardCopyOption are listed in the following table: Value Meaning ATOMIC_MOVE Perform the copy operation atomically COPY_ATTRIBUTES Copy the source file attributes to the destination file REPLACE_EXISTING Replace the existing file if it already exists Replace the copy method call in the previous example with the following: Files.copy(newFile, copiedFile, StandardCopyOption.REPLACE_EXISTING); When the code executes, the file should be replaced. Another example of the use of the copy options is found in the There's more... section of the Moving a file and directory recipe. There's more... If the source file and the destination file are the same, then the method completes, but no copy actually occurs. The copy method is not atomic in nature. There are two other overloaded copy methods. One copies a java.io.InputStream to a file and the other copies a file to a java.io.OutputStream. In this section, we will examine, in more depth, the processes of: Copying a symbolic link file Copying a directory Copying an input stream to a file Copying a file to an output stream Copying a symbolic link file When a symbolic link file is copied, the target of the symbolic link is copied. To illustrate this, create a symbolic link file called users.txt in the music directory to the users.txt file in the docs directory. Use the following code sequence to perform the copy operation: Path originalLinkedFile = FileSystems.getDefault(). getPath("C:/home/music/users.txt"); Path newLinkedFile = FileSystems.getDefault(). getPath("C:/home/music/users2.txt"); try{ Files.copy(originalLinkedFile, newLinkedFile); System.out.println("Symbolic link file copied successfully!");}catch (IOException e){ System.out.println("IO Exception.");} Execute the code. You should get the following output: Symbolic link file copied successfully! Examine the resulting music directory structure. The user2.txt file has been added and is not connected to either the linked file or the original target file. Modification of the user2.txt does not affect the contents of the other two files. Copying a directory When a directory is copied, an empty directory is created. The files in the original directory are not copied. The following code sequence illustrates this process: Path originalDirectory = FileSystems.getDefault(). getPath("C:/home/docs"); Path newDirectory = FileSystems.getDefault(). getPath("C:/home/tmp"); try{ Files.copy(originalDirectory, newDirectory); System.out.println("Directory copied successfully!");} catch (IOException e){ e.printStackTrace();} When this sequence is executed, you should get the following output: Directory copied successfully! Examine the tmp directory. It should be empty as any files in the source directory are not copied. Copying an input stream to a file The copy method has a convenient overloaded version that permits the creation of a new file based on the input from an InputStream. The first argument of this method differs from the original copy method, in that it is an instance of an InputStream. The following example uses this method to copy the jdk7.java.net website to a file: Path newFile = FileSystems.getDefault(). getPath("C:/home/docs/java7WebSite.html"); URI url = URI.create("http://jdk7.java.net/"); try (InputStream inputStream = url.toURL().openStream()) Files.copy(inputStream, newFile); System.out.println("Site copied successfully!");} catch (MalformedURLException ex){ ex.printStackTrace();}catch (IOException ex){ ex.printStackTrace();} When the code executes, you should get the following output: Site copied successfully! A java.lang.Object.URI object was created to represent the website. Using the URI object instead of a java.lang.Object.URL object immediately avoids having to create a separate try-catch block to handle the MalformedURLException exception. The URL class' openStream method returns an InputStream, which is used as the first parameter of the copy method. The copy method was then executed. The new file can now be opened with a browser or otherwise can be processed as needed. Notice that the method returns a long value representing the number of bytes written. Copying a file to an output stream The third overloaded version of the copy method will open a file and write its contents to an OutputStream. This can be useful when the content of a file needs to be copied to a non-file object such as a PipedOutputStream. It can also be useful when communicating to other threads or writing to an array of bytes, as illustrated here. In this example, the content of the users.txt file is copied to an instance of a ByteArrayOutputStream>. Its toByteArray method is then used to populate an array as follows: Path sourceFile = FileSystems.getDefault(). getPath("C:/home/docs/users.txt"); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { Files.copy(sourceFile, outputStream); byte arr[] = outputStream.toByteArray(); System.out.println("The contents of " + sourceFile.getFileName()); for(byte data : arr) { System.out.print((char)data);} System.out.println();}catch (IOException ex) { ex.printStackTrace();} Execute this sequence. The output will depend on the contents of your file, but should be similar to the following: The contents of users.txt Bob Jennifer Sally Tom Ted Notice the use of the try-with-resources block that handles the opening and closing of the file. It is always a good idea to close the OutputStream, when the copy operation is complete or exceptions occur. The try-with-resources block handles this nicely. The method may block until the operation is complete in certain situations. Much of its behavior is implementation-specific. Also, the output stream may need to be flushed since it implements the Flushable interface. Notice that the method returns a long value representing the number of bytes written. See also See the Managing symbolic links recipe for more details on working with symbolic links.
Read more
  • 0
  • 0
  • 8621

article-image-customizing-look-and-feel-uag
Packt
22 Feb 2012
8 min read
Save for later

Customizing Look and Feel of UAG

Packt
22 Feb 2012
8 min read
(For more resources on Microsoft Forefront UAG, see here.) Honey, I wouldn't change a thing! We'll save the flattery for our spouses, and start by examining some key areas of interest what you might want and be able to change on a UAG implementation. Typically, the end user interface is comprised of the following: The Endpoint Components Installation page The Endpoint Detection page The Login page The Portal Frame The Portal page The Credentials Management page The Error pages There is also a Web Monitor, but it is typically only used by the administrator, so we won't delve into that. The UAG management console itself and the SSL-VPN/SSTP client-component user interface are also visual, but they are compiled code, so there's not much that can be done there. The elements of these pages that you might want to adjust are the graphics, layout, and text strings. Altering a piece of HTML or editing a GIF in Photoshop to make it look different may sound trivial, but there's actually more to it than that, and the supportability of your changes should definitely be questioned on every count. You wouldn't want your changes to disappear upon the next update to UAG, would you? Nor would you look the page to suddenly become all crooked because someone decided that he wants the RDP icon to have an animation from the Smurfs. The UI pages Anyone familiar with UAG will know of its folder structure and the many files that make up the code and logic that is applied throughout. For those less acquainted however, we'll start with the two most important folders you need to know—InternalSite and PortalHomePage. InternalSite contains pages that are displayed to the user as part of the login and logout process, as well as various error pages. PortalHomePage contains the files that are a part of the portal itself, shown to the user after logging in. The portal layout comes in three different flavors, depending on the client that is accessing it. The most common one is the Regular portal, which happens to be the more polished version of the three, shown to all computers. The second is the Premium portal, which is a scaled-down version designed for phones that have advanced graphic capabilities, such as Windows Mobile phones. The third is the Limited portal, which is a text-based version of the portal, shown to phones that have limited or no graphic capabilities, such as the Nokia S60 and N95 handsets. Regardless of the type, the majority of devices connecting to UAG will present a user-agent string in their request and it is this string that determines the type of layout that UAG will use to render its pages and content. UAG takes advantage of this, by allowing the administrator to choose between the various formats that are made available, on a per application basis. The results are pretty cool and being able to cater for most known platforms and form factors, provides users with the best possible experience. The following screenshot illustrates an application that is enabled for the Premium portal, and how the portal and login pages would look on both a premium device and on a limited device: Customizing the login and admin pages The login and admin pages themselves are simple ASP pages, which contain a lot of code, as well as some text and visual elements. The main files in InternalSite that may be of interest to you are the following: Login.asp LogoffMsg.asp InstallAndDetect.asp Validate.asp PostValidate.asp InternalError.asp In addition, UAG keeps another version of some of the preceding files for ADFS, OTP, and OWA under similarly named folders. This means that if you have enabled the OWA theme on your portal, and you wish to customize it, you should work with the files under the /InternalSite/OWA folder. Of course, there are many other files that partake in the flow of each process, but the fact is there is little need to touch either the above or the others, as most of the appearance is controlled by a CSS template and text strings stored elsewhere. Certain requirements may even involve making significant changes to the layout of the pages, and leave you with no other option but to edit core ASP files themselves, but be careful as this introduces risk and is not technically supported. It's likely that these pages change with future updates to UAG, and that may cause a conflict with the older code that is in your files. The result of mixing old and new code is unpredictable, to say the least. The general appearance of the various admin pages is controlled by the file /InternalSite/CSS/template.css. This file contains about 80 different style elements including some of the 50 or so images displayed in the portal pages, such as the gradient background, the footer, and command buttons to name a few. The images themselves are stored in /InternalSite/Images. Both these folders have an OWA folder, which contains the CSS and images for the OWA theme. When editing the CSS, most of the style names will make sense, but if you are not sure, then why not copy the relevant ASP file and the CSS to your computer, so you can take a closer look with a visual editor, to better understand the structure. If you are doing this be careful not to make any changes that may alter the code in a damaging way, as this is easily done and can waste a lot of valuable time. A very useful piece of advice for checking tweaked code is to consider the use of Internet Explorer's integrated developer tool. In case you haven't noticed, it's a simple press of F12 on the keyboard and you'll find everything you need to get debugging. IE 9 and higher versions even pack a nifty trace module that allows you to perform low-level inspection on client-server interaction, without the need for additional third-party tools. We don't intend to devote this book to CSS, but one useful CSS element to be familiar with is the display: none; element, which can be used to hide any element it's put in. For example, if you add this to the .button element, it will hide the Login button completely. A common task is altering the part of the page where you see the Application and Network Access Portal text displayed. The text string itself can be edited using the master language files, which we will discuss shortly. The background of that part of the page, however, is built with the files headertopl.gif, headertopm.gif, and headertopr.gif. The original page design is classic HTML—it places headertopl on the left, headertopr on the right, and repeats headertopm in between to fill the space. If you need to change it, you could simply design a similar layout and put the replacement image files in /InternalSite/Images/CustomUpdate. Alternatively, you might choose to customize the logo only by copying the /InternalSite/Samples/logo.inc file into the /InternalSite/Inc/CustomUpdate folder, as this is where the HTML code that pertains to that area is located. Another thing that's worth noting is that if you create a custom CSS file, it takes effect immediately, and there's no need to do an activation. Well at least for the purposes of testing anyway. The same applies for image file changes too but as a general rule you should always remember to activate when finished, as any new configurations or files will need to be pushed into the TMG storage. Arrays are no exception to this rule either and you should know that custom files are only propagated to array members during an activation, so in this scenario, you do need to activate after each change. During development, you may copy the custom files to each member node manually to save time between activations, or better still, simply stop NLB on all array members so that all client traffic is directed to the one you are working on. An equally important point is that when you test changes to the code, the browser's cache or IIS itself may still retain files from the previous test or config, so if changes you've made do not appear first time around, then start by clearing your browser's cache and even reset IIS, before assuming you messed up the code. Customizing the portal As we said earlier, the pages that make up a portal and its various flavors are under the PortalHomePage folder. These are all ASP.NET files (.ASPX), and the scope for making any alterations here is very limited. However, the appearance is mostly controlled via the file /InternalSite/PortalHomePage/Standard.Master, which contains many visual parameters that you can change. For example, the DIV with ID content has a section pertaining to the side bar application list. You might customize the midTopSideBarCell width setting to make the bar wider or thinner. You can even hide it completely by adding style="display: none;" to the contentLeftSideBarCell table cell. As always, make sure you copy the master file to CustomUpdate, and not touch the original file, and as with the CSS files, any changes you make take effect immediately. Additional things that you can do with the portal are removing or adding buttons to the portal toolbar. For example, you might add a button to point to a help page that describes your applications, or a procedure to contact your internal technical support in case of a problem with the site.
Read more
  • 0
  • 0
  • 2710

article-image-making-your-iad
Packt
17 Feb 2012
6 min read
Save for later

Making Your iAd

Packt
17 Feb 2012
6 min read
Getting iAd Producer iAd Producer is the tool that allows us to assemble great interactive ads with a simple drag-and-drop visual interface. Download and install iAd Producer on your Mac, so that you can start creating an ad. Time for action – installing iAd Producer To install iAd Producer, follow these steps: To download and use iAd Producer, you need to be a paid member of the iOS Developer Program. Go to https://developer.apple.com/ios/ and click on the Log in button. Enter your Apple ID and password, and click on Sign In. After you've signed in, find the Downloads section at the bottom of the page. Click on iAd Producer to start downloading it. You can see the download highlighted here: If you cannot see iAd Producer in the Downloads, make sure you're logged in and your developer account has been activated. After the download is complete, open the file and run iAd Producer.mpkg to start the installation wizard. Follow the steps in the installation and enter your Mac password, if asked for it. When installing certain software, you need to enter your Mac password to allow it to have privileged access to your system. Don't confuse this with your Apple ID that we set up for the iOS Developer Program. If you don't have a password on your Mac, just leave the password area blank and click on OK. When you've gone through the installation steps it'll take a couple of moments to install. After you get a The installation was successful message you can close the installer. What just happened? We now have iAd Producer installed; whenever you need to open it, you can find it in the Applications folder on your Mac. Working with iAd Producer Let's take a look at some of the main parts of iAd Producer that you'll be using regularly, to familiarize yourself with the interface. Launch screen When you first open iAd Producer, you'll be able to start a new iPhone or iPad project from the project selector, as shown in the following screenshot. As the screen size and experience is so different between the two devices, we have to design and build ads specifically for each one: From the launch screen, you can also open existing projects you've been working on. Default ad Once you have chosen to create either an iPad or iPhone iAd, a placeholder ad is created for you, showing the visual flow. This is the overview of your ad, which you'll be using to piece the sections of your ad together. The following screenshot shows the default overview: Double-clicking on any of the screens in your ad flow will ask you to pick a template for that page; once assigned, you're then able to design the iAd using the canvas editor. Template selector Before we edit any page of an ad, we have to apply a template to it, even if it's just a blank canvas to build upon. iAd Producer automatically shows the relevant templates to the current page you're editing. This means your ad follows a structure that the users expect. Templates provide some great starting points for your iAd, whether it's for a simple banner with an image and text or a 3D image carousel that the user can flick and manipulate, all created with easy point and click. The following screenshot is an example of the template chooser: Asset Library The Asset Library holds all the media and content for your iAd, such as the images, videos, and audio. When adding media to your Asset Library, make sure you're using high-resolution images for the high-resolution Retina display. iAd Producer automatically generates the lower-resolution images for your ad, whenever you import resources. If you wanted an image to be 200px wide and 300px high, you should double the horizontal and vertical pixels to 400px wide and 600px high. This will mean your graphics look crisp and awesome on the high-resolution screens. The following screenshot shows an example of media in the Asset Library: Ad canvas Once you've selected a template, you can double-click on the item in the Overview to open up the canvas for that page. The ad canvas is where you customize your iAd with a powerful visual editor to manipulate each page of your ad. Here's an example of the ad canvas with a video carousel added to it: Setting up your ad Let's create and save an empty project to use as we create our iAd; you'll only need to do this once for each ad. Whenever you're working with something digital, it's important to save your iAd whenever you make a significant change, in case iAd Producer closes unexpectedly. Try to get into the habit of saving regularly, to avoid losing your ad. Time for action – creating a new project In order to create a new project, follow the ensuing steps: If you haven't created a new project already, open iAd Producer from your Applications folder. Select the iPhone from the launch screen and choose Select. You'll now see the default ad overview. iAd Producer has automatically made us a project called Untitled and populated it with the default set of pages. From the File menu, select Save to save your empty iAd, ready to have the components added to it later. Name the project something like Dino Stores, as that is the ad we'll be working on. You can now save the progress of your project at any time by choosing File then Save from the menu bar or pressing Command + S on your keyboard. What just happened? You've now seen the project selector and the launch screen in action, and have the base project that we'll be building upon as we make our first iAd. If you quit this project you can now open the project from within iAd Producer by clicking on File | Open, from the menu bar; or, simply double-click the project file in Finder to automatically open it. Getting the resources In this article, we'll be using the Dino Stores example resources that are available to download with this book. If you want to use your own assets, you'll need the following media: An image for your banner, approximately 120px wide and 100px high An image of your company logo or name, around 420px wide and 45px high An 80px square image, with transparency, to be used as a map pin A loading image, approximately 600px wide and 400px high Between six and 10 images for a gallery, each around 304px wide and 440px high Two or more images that will change when the iPhone is shaken, each around 600px wide and 800px high An image related to your product or service, at least 300px wide, to use on the main menu page These pixel sizes are at double-size to account for the high-resolution Retina display found on the iPhone 4 and later. iAd Producer will automatically create the lower-resolution versions for older devices.
Read more
  • 0
  • 0
  • 8819

article-image-sencha-touch-layouts-revisited
Packt
16 Feb 2012
7 min read
Save for later

Sencha Touch: Layouts Revisited

Packt
16 Feb 2012
7 min read
  (For more resources on this topic, see here.) The reader can benefit from the previous article on The Various Components in Sencha Touch. The base component class When we talk about components in Sencha Touch, we are generally talking about buttons, panels, sliders, toolbars, form fields, and other tangible items that we can see on the screen. However, all of these components inherit their configuration options, methods, properties, and events from a single base component with the startlingly original name of component. This can obviously lead to a bit of confusion, so we will refer to this as Ext.Component. One of the most important things to understand is that you will never actually use Ext.Component directly. It is simply used as a building block for all of the other components in Sencha Touch. However, it is important to be familiar with the base component class, because anything it can do, all the other components can do. Learning this one class can give you a huge head start on everything else. Some of the more useful configuration options of Ext.Component are as follows: border cls disabled height/width hidden html margin padding scroll style ui Ext.Component also contains a number of useful methods that will allow you to get and set properties on any Sencha Touch component. Here are a few of those methods: addCls and removeCls: Add or remove a CSS class from your component. destroy: Remove the component from memory. disable and enable: Disable or enable the component (very useful in forms). getHeight, getWidth, and getSize: Get the current height, width, or size of the component. Size returns both height and width. You can also use setHeight, setWidth, and setSize, to change the dimensions of your component. show and hide: Show or hide the component. setPosition: Set the top and left values for the component. update: Update the content area of a component. Unlike our configuration options, methods can only be used once the component is created. This means we also need to understand how to get the component itself before we can begin using the methods. This is where the Ext class comes into play. The Ext object and Ext.getCmp() The Ext object is created, by default, when the Sencha Touch library is loaded. This object has methods that are used to create our initial application and its components. It also allows us to talk to our other components after they have been created. For example, let's take a look at a code example: new Ext.Application({ name: 'TouchStart', launch: function() { var hello = new Ext.Container({ fullscreen: true, html: '<div id="hello">Hello World</div>', id: 'helloContainer' }); this.viewport = hello;}}); The configuration option, id: 'helloContainer' will allow us to grab the container, later on, using our Ext class and the method getCmp(). For example, we can add the following code after this.viewport = hello;: var myContainer = Ext.getCmp('helloContainer');myContainer.update('Hello Again!'); By using Ext.getCmp, we get back the component with an id value of helloContainer, which we then set to our variable myContainer. Using this method returns an actual component, in this case a container. Since we get this object back as a container component, we can use any of the methods that the container understands. For our example, we used the update() method to change the content of the container to 'Hello Again!'. Typically, these types of changes will be generated by a button click and not in the launch function. This example simply shows that we can manipulate the component on the fly even after it gets created. The ID configuration It's a good idea to include an id configuration in all of your components. This makes it possible to use Ext.getCmp() to get to those components, later on, when we need them. Remember to keep the ID of every component unique. If you plan on creating multiple copies of a component, you will need to make sure that a unique ID is generated for each copy. The Ext.getCmp() method is great for grabbing Sencha Touch components and manipulating them.   Layouts revisited Layouts are another area we need to expand upon. When you start creating your own applications, you will need a firm understanding of how the different layouts affect what you see on the screen. To this end, we are going to start out with a demonstration application that shows how the different layouts work. For the purposes of this demo application, we will create the different components, one at a time, as individual variables. This is done for the sake of readability and should not be considered the best programming style. Remember that any items created this way will take up memory, even if the user never views the component. var myPanel = new Ext.Panel({ ... It is always a much better practice to create your components, using xtype attibutes, within your main container: items: [{ xtype: 'panel', ... This allows Sencha Touch to render the components as they are needed, instead of all at once when the page loads. The card layout To begin with, we will create a simple card layout: new Ext.Application({ name: 'TouchStart', launch: function() { var layoutPanel = new Ext.Panel({ fullscreen: true, layout: 'card', id: 'layoutPanel', cardSwitchAnimation: 'slide', items: [hboxTest] }); this.viewport = layoutPanel; }}); This sets up a single panel with a card layout. The card layout arranges its items similar to a stack of cards. Only one of these cards is active and displayed at a time. The card layout keeps any additional cards in the background and only creates them when the panel receives the setActiveItem() command. Each item in the list can be activated by using setActiveItem() and the item number. This can be a bit confusing, as the numbering of the items is zero-indexed, meaning that you start counting at zero and not one. For example, if you want to activate the fourth item in the list, you would use: layoutPanel.setActiveItem(3); In this case, we are starting out with only a single card/item called hboxTest. We need to add this container to make our program run. The hbox layout Above the line that says var layoutPanel = new Ext.Panel({, in the preceding code, add the following code: var hboxTest = new Ext.Container({ layout: { type: 'hbox', align: 'stretch' }, items: [{ xtype: 'container', flex: 1, html: 'My flex is 1', margin: 5, style: 'background-color: #7FADCF' }, { xtype: 'container', flex: 2, html: 'My flex is 2', margin: 5, style: 'background-color: #7FADCF' }, { xtype: 'container', width: 80, html: 'My width is 80', margin: 5, style: 'background-color: #7FADCF' }]}); This gives us a container with an hbox layout and three child items. Child and parent In Sencha Touch, we often find ourselves dealing with very large arrays of items, nested in containers that are in turn nested in other containers. It is often helpful to refer to a container as a parent to any items it contains. These items are then referred to as the children of the container. The hbox layout stacks its items horizontally and uses the width and flex values to determine how much horizontal space each of its child items will take up. The align: 'stretch' configuration causes the items to stretch to fill all of the available vertical space. If we run the code now, we should see this: You should try adjusting the flex and width values to see how it affects the size of the child containers. You can also change the available configuration options for align (center, end, start, and stretch), to see the different options available. Once you are finished, let's move on and add some more items to our card layout.  
Read more
  • 0
  • 0
  • 3236

article-image-various-components-sencha-touch
Packt
16 Feb 2012
8 min read
Save for later

The Various Components in Sencha Touch

Packt
16 Feb 2012
8 min read
  (For more resources on this topic, see here.) The reader can benefit from the previous article on Sencha Touch: Layouts Revisited. The TabPanel and Carousel components In our last application, we used buttons and a card layout to create an application that switched between different child items. While it is often desirable for your application to do this programmatically (with your own buttons and code), you can also choose to have Sencha Touch set this up automatically, using TabPanel or Carousel. TabPanel TabPanel is useful when you have a number of views the user needs to switch between, such as, contacts, tasks, and settings. The TabPanel component autogenerates the navigation for the layout, which makes it very useful as the main container for an application. The following is a code example: new Ext.Application({ name: 'TouchStart', launch: function() { this.viewport = new Ext.TabPanel({ fullscreen: true, cardSwitchAnimation: 'slide', tabBar:{ dock: 'bottom', layout: { pack: 'center' } }, items: [{ xtype: 'container', title: 'Item 1', fullscreen: false, html: 'TouchStart container 1', iconCls: 'info' }, { xtype: 'container', html: 'TouchStart container 2', iconCls: 'home', title: 'Item 2' }, { xtype: 'container', html: 'TouchStart container 3', iconCls: 'favorites', title: 'Item 3' }] }); }}); TabPanel, in this code, automatically generates a card layout; you don't have to declare a layout. You do need to declare a configuration for the tabBar component. This is where your tabs will automatically appear. In our previous code example, we dock the toolbar at the bottom. This will generate a large square button for each child item in the items list. The button will also use the iconCls value to assign an icon to the button. The title configuration is used to name the button. If you dock the tabBar component at the top, it makes the buttons small and round. It also eliminates the icons, even if you declare a value for iconCls, in your child items. Only the title configuration is used when the bar is docked at the top. Carousel The Carousel component is similar to TabPanel, but the navigation it generates is more appropriate for things such as slide shows. It probably would not work as well as a main interface for your application, but it does work well as a way to display multiple items in a single swipeable container. Similar to TabPanel, Carousel gathers its child items and automatically arranges them in a card layout. In fact, we can actually make just some simple modifications to our previous code to make it into a Carousel: new Ext.Application({ name: 'TouchStart', launch: function() { this.viewport = new Ext.Carousel({ fullscreen: true, direction: 'horizontal', items: [{ html: 'TouchStart container 1' }, { html: 'TouchStart container 2' }, { html: 'TouchStart container 3' }] }); }}); The first thing we did was create a new Ext.Carousel class instead of a new Ext.TabPanel class. We also added a configuration for direction, which can be either horizontal (scrolling from left to right) or vertical (scrolling up or down). We removed the docked toolbar, because, as we will see, Carousel doesn't use one. We also removed iconClass and title from each of our child items for the same reason. Finally, we removed the xtype configuration, since the Carousel automatically creates a panel for each of its items. Unlike TabPanel, Carousel has no buttons, only a series of dots at the bottom, with one dot for each child item. While it is possible to navigate using the dots, the Carousel component automatically sets itself up to respond to a swipe on a touch screen. You can duplicate this gesture in the browser by clicking and holding with the mouse, while moving it horizontally. If you declare a direction: vertical configuration in your Carousel, you can swipe vertically, to move between the child items. TabPanel and the Carousel components understand the activeItem configuration. This lets you set which item appears when the application first loads. Additionally, they all understand the setActiveItem() method that allows you to change the selected child item after the application loads. Carousel also has methods for next() and previous(), which allow you to step through the items in order. It should also be noted that, since TabPanel and Carousel both inherit from the panel, they also understand any methods and configurations that panels and containers understand. Along with containers and panels, TabPanel and Carousel will serve as the main starting point for most of your applications. However, there is another type of panel you will likely want to use at some point: the FormPanel.   FormPanel The FormPanel panel is a very specialized version of the panel, and as the name implies, it is designed to handle form elements. Unlike panels and containers, you don't need to specify the layout for FormPanel. It automatically uses its own special form layout. A basic example of creating a FormPanel would look something like this: var form = new Ext.form.FormPanel({ items: [ { xtype: 'textfield', name : 'first', label: 'First name' }, { xtype: 'textfield', name : 'last', label: 'Last name' }, { xtype: 'emailfield', name : 'email', label: 'Email' } ]}); For this example, we just create the panel and add items for each field in the form. Our xtype tells the form what type of field to create. We can add this to our Carousel and replace our first container, as follows: this.viewport = new Ext.Carousel({ fullscreen: true, direction: 'horizontal', items: [form, { layout: 'fit', html: 'TouchStart container 2' }, { layout: 'fit', html: 'TouchStart container 3' }]}); Anyone who has worked with forms in HTML should be familiar with all of the standard field types, so the following xtype attribute names will make sense to anyone who is used to standard HTML forms: checkboxfield fieldset hiddenfield passwordfield radiofield selectfield textfield textareafield These field types all match their HTML cousins, for the most part. Sencha Touch also offers a few specialized text fields that can assist with validating the user's input: emailfield - Accepts only a valid e-mail address, and on iOS devices, will pull up an alternate e-mail address and URL-friendly keyboard numberfield - Accepts only numbers urlfield - Accepts only a valid web URL, and also brings up the special keyboard These special fields will only submit if the input is valid. All of these basic form fields inherit from the main container class, so they have all of the standard height, width, cls, style, and other container configuration options. They also have a few field-specific options: label - A text label to use with the field labelAlign - Where the label appears; this can be top or left, and defaults to left labelWidth - How wide the label should be name - This corresponds to the HTML name attribute, which is how the value of the field will be submitted maxLength - How many characters can be used in the field required - If the field is required in order for the form to submit Form field placement While FormPanel is typically the container you will use when displaying form elements, you can also place them in any panel or toolbar, if desired. FormPanel has the advantage of understanding the submit() method that will post the form values via AJAX request or POST. If you include a form field in something that is not a FormPanel, you will need to get and set the values for the field using your own custom JavaScript method. In addition to the standard HTML fields, there are a few specialty fields available in Sencha Touch. These include the datepicker, slider, spinner, and toggle fields. DatePicker datepickerfield places a clickable field in the form with a small triangle on the far right side. You can add a date picker to our form by adding the following code after the emailfield item: ,{ xtype: 'datepickerfield', name : 'date', label: 'Date'} When the user clicks the field, a DatePicker will appear, allowing the user to select a date by rotating the month, day, and year wheels, by swiping up or down. Sliders, spinners, and toggles Sliders allow for the selection of a single value from a specified numerical range. The sliderfield value displays a bar, with an indicator, that can be slid horizontally to select a value. This can be useful for setting volume, color values, and other ranged options. Like the slider, a spinner allows for the selection of a single value from a specified numerical range. The spinnerfield value displays a form field with a numerical value with + and - buttons on either side of the field. A toggle allows for a simple selection between one and zero (on and off) and displays a toggle-style button on the form. Add the following new components to the end of our list of items: ,{ xtype : 'sliderfield', label : 'Volume', value : 5, minValue: 0, maxValue: 10},{ xtype: 'togglefield', name : 'turbo', label: 'Turbo'},{xtype: 'spinnerfield',minValue: 0,maxValue: 100,incrementValue: 2,cycle: true} The following screenshot shows how the new components will look: Our sliderfield and spinnerfield have configuration options for minValue and maxValue. We also added an incrementValue attribute, to spinnerfield, that will cause it to move in increments of 2 whenever the + or - button is pressed.  
Read more
  • 0
  • 0
  • 3491

article-image-creating-simple-application-sencha-touch
Packt
15 Feb 2012
10 min read
Save for later

Creating a Simple Application in Sencha Touch

Packt
15 Feb 2012
10 min read
  (For more resources on this topic, see here.) Setting up your folder structure Before we get started, you need to be sure that you've set up your development environment properly. Root folder You will need to have the folders and files for your application located in the correct web server folder, on your local machine. On the Mac, this will be the Sites folder in your Home folder. On Windows, this will be C:xamphtdocs (assuming you installed xampp). Setting up your application folder Before we can start writing code, we have to perform some initial set up, copying in a few necessary resources and creating the basic structure of our application folder. This section will walk you through the basic setup for the Sencha Touch files, creating your style sheets folder, and creating the index.html file. Locate the Sencha Touch folder you downloaded. Create a folder in the root folder of your local web server. You may name it whatever you like. I have used the folder name TouchStart in this article. Create three empty sub folders called lib, app, and css in your TouchStart folder. Now, copy the resources and src folders, from the Sencha Touch folder you downloaded earlier, into the TouchStart/lib folder. Copy the following files from your Sencha Touch folder to your TouchStart/lib folder: sencha-touch.js sencha-touch-debug.js sencha-touch-debug-w-comments.js Create an empty file in the TouchStart/css folder called TouchStart.css. This is where we will put custom styles for our application. Create an empty index.html file in the main TouchStart folder. We will flesh this out in the next section. Icon files Both iOS and Android applications use image icon files for display. This creates pretty rounded launch buttons, found on most touch-style applications. If you are planning on sharing your application, you should also create PNG image files for the launch image and application icon. Generally, there are two launch images, one with a resolution of 320 x 460 px, for iPhones, and one at 768 x 1004 px, for iPads. The application icon should be 72 x 72 px. See Apple's iOS Human Interface Guidelines for specifics, at http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/IconsImages/IconsImages.html. When you're done, your folder structure should look as follows: Creating the HTML application file Using your favorite HTML editor, open the index.html file we created when we were setting up our application folder. This HTML file is where you specify links to the other files we will need in order to run our application. The following code sample shows how the HTML should look: <!DOCTYPE html><html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <title>TouchStart Application - My Sample App</title> <!-- Sencha Touch CSS --> <link rel="stylesheet" href="lib/resources/css/sencha-touch.css"type="text/css"> <!-- Sencha Touch JS --> <script type="text/javascript" src="lib/sencha-touch-debug.js"></script> <!-- Application JS --> <script type="text/javascript" src="app/TouchStart.js"></script> <!-- Custom CSS --> <link rel="stylesheet" href="css/TouchStart.css" type="text/css"> </head> <body></body></html> Comments In HTML, anything between <!-- and --> is a comment, and it will not be displayed in the browser. These comments are to tell you what is going on in the file. It's a very good idea to add comments into your own files, in case you need to come back later and make changes. Let's take a look at this HTML code piece-by-piece, to see what is going on in this file. The first five lines are just the basic set-up lines for a typical web page: <!DOCTYPE html><html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <title>TouchStart Application - My Sample App</title> With the exception of the last line containing the title, you should not need to change this code for any of your applications. The title line should contain the title of your application. In this case, TouchStart Application – Hello World is our title. The next few lines are where we begin loading the files to create our application, starting with the Sencha Touch files. The first file is the default CSS file for the Sencha Touch library—sencha-touch.css. <link rel="stylesheet" href="lib/resources/css/ext-touch.css"type="text/css"> CSS files CSS or Cascading Style Sheet files contain style information for the page, such as which items are bold or italic, which font sizes to use, and where items are positioned in the display. The Sencha Touch style library is very large and complex. It controls the default display of every single component in Sencha Touch. It should not be edited directly. The next file is the actual Sencha Touch JavaScript library. During development and testing, we use the debug version of the Sencha Touch library, sencha-touchdebug.js: <script type="text/javascript" src="lib/sencha-touch-debug.js"></script> The debug version of the library is not compressed and contains comments and documentation. This can be helpful if an error occurs, as it allows you to see exactly where in the library the error occurred. When you have completed your development and testing, you should edit this line to use sencha-touch.js instead. This alternate file is the version of the library that is optimized for production environments and takes less bandwidth and memory to use; but, it has no comments and is very hard to read. Neither the sencha-touch-debug.js nor the sencha-touch.js files should ever be edited directly. The next two lines are where we begin to include our own application files. The names of these files are totally arbitrary, as long as they match the name of the files you create later, in the next section of this chapter. It's usually a good idea to name the file the same as your application name, but that is entirely up to you. In this case, our files are named TouchStart.js and TouchStart.css. <script type="text/javascript" src="app/TouchStart.js"></script> This first file, TouchStart.js, is the file that will contain our JavaScript application code. The last file we need to include is our own custom CSS file, called TouchStart.css. This file will contain any style information we need for our application. It can also be used to override some of the existing Sencha Touch CSS styles. <link rel="stylesheet" href="resources/css/TouchStart.css"type="text/css"> This closes out the </head> area of the index.html file. The rest of the index.html file contains the <body></body> tags and the closing </html> tag. If you have any experience with traditional web pages, it may seem a bit odd to have empty <body></body> tags, in this fashion. In a traditional web page, this is where all the information for display would normally go. For our Sencha Touch application, the JavaScript we create will populate this area automatically. No further content is needed in the index.html file, and all of our code will live in our TouchStart.js file. So, without further delay, let's write some code!   Starting from scratch with TouchStart.js Let's start by opening the TouchStart.js file and adding the following: new Ext.Application({name: 'TouchStart',launch: function() {var hello = new Ext.Container({fullscreen: true,html: '<div id="hello">Hello World</div>' });this.viewport = hello; }}); This is probably the most basic application you can possibly create: the ubiquitous "Hello World" application. Once you have saved the code, use the Safari web browser to navigate to the TouchStart folder in the root folder of your local web server. The address should look like the following: http://localhost/TouchStart/, on the PC http://127.0.0.1/~username/TouchStart, on the Mac (username should be replaced with the username for your Mac) As you can see, all that this bit of code does is create a single window with the words Hello World. However, there are a few important elements to note in this example. The first line, NewExt.Application({, creates a new application for Sencha Touch. Everything listed between the curly braces is a configuration option of this new application. While there are a number of configuration options for an application, most consist of at least the application's name and a launch function. Namespace One of the biggest problems with using someone else's code is the issue of naming. For example, if the framework you are using has an object called "Application", and you create your own object called "Application", the two functions will conflict. JavaScript uses the concept of namespaces to keep these conflicts from happening. In this case, Sencha Touch uses the namespace Ext. It is simply a way to eliminate potential conflicts between the frameworks' objects and code, and your own objects and code. Sencha will automatically set up a namespace for your own code as part of the new Ext.Application object. Ext is also part of the name of Sencha's web application framework called ExtJS. Sencha Touch uses the same namespace convention to allow developers familiar with one library to easily understand the other. When we create a new application, we need to pass it some configuration options. This will tell the application how to look and what to do. These configuration options are contained within the curly braces ({}) and separated by commas. The first option is as follows: name: 'TouchStart' The launch configuration option is actually a function that will tell the application what to do once it starts up. Let's start backwards on this last bit of code for the launch configuration and explain this.viewport. By default, a new application has a viewport. The viewport is a pseudo-container for your application. It's where you will add everything else for your application. Typically, this viewport will be set to a particular kind of container object. At the beginning of the launch function, we start out by creating a basic container, which we call hello: launch: function() {var hello = new Ext.Container({fullscreen: true,html: '<div id="hello">Hello World</div>' });this.viewport = hello; } Like the Application class, a new Ext.Container class is passed a configuration object consisting of a set of configuration options, contained within the curly braces ({}) and separated by commas. The Container object has over 40 different configuration options, but for this simple example, we only use two: fullscreen sets the size of the container to fill the entire screen (no matter which device is being used). html sets the content of the container itself. As the name implies, this can be a string containing either HTML or plain text. Admittedly, this is a very basic application, without much in the way of style. Let's add something extra using the container's layout configuration option. My application didn't work! When you are writing code, it is an absolute certainty that you will, at some point, encounter errors. Even a simple error can cause your application to behave in a number of interesting and aggravating ways. When this happens, it is important to keep in mind the following: Don't Panic. Retrace your steps and use the tools to track down the error and fix it.  
Read more
  • 0
  • 0
  • 4252
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-creating-compiling-and-deploying-native-projects-android-ndk
Packt
13 Feb 2012
13 min read
Save for later

Creating, Compiling, and Deploying Native Projects from the Android NDK

Packt
13 Feb 2012
13 min read
(For more resources on Android, see here.) Compiling and deploying NDK sample applications I guess you cannot wait anymore to test your new development environment. So why not compile and deploy elementary samples provided by the Android NDK first to see it in action? To get started, I propose to run HelloJni, a sample application which retrieves a character string defined inside a native C library into a Java activity (an activity in Android being more or less equivalent to an application screen). Time for action – compiling and deploying hellojni sample Let's compile and deploy HelloJni project from command line using Ant: Open a command-line prompt (or Cygwin prompt on Windows). Go to hello-jni sample directory inside the Android NDK. All the following steps have to performed from this directory: $ cd $ANDROID_NDK/samples/hello-jni Create Ant build file and all related configuration files automatically using android command (android.bat on Windows). These files describe how to compile and package an Android application: android update project –p . (Move the mouse over the image to enlarge.) Build libhello-jni native library with ndk-build, which is a wrapper Bash script around Make. Command ndk-build sets up the compilation toolchain for native C/ C++ code and calls automatically GCC version featured with the NDK. $ ndk-build Make sure your Android development device or emulator is connected and running. Compile, package, and install the final HelloJni APK (an Android application package). All these steps can be performed in one command, thanks to Ant build automation tool. Among other things, Ant runs javac to compile Java code, AAPT to package the application with its resources, and finally ADB to deploy it on the development device. Following is only a partial extract of the output: $ ant install The result should look like the following extract: Launch a shell session using adb (or adb.exe on Windows). ADB shell is similar to shells that can be found on the Linux systems: $ adb shell From this shell, launch HelloJni application on your device or emulator. To do so, use am, the Android Activity Manager. Command am allows to start Android activities, services or sending intents (that is, inter-activity messages) from command line. Command parameters come from the Android manifest: # am start -a android.intent.action.MAIN -n com.example.hellojni/com.example.hellojni.HelloJni Finally, look at your development device. HelloJni appears on the screen! What just happened? We have compiled, packaged, and deployed an official NDK sample application with Ant and SDK command-line tools. We will explore them more in later part. We have also compiled our first native C library (also called module) using the ndk-build command. This library simply returns a character string to the Java part of the application on request. Both sides of the application, the native and the Java one, communicate through Java Native Interface. JNI is a standard framework that allows Java code to explicitly call native C/C++ code with a dedicated API. Finally, we have launched HelloJni on our device from an Android shell (adb shell) with the am Activity Manager command. Command parameters passed in step 8 come from the Android manifest: com.example.hellojni is the package name and com.example.hellojni. HelloJni is the main Activity class name concatenated to the main package. <?xml version="1.0" encoding="utf-8"?><manifest package="com.example.hellojni" HIGHLIGHT android_versionCode="1" android_versionName="1.0">... <activity android_name=".HelloJni" HIGHLIGHT android_label="@string/app_name">... Automated build Because Android SDK, NDK, and their open source bricks are not bound to Eclipse or any specific IDE, creating an automated build chain or setting up a continuous integration server becomes possible. A simple bash script with Ant is enough to make it work! HelloJni sample is a little bit... let's say rustic! So what about trying something fancier? Android NDK provides a sample named San Angeles. San Angeles is a coding demo created in 2004 for the Assembly 2004 competition. It has been later ported to OpenGL ES and reused as a sample demonstration in several languages and systems, including Android. You can find more information by visiting one of the author's page: http://jet.ro/visuals/4k-intros/san-angeles-observation/. Have a go hero – compiling san angeles OpenGL demo To test this demo, you need to follow the same steps: Go to the San Angeles sample directory. Generate project files. Compile and install the final San Angeles application. Finally run it. As this application uses OpenGL ES 1, AVD emulation will work, but may be somewhat slow! You may encounter some errors while compiling the application with Ant: The reason is simple: in res/layout/ directory, main.xml file is defined. This file usually defines the main screen layout in Java application—displayed components and how they are organized. However, when Android 2.2 (API Level 8) was released, the layout_width and layout_height enumerations, which describe the way UI components should be sized, were modified: FILL_PARENT became MATCH_PARENT. But San Angeles uses API Level 4. There are basically two ways to overcome this problem. The first one is selecting the right Android version as the target. To do so, specify the target when creating Ant project files: $ android update project –p . -–target android-8 This way, build target is set to API Level 8 and MATCH_PARENT is recognized. You can also change the build target manually by editing default.properties at the project root and replacing: target=android-4 with the following line: target=android-8 The second way is more straightforward: erase the main.xml file! Indeed, this file is in fact not used by San Angeles demo, as only an OpenGL screen created programmatically is displayed, without any UI components. Target right! When compiling an Android application, always check carefully if you are using the right target platform, as some features are added or updated between Android versions. A target can also dramatically change your audience wideness because of the multiple versions of Android in the wild... Indeed, targets are moving a lot and fast on Android!. All these efforts are not in vain: it is just a pleasure to see this old-school 3D environment full of flat-shaded polygons running for the first time. So just stop reading and run it! Exploring android SDK tools Android SDK includes tools which are quite useful for developers and integrators. We have already overlooked some of them including the Android Debug Bridge and android command. Let's explore them deeper.   Android debug bridge You may have not noticed it specifically since the beginning but it has always been there, over your shoulder. The Android Debug Bridge is a multifaceted tool used as an intermediary between development environment and emulators/devices. More specifically, ADB is: A background process running on emulators and devices to receive orders or requests from an external computer. A background server on your development computer communicating with connected devices and emulators. When listing devices, ADB server is involved. When debugging, ADB server is involved. When any communication with a device happens, ADB server is involved! A client running on your development computer and communicating with devices through ADB server. That is what we have done to launch HelloJni: we got connected to our device using adb shell before issuing the required commands. ADB shell is a real Linux shell embedded in ADB client. Although not all standard commands are available, classical commands, such as ls, cd, pwd, cat, chmod, ps, and so on are executable. A few specific commands are also provided such as: logcat To display device log messages dumpsys To dump system state dmesg To dump kernel messages ADB shell is a real Swiss Army knife. It also allows manipulating your device in a flexible way, especially with root access. For example, it becomes possible to observe applications deployed in their "sandbox" (see directory /data/data) or to a list and kill currently running processes. ADB also offers other interesting options; some of them are as follows: pull <device path> <local path> To transfer a file to your computer push <local path> <device path> To transfer a file to your device or emulator install <application package> To install an application package install -r <package to reinstall> To reinstall an application, if already deployed devices To list all Android devices currently connected, including emulators reboot To restart an Android device programmatically wait-for-device To sleep, until a device or emulator is connected to your computer (for example,. in a script) start-server To launch the ADB server communicating with devices and emulators kill-server To terminate the ADB server bugreport To print the whole device state (like dumpsys) help To get an exhaustive help with all options and flags available To ease the writing of issued command, ADB provides facultative flags to specify before options: -s <device id> To target a specific device -d To target current physical device, if only one is connected (or an error message is raised) -e To target currently running emulator, if only one is connected (or an error message is raised) ADB client and its shell can be used for advanced manipulation on the system, but most of the time, it will not be necessary. ADB itself is generally used transparently. In addition, without root access to your phone, possible actions are limited. For more information, see http://developer.android.com/guide/developing/tools/adb.html. Root or not root. If you know the Android ecosystem a bit, you may have heard about rooted phones and non-rooted phones. Rooting a phone means getting root access to it, either "officially" while using development phones or using hacks with an end user phone. The main interest is to upgrade your system before the manufacturer provides updates (if any!) or to use a custom version (optimized or modified, for example, CyanogenMod). You can also do any possible (especially dangerous) manipulations that an Administrator can do (for example, deploying a custom kernel). Rooting is not an illegal operation, as you are modifying YOUR device. But not all manufacturers appreciate this practice and usually void the warranty. Have a go hero – transferring a file to SD card from command line Using the information provided, you should be able to connect to your phone like in the good old days of computers (I mean a few years ago!) and execute some basic manipulation using a shell prompt. I propose you to transfer a resource file by hand, like a music clip or a resource that you will be reading from a future program of yours. To do so, you need to open a command-line prompt and perform the following steps: Check if your device is available using adb from command line. Connect to your device using the Android Debug Bridge shell prompt. Check the content of your SD card using standard Unix ls command. Please note that ls on Android has a specific behavior as it differentiates ls mydir from ls mydir/, when mydir is a symbolic link. Create a new directory on your SD card using the classic command mkdir . Finally, transfer your file by issuing the appropriate adb command. Project configuration tool The command named android is the main entry point when manipulating not only projects but also AVDs and SDK updates. There are few options available, which are as follows: create project: This option is used to create a new Android project through command line. A few additional options must be specified to allow proper generation: -p The project path -n The project name -t The Android API target -k The Java package, which contains application's main class -a The application's main class name (Activity in Android terms) For example: $ android create project –p ./MyProjectDir –n MyProject –t android-8 –k com.mypackage –a MyActivity update project: This is what we use to create Ant project files from an existing source. It can also be used to upgrade an existing project to a new version. Main parameters are as follows: -p The project path -n To change the project name -l To include an Android library project (that is, reusable code). The path must be relative to the project directory). -t To change the Android API target There are also options to create library projects (create lib-project, update lib- project) and test projects (create test-project, update test-project). I will not go into details here as this is more related to the Java world. As for ADB, android command is your friend and can give you some help: $ android create project –help   Command android is a crucial tool to implement a continuous integration toolchain in order to compile, package, deploy, and test a project automatically entirely from command line. Have a go hero – towards continuous integration With adb, android, and ant commands, you have enough knowledge to build a minimal automatic compilation and deployment script to perform some continuous integration. I assume here that you have a versioning software available and you know how to use it. Subversion (also known as SVN) is a good candidate and can work in local (without a server). Perform the following operations: Create a new project by hand using android command. Then, create a Unix or Cygwin shell script and assign it the necessary execution rights (chmod command). All the following steps have to be scribbled in it. In the script, check out sources from your versioning system (for example, using a svn checkout command) on disk. If you do not have a versioning system, you can still copy your own project directory using Unix commands. Build the application using ant. Do not forget to check command results using $?. If the returned value is different from 0, it means an error occurred. Additionally, you can use grep or some custom tools to check potential error messages. If needed, you can deploy resources files using adb Install it on your device or on the emulator (which you can launch from the script) using ant as shown previously. You can even try to launch your application automatically and check Android logs (see logcat option in adb). Of course, your application needs to make use of logs! A free monkey to test your App! In order to automate UI testing on an Android application, an interesting utility that is provided with the Android SDK is MonkeyRunner, which can simulate user actions on a device to perform some automated UI testing. Have a look at http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html . To favor automation, a single Android shell statement can be executed from command-line as follows: adb shell ls /sdcard/   To execute a command on an Android device and retrieve its result back on your host shell, execute the following command: adb shell "ls / notexistingdir/ 1> /dev/null 2> &1; echo $?" Redirection is necessary to avoid polluting the standard output. The escape character before $? is required to avoid early interpretation by the host shell. Now you are fully prepared to automate your own build toolchain!
Read more
  • 0
  • 0
  • 10352

article-image-administrating-mysql-server
Packt
09 Feb 2012
10 min read
Save for later

Administrating the MySQL Server

Packt
09 Feb 2012
10 min read
(For more resources on MySQL, see here.) Managing users and their privileges The Privileges sub-page (visible only if we are logged in as a privileged user) contains dialogs to manage MySQL user accounts. It also contains dialogs to manage privileges on global, database, and table levels. This sub-page is hierarchical. When editing a user's privileges, we can see the global privileges as well as the database-specific privileges. Then, when viewing database-specific privileges for a user, we can view and edit this user's privileges for any table within this database. The user overview The first page displayed when we enter the Privileges sub-page is called User overview. This shows all user accounts and a summary of their global privileges, as shown in the following screenshot: (Move the mouse over the image to enlarge.) From this page, we can: Edit a user's privileges, via the Edit Privileges link for this user Export a user's privileges definition, via the Export link for this user Use the checkboxes to remove users, via the Remove selected users dialog Access the page where the Add a new User dialog is available The displayed users' list has columns with the following characteristics: Column Characteristic User The user account we are defining. Host The machine name or IP address, from which this user account will be connecting to the MySQL server. A % value here indicates all hosts. Password Contains Yes if a password is defined and No if it isn't. The password itself cannot be seen from phpMyAdmin's interface or by directly looking at the mysql.user table, as it is encrypted with a one-way hashing algorithm. Global privileges A list of the user's global privileges. Grant Contains Yes if the user can grant his/her privileges to others. Action Contains a link to edit this user's privileges or export them. Exporting privileges This feature can be useful when we need to create a user with the same password and privileges on another MySQL server. Clicking on Export for user marc produces the following panel: Then it's only a matter of selecting these GRANT statements and pasting them in the SQL box of another phpMyAdmin window, where we have logged in on another MySQL server. Privileges reload At the bottom of User overview page, this message is displayed: Note: phpMyAdmin gets the users' privileges directly from MySQL's privilege tables. The content of these tables may differ from the privileges the server uses, if they have been changed manually. In this case, you should reload the privileges before you continue. Here, the text reload the privileges is clickable. The effective privileges (the ones against which the server bases its access decisions) are the privileges that are located in the server's memory. Privilege modifications that are made from the User overview page are made both in memory and on disk in the mysql database. Modifications made directly to the mysql database do not have immediate effect. The reload the privileges operation reads the privileges from the database and makes them effective in memory. Adding a user The Add a new User link opens a dialog for user account creation. First, we see the panel where we will describe the account itself, as shown in the following screenshot: The second part of the Add a new User dialog is where we will specify the user's global privileges, which apply to the server as a whole (see the Assigning global privileges section of this article), as shown in the following screenshot: Entering the username The User name menu offers two choices. We can choose Use text field: and enter a username in the box, or we can choose Any user to create an anonymous user (the blank user). More details about the anonymous user are available at http://dev.mysql.com/doc/refman/5.5/en/connection-access.html. Let us choose Use text field: and enter bill. Assigning a host value By default, this menu is set to Any host, with % as the host value. The Local choice means localhost. The Use host table choice (which creates a blank value in the host field) means to look in the mysql.host table for database-specific privileges. Choosing Use text field: allows us to enter the exact host value we want. Let us choose Local. Setting passwords Even though it's possible to create a user without a password (by selecting the No password option), it's best to have a password. We have to enter it twice (as we cannot see what is entered) to confirm the intended password. A secure password should have more than eight characters, and should contain a mixture of uppercase and lowercase characters, digits, and special characters. Therefore, it's recommended to have phpMyAdmin generate a password—this is possible in JavaScript-enabled browsers. In the Generate password dialog, clicking on Generate button enters a random password (in clear text) on the screen and fills the Password and Re-type input fields with the generated password. At this point, we should note the password so that we can pass it on to the user. Understanding rights for database creation A frequent convention is to assign a user the rights to a database having the same name as this user. To accomplish this, the Database for user section offers the Create database with same name and grant all privileges radio button. Selecting this checkbox automates the process by creating both the database (if it does not already exist) and assigning the corresponding rights. Please note that, with this method, each user would be limited to one database (user bill, database bill). Another possibility is to allow users to create databases that have the same prefix as their usernames. Therefore, the other choice Grant all privileges on wildcard name (username_%) performs this function by assigning a wildcard privilege. With this in place, user bill could create the databases bill_test, bill_2, bill_payroll, and so on; phpMyAdmin does not pre-create the databases in this case. Assigning global privileges Global privileges determine the user's access to all databases. Hence, these are sometimes known as superuser privileges. A normal user should not have any of these privileges unless there is a good reason for this. Moreover, should a user account that has global privileges become compromised, the damage could be far greater. If we are really creating a superuser, we will select every global privilege that he or she needs. These privileges are further divided into Data, Structure, and Administration groups. In our example, bill will not have any global privileges. Limiting the resources used We can limit the resources used by this user on this server (for example, the maximum queries per hour). Zero means no limit. We will not impose any resources limits on bill. The following screenshot shows the status of the screen just before hitting Create user to create this user's definition (with the remaining fields being set to default): Editing a user profile The page used to edit a user's profile appears whenever we click on Edit Privileges for a user in the User overview page. Let us try it for our newly created user bill. There are four sections on this page, each with its own Go button. Hence, each section is operated independently and has a distinct purpose. Editing global privileges The section for editing the user's privileges has the same look as the Add a new User dialog, and is used to view and to change global privileges. Assigning database-specific privileges In this section, we define the databases to which our user has access, and his or her exact privileges on these databases. As shown in the previous screenshot, we see None because we haven't defined any privileges yet. There are two ways of defining database privileges. First, we can choose one of the existing databases from the drop-down menu as shown in the following screenshot: This assigns privileges only for the chosen database. Secondly, we can also choose Use text field: and enter a database name. We could enter a non-existent database name, so that the user can create it later (provided we give him/her the CREATE privilege in the next panel). We can also use special characters, such as the underscore and the percent sign, for wildcards. For example, entering bill here would enable him to create a bill database, and entering bill% would enable him to create a database with any name that starts with bill. For our example, we will enter bill and click on Go. The next screen is used to set bill's privileges on the bill database, and create table-specific privileges. To learn more about the meaning of a specific privilege, we can hover the mouse over a privilege name (which is always in English), and an explanation about this privilege appears in the current language. We give SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, and DROP privileges to bill on this database. We then click on Go. After the privileges have been assigned, the interface stays at the same place, so that we can refine these privileges further. We cannot assign table-specific privileges for the moment, as the database does not yet exist. To go back to the general privileges page of bill, click on the 'bill'@'localhost' title. This brings us back to the following, familiar page except for a change in one section: We see the existing privileges (we could click on Edit Privileges link to edit or on Revoke link to revoke them) on the bill database for user bill, and we can add privileges for bill on another database. We can also see that bill has no table-specific privilege on the bill database. Changing the password The Change password dialog is part of the Edit user page, and we can use it either to change bill's password or to remove it. Removing the password will enable bill to log in without a password. The dialog offers a choice of password hashing options, and it's recommended to keep the default of MySQL 4.1+ hashing. For more details about hashing, please visit http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html. Changing login information or copying a user This dialog can be used to change the user's login information, or to copy his or her login information to a new user. For example, suppose that Bill calls and tells us that he prefers the login name billy instead of bill. We just have to add a y to the username, and then select delete the old one from the user tables radio button, as shown in the following screenshot: After clicking on Go, bill no longer exists in the mysql database. Also, all of his privileges, including the privileges on the bill database, will have been transferred to the new user—billy. However, the user definition of bill will still exist in memory, and hence it's still effective. If we had chosen the delete the old one from the user tables and reload the privileges afterwards option instead, the user definition of bill would immediately have ceased to be valid. Alternatively, we could have created another user based on bill, by making use of the keep the old one choice. We can transfer the password to the new user by choosing Do not change the password option, or change it by entering a new password twice. The revoke all active privileges… option immediately terminates the effective current privileges for this user, even if he or she is currently logged in. Removing a user Removing a user is done from the User overview section of the Privileges page. We select the user to be removed. Then (in Remove selected users) we can select the Drop the databases that have the same names as the users option to remove any databases that are named after the users we are deleting. A click on Go effectively removes the selected users.
Read more
  • 0
  • 0
  • 2430

article-image-article-understanding-services
Packt
07 Feb 2012
23 min read
Save for later

Understanding Services in JBoss

Packt
07 Feb 2012
23 min read
(For more resources on topic_name, see here.) Preparing JBoss Developer Studio The examples in this article are based on a standard ESB application template that can be found under the Chapter3 directory within the sample downloads..We will modify this template application as we proceed through this chapter. Time for action – opening the Chapter3 app Follow these steps: Click on the File menu and select Import. Now choose Existing Projects into workspace and select the folder where the book samples have been extracted: Then click on Finish. Now have a look at the jboss-esb.xml file. You can see that it has a single service and action as defined in the following snippet: <jbossesb parameterReloadSecs="5" xsi_schemaLocation="http://anonsvn.labs.jboss.com/labs/ jbossesb/trunk/product/etc/schemas/xml/ jbossesb-1.3.0.xsd http://anonsvn.jboss.org/repos/labs/ labs/jbossesb/trunk/product/etc/ schemas/xml/jbossesb-1.3.0.xsd"> <providers> <jms-provider connection-factory="ConnectionFactory" name="JBossMQ"> <jms-bus busid="chapter3GwChannel"> <jms-message-filter dest-name="queue/chapter3_Request_gw" dest-type="QUEUE"/> </jms-bus> <jms-bus busid="chapter3EsbChannel"> <jms-message-filter dest-name="queue/chapter3_Request_esb" dest-type="QUEUE"/> </jms-bus> </jms-provider> </providers> <services> <service category="Chapter3Sample" description="A template for Chapter3" name="Chapter3Service"> <listeners> <jms-listener busidref="chapter3GwChannel" is-gateway="true" name="Chapter3GwListener"/> <jms-listener busidref="chapter3EsbChannel" name="Chapter3Listener"/> </listeners> <actions mep="OneWay"> <action class="org.jboss.soa.esb.actions.SystemPrintln" name="PrintBefore"> <property name="message"/> <property name="printfull" value="true"/> </action> </actions> </service> </services></jbossesb> Examining the structure of ESB messages A service is an implementation of a piece of business logic which exposes a well defined service contract to consumers. The service will provide an abstract service contract which describes the functionality exposed by the service and will exhibit the following characteristics: Self contained: The implementation of the service is independent from the context of the consumers; any implementation changes will have no impact. Loosely coupled: The consumer invokes the service indirectly, passing messages through the bus to the service endpoint. There is no direct connection between the service and its consumers. Reusable: The service can be invoked by any consumer requiring the functionality exposed by the service. The provider is tied to neither a particular application nor process. Services which adhere to these criteria will be capable of evolving and scaling without affecting any consumers of that service. The consumer no longer cares which implementation of the service is being invoked, nor where it is located, provided that the exposed service contract remains compatible. Examining the message The structure of the message, and how it can be manipulated, plays an important part in any ESB application as a result of the message driven nature of the communication between service providers and consumers. The message is the envelope which contains all of the information relevant to a specific invocation of a service. All messages within JBoss ESB are implementations of the org.jboss.soa.esb.message. Message interface, the major aspects of which are: Header: Information concerning the identity, routing addresses, and correlation of the message Context: Contextual information pertaining to the delivery of each message, such as the security context Body: The payload and additional details as required by the service contract Attachment: Additional information that may be referenced from within the payload Properties: Information relating to the specific delivery of a message, usually transport specific (for example the original JMS queue name) Time for action – printing the message structure Let us execute the Chapter3 sample application that was opened up at the beginning of this chapter. Follow these steps: In JBoss Developer Studio, click Run and select Run As and Run on Server. Alternatively you can press Alt + Shift + X, followed by R. You can see the server runtime has been pre-selected. Choosing the Always use this server when running this project check box will always use this runtime and this dialog will not appear again. Click Next. A window with the project pre-configured to run on this server is shown. Ensure that we have only our project Chapter3 selected to the right hand side. Click Finish. The server runtime will be started up (if not already started) and the ESB file will be deployed to the server runtime. Select the src folder, expand it till the SendJMSMessage.java file is displayed in the tree. Now click Run, select Run As and Java Application. The entire ESB message contents will be printed in the console as follows: INFO [STDOUT] Message structure: INFO [STDOUT] [ message: [ JBOSS_XML ]header: [ To: JMSEpr [ PortReference < <wsa:Address jms:localhost:1099#queue/chapter3_Request_esb/>, <wsa:ReferenceProperties jbossesb:java.naming.factory.initial : org.jnp.interfaces.NamingContextFactory/>, <wsa:ReferenceProperties jbossesb:java.naming.provider.url : localhost:1099/>, <wsa:ReferenceProperties jbossesb:java.naming.factory.url.pkgs : org.jnp.interfaces/>, <wsa:ReferenceProperties jbossesb:destination-type : queue/>, <wsa:ReferenceProperties jbossesb:destination-name : queue/chapter3_Request_esb/>, <wsa:ReferenceProperties jbossesb:specification-version : 1.1/>, <wsa:ReferenceProperties jbossesb:connection-factory : ConnectionFactory/>, <wsa:ReferenceProperties jbossesb:persistent : true/>, <wsa:ReferenceProperties jbossesb:acknowledge-mode : AUTO_ACKNOWLEDGE/>, <wsa:ReferenceProperties jbossesb:transacted : false/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/jms/> > ] MessageID: e694a6a5-6a30-45bf-8f6d-f48363219ccf RelatesTo: jms:correlationID#e694a6a5-6a30-45bf-8f6d-f48363219ccf ]context: {}body: [ objects: {org.jboss.soa.esb.message.defaultEntry=Chapter 3 says Hello!} ]fault: [ ]attachments: [ Named:{}, Unnamed:[] ]properties: [ {org.jboss.soa.esb.message.transport.type=Deferred serialized value: 12d16a5, org.jboss.soa.esb.message.byte.size=2757, javax.jms.message.redelivered=false, org.jboss.soa.esb.gateway.original.queue.name=Deferred serialized value: 129bebb, org.jboss.soa.esb.message.source=Deferred serialized value: 1a8e795} ] ] What just happened? You have just created a Chapter3.esb file and deployed it to the ESB Runtime on the JBoss Application Server 5.1. You executed a gateway client that posted a string to the Bus. The server converted this message to an ESB message and the complete structure was printed out. Take a moment to examine the output and understand the various parts of the ESB message. Have a go hero – deploying applications Step 1 through step 4 describe how to start the server and deploy our application from within JBoss Developer Studio. For the rest of this chapter, and throughout this book, you will be repeating these steps and will just be asked to deploy the application. Message implementations JBoss ESB provides two different implementations of the message interface, one which marshalls data into an XML format and a second which uses Java serialization to create a binary representation of the message. Both of these implementations will only handle Java serializable objects by default, however it is possible to extend the XML implementation to support additional object types. Message implementations are created indirectly through the org.jboss.soa.esb. message.format.MessageFactory class. In general any use of serializable objects can lead to a brittle application, one that is more tightly coupled between the message producer and consumer. The message implementations within JBoss ESB mitigate this by supporting a 'Just In Time' approach when accessing the data. Care must still be taken with what data is placed within the message, however serialization/marshalling of these objects will only occur as and when required. Extending the ESB to provide alternative message implementations, and extending the current XML implementation to support additional types, is outside the scope of this book. The body This is the section of the message which contains the main payload information for the message, adhering to the contract exposed by the service. The payload should only consist of the data required by the service contract and should not rely on any service implementation details as this will prevent the evolution or replacement of the service implementation at a future date. The types of data contained within the body are restricted only by the requirements imposed by the message implementation, in other words the implementation must be able to serialize or marshall the contents as part of service invocation. The body consists of Main payload: accessed using the following methods: public Object get() ;public void add(final Object value) ; Named objects: accessed using the following methods: public Object get(final String name) ;public void add(final String name, final Object value) ; Time for action – examining the main payload Let us create another action class that simply prints the message body. We will add this action to the sample application that was opened up at the beginning of this chapter. Right click on the src folder and choose New and select Class: Enter the Name as "MyAction", enter the Package as "org.jboss.soa. samples.chapter3", and select the Superclass as "org.jboss.soa.esb. actions.AbstractActionLifecycle": Click Finish. Add the following imports and the following body contents to the code: import org.jboss.soa.esb.helpers.ConfigTree;import org.jboss.soa.esb.message.Message; protected ConfigTree _config;public MyAction(ConfigTree config) { _config = config;}public Message displayMessage(Message message) throws Exception { System.out.println( "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); System.out.println("Body: " + message.getBody().get()); System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); return message;} Click Save. Open the jboss-esb.xml file in Tree mode, expand till Actions is displayed in the tree. Select Actions, click Add | Custom Action: Enter the Name as "BodyPrinter" and choose the "MyAction" class and "displayMessage" process method: Click Save and the application will be deployed. If the server was stopped then deploy it using the Run menu and select Run As | Run on Server: Once the application is deployed on the server, run SendJMSMessage.java by clicking Run | Run As | Java Application. The following can be seen displayed in the console output: 12:19:32,562 INFO [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&12:19:32,562 INFO [STDOUT] Body: Chapter 3 says Hello!12:19:32,562 INFO [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& What just happened? You have just created your own action class that used the Message API to get the main payload of the message and printed it to the console. Have a go hero – additional body contents Now add another miscellaneous SystemPrintln action after our BodyPrinter. Name it PrintAfter and make sure printfull is set to true. Modify the MyAction class and add additional named content using the getBody().add(name, object) method and see what gets printed on the console. Here is the actions section of the config file <actions mep="OneWay"> <action class="org.jboss.soa.esb.actions.SystemPrintln" name="PrintBefore"> <property name="message"/> <property name="printfull" value="true"/> </action> <action class="org.jboss.soa.esb.samples.chapter3.MyAction" name="BodyPrinter" process="displayMessage"/> <action class="org.jboss.soa.esb.actions.SystemPrintln" name="PrintAfter"> <property name="message"/> <property name="printfull" value="true"/> </action></actions> The following is the listing of the MyAction class's modified displayMessage method public Message displayMessage(Message message) throws Exception { System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); System.out.println("Body: " + message.getBody().get()); message.getBody().add("Something", "Unknown"); System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); return message;} The header The message header contains the information relating to the identity, routing, and the correlation of messages. This information is based on, and shares much in common with, the concepts defined in the W3C WS-Addressing specification. It is important to point out that many of these aspects are normally initialized automatically by other parts of the codebase; a solid understanding of these concepts will allow the developer to create composite services using more advanced topologies. Routing information Every time a message is sent within the ESB it contains information which describes who sent the message, which service it should be routed to, and where any replies/faults should be sent once processing is complete. The creation of this information is the responsibility of the invoker and, once delivered, any changes made to this information, from within the target service, will be ignored by that service. The information in the header takes the form of Endpoint References (EPRs) containing a representation of the service address, often transport specific, and extensions which can contain relevant contextual information for that endpoint. This information should be treated as opaque by all parties except the party which was responsible for creating it. There are four EPRs included in the header, they are as follows: To: This is the only mandatory EPR, representing the address of the service to which the message is being sent. This will be initialized by ServiceInvoker with the details of the service chosen to receive the message. From: This EPR represents the originator of the message, if present, and may be used as the address for responses if there is neither an explicit ReplyTo nor FaultTo set on the message. ReplyTo: This EPR represents the endpoint to which all responses will be sent, if present, and may be used as the address for faults if there is no explicit FaultTo set on the message. This will normally be initialized by ServiceInvoker if a synchronous response is expected by the service consumer. FaultTo: This EPR represents the endpoint to which all faults will be sent, if present. When thinking about the routing information it is important to view these details from the perspective of the service consumer, as the EPRs represent the wishes of the consumer and must be adhered to. If the service implementation involves more advanced topologies, like chaining and continuations, which we will discuss later in the chapter, then care must be taken to preserve these EPRs when messages are propagated to subsequent services. Message identity and correlation There are two parts of the header which are related to the identity of the message and its correlation with a preceding message. These are as follows: MessageID: A unique reference which can be used to identify the message as it progresses through the ESB. The reference is represented by a Uniform Resource Name (URN), a specialized Uniform Resource Identifier (URI) which will represent the identity of the message within a specific namespace. The creator of the message may choose to associate it with an identity which is specific to the application context within which it is being used, in which case the URN should refer to a namespace which is also application context specific. If no MessageID has been associated with the message then the ESB will assign a unique identifier when it is first sent to a service. RelatesTo: When sending a reply, this represents the unique reference of the message representing the request. This may be used to correlate the response message with the original request. Service action The action header is an optional, service-specific URN that may be used to further refine the processing of the message by a service provider or service consumer. The URN should refer to an application-specific namespace. There are no restrictions on how this header is to be used by the application including, if considered appropriate, ignoring its contents.   Time for action – examining the header Let us modify MyAction to display some of the header information that we need: Open MyAction and edit the displayMessage method as follows: public Message displayMessage(Message message) throws Exception { System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); System.out.println("From: " + message.getHeader().getCall().getFrom()); System.out.println("To: " + message.getHeader().getCall().getTo()); System.out.println("MessageID: " + message.getHeader().getCall().getMessageID()); System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); return message;} Remove the PrintBefore and PrintAfter actions if they exist. Make sure that we have only the BodyPrinter action: Click on Save. If the server was still running (and a small red button appears in the console window), then you might notice the application gets redeployed by default. If this did not happen then deploy the application using the Run menu and select Run As | Run on Server. The following output will be displayed in the console: INFO [EsbDeployment] Stopping 'Chapter3.esb'INFO [EsbDeployment] Destroying 'Chapter3.esb'WARN [ServiceMessageCounterLifecycleResource] Calling cleanup on existing service message counters for identity ID-7INFO [QueueService] Queue[/queue/chapter3_Request_gw] stoppedINFO [QueueService] Queue[/queue/chapter3_Request_esb] stoppedINFO [QueueService] Queue[/queue/chapter3_Request_esb] started, fullSize=200000, pageSize=2000, downCacheSize=2000INFO [QueueService] Queue[/queue/chapter3_Request_gw] started, fullSize=200000, pageSize=2000, downCacheSize=2000INFO [EsbDeployment] Starting ESB Deployment 'Chapter3.esb' Run SendJMSMessage.java by clicking Run | Run As | Java Application. The following messages will be printed in the console INFO [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&INFO [STDOUT] From: nullINFO [STDOUT] To: JMSEpr [ PortReference < <wsa:Address jms:localhost:1099#queue/chapter3_Request_esb/>, <wsa:ReferenceProperties jbossesb:java.naming.factory.initial : org.jnp.interfaces.NamingContextFactory/>, <wsa:ReferenceProperties jbossesb:java.naming.provider.url : localhost:1099/>, <wsa:ReferenceProperties jbossesb:java.naming.factory.url.pkgs : org.jnp.interfaces/>, <wsa:ReferenceProperties jbossesb:destination-type : queue/>, <wsa:ReferenceProperties jbossesb:destination-name : queue/chapter3_Request_esb/>, <wsa:ReferenceProperties jbossesb:specification-version : 1.1/>, <wsa:ReferenceProperties jbossesb:connection-factory : ConnectionFactory/>, <wsa:ReferenceProperties jbossesb:persistent : true/>, <wsa:ReferenceProperties jbossesb:acknowledge-mode : AUTO_ACKNOWLEDGE/>, <wsa:ReferenceProperties jbossesb:transacted : false/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/jms/> > ]INFO [STDOUT] MessageID: 46e57744-d0ac-4f01-ad78-b1f15a3335d1INFO [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& What just happened? We examined some of the header contents through the API. We printed the From, To, and the MessageID from within our MyAction class. Have a go hero – additional header contents Now modify the MyAction class to print the Action, ReplyTo, RelatesTo, and FaultTo contents of the header to the console. Here is the listing of the modified MyAction class's method: public Message displayMessage(Message message) throws Exception { System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); System.out.println("From: " + message.getHeader().getCall().getFrom()); System.out.println("To: " + message.getHeader().getCall().getTo()); System.out.println("MessageID: " + message.getHeader().getCall().getMessageID()); System.out.println("Action: " + message.getHeader().getCall().getAction()); System.out.println("FaultTo: " + message.getHeader().getCall().getFaultTo()); System.out.println("RelatesTo: " + message.getHeader().getCall().getRelatesTo()); System.out.println("ReplyTo: " + message.getHeader().getCall().getReplyTo()); System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); return message;} The context The message context is used to transport the active contextual information when the message is sent to the target service. This may include information such as the current security context, transactional information, or even context specific to the application. This contextual information is not considered to be part of the service contract and is assumed to change between successive message deliveries. Where the message context really becomes important is when a service pipeline is invoked through an InVM transport, as this can allow the message to be passed by reference. When the transport passes the message to the target service it will create a copy of the message header and message context, allowing each to be updated in subsequent actions without affecting the invoked service. Have a go hero – printing message context Modify the MyAction class to print the context of the ESB message; obtain the context through the getContext() method. You will notice that the context is empty for our sample application as we currently have no security or transactional context attached to the message. Message validation The message format within JBoss ESB allows the consumer and producer to use any payload that suits the purpose of the service contract. No constraints are placed on this payload other than the fact that it must be possible to marshall the payload contents so that the messages can be transported between the consumer and producer. While this ability is useful for creating composite services, it can be a disadvantage when you need to design services that have an abstract contract, hide the details of the implementation, are loosely coupled, and can easily be reused. In order to encourage the loose coupling of services it is often advantageous to choose a payload that does not dictate implementation, for example XML. JBoss ESB provides support for enforcing the structure of XML payloads for request and response messages, through the XML schema language as defined through the W3C. An XML Schema Document (XSD) is an abstract, structural definition which can be used to formally describe an XML message and guarantee that a specific payload matches that definition through a process called validation. Enabling validation on a service is simply a matter of providing the schema associated with the request and/or response messages and specifying the validate attribute, as follows: <actions inXsd="/request.xsd" outXsd="/response.xsd" validate="true"> ...</actions> This will force the service pipeline to validate the request and response messages against the XSD files, if they are specified, with the request validation occurring before the first service action is executed and the response validation occurring immediately before the response message is sent to the consumer. If validation of the request or response message does fail then a MessageValidationException fault will be raised and sent to the consumer using the normal fault processing as defined in the MEPs and responses section. This exception can also be seen by enabling DEBUG logging through the mechanism supported by the server. Have a go hero – enabling validation Add a request.xsd or a response.xsd or both to your actions in the sample application provided. Enable validation and test the output. Configuring through the ConfigTree JBoss ESB handles the majority of its configuration through a hierarchical structure similar to the W3C DOM, namely, org.jboss.soa.esb.helpers.ConfigTree. Each node within the structure contains a name, a reference to the parent node, a set of named attributes, and references to all child nodes. This structure is used, directly and indirectly, within the implementation of the service pipeline and action processors, and will be required if you are intending to create your own action processors. The only exception to this is when using an annotated action class when the configuring of the action will be handled by the framework instead of programmatically. Configuring properties in the jboss-esb.xml file The ConfigTree instance passed to an action processor is a hierarchical representation of the properties as defined within the action definition of the jboss-esb.xml file. Each property defined within an action may be interpreted as a name/value pair or as hierarchical content to be parsed by the action. For example the following: <action ....> <!-- name/value property --> <property name="propertyName" value="propertyValue"/> <!-- Hierarchical property --><property name="propertyName"> <hierarchicalProperty attr="value"> <inner name="myName" random="randomValue"/> </hierarchicalProperty> </property></action> This will result in the following ConfigTree structure being passed to the action: Traversing the ConfigTree hierarchy Traversing the hierarchy is simply a matter of using the following methods to obtain access to the parent or child nodes: public ConfigTree getParent() ;public ConfigTree[] getAllChildren() ;public ConfigTree[] getChildren(String name) ;public ConfigTree getFirstChild(String name) ; Accessing attributes Attributes are usually accessed by querying the current ConfigTree instance for the value associated with the required name, using the following methods: public String getAttribute(String name) ;public String getAttribute(String name, String defaultValue) ;public long getLongAttribute(String name, long defaultValue) ;public float getFloatAttribute(String name, float defaultValue) ;public boolean getBooleanAttribute(String name, boolean defaultValue) ;public String getRequiredAttribute(String name) throws ConfigurationException ; It is also possible to obtain the number of attributes, names of all the attributes, or the set of key/value pairs using the following methods: public int attributeCount() ;public Set<String> getAttributeNames() ;public List<KeyValuePair> attributesAsList() ; Time for action – examining configuration properties Let us add some configuration properties to our MyAction. We will make the & and the number of times it needs to be printed as configurable properties. Follow these steps: Add two members to the MyAction class: public String SYMBOL = "&";public int COUNT = 48; Modify the constructor as follows: _config = config;String symbol = _config.getAttribute("symbol");if (symbol != null) { SYMBOL = symbol;}String count = _config.getAttribute("count");if (count != null) { COUNT = Integer.parseInt(count);} Add a printLine() method: private void printLine() { StringBuffer line = new StringBuffer(COUNT); for (int i = 0; i < COUNT; i++) { line.append(SYMBOL); } System.out.println(line);} Modify the printMessage() method as shown in the following snippet: printLine();System.out.println("Body: " + message.getBody().get());printLine();return message; Edit the jboss-esb.xml file and select the action, BodyPrinter. Add two properties symbol as * and count as 50: Click on Save or press Ctrl + S. Deploy the application using the Run menu and select Run As | Run on Server. Run SendJMSMessage.java by clicking Run, select Run As and Java Application. INFO [STDOUT] **************************************************INFO [STDOUT] Body: Chapter 3 says Hello!INFO [STDOUT] ************************************************** What just happened? You just added two properties to the MyAction class. You also retrieved these properties from the ConfigTree and used them. Have a go hero – additional header contents Experiment with the other API methods. Write hierarchicalProperty and see how that can be retrieved.
Read more
  • 0
  • 0
  • 1988

article-image-monitoring-and-responding-windows-intune-alerts
Packt
02 Feb 2012
5 min read
Save for later

Monitoring and Responding to Windows Intune Alerts

Packt
02 Feb 2012
5 min read
General Windows Intune alerts Windows Intune will raise an alert in a number of situations where we, as the administrators, need to either be aware of an event or respond directly to it. The alerts will appear in a number of the screens and reports in Windows Intune. Windows Intune has seven alert categories: Endpoint Protection Monitoring Notices Policy Remote Assistance System Updates Some of these alerts require special attention and have their own section, while others can be generically dealt with. The two areas that need some special attention are the Endpoint Protection alerts relating to malware and remote assistance, as the actions taken here always need to be decisive. We have also already tackled the update alerts in the previous chapter. Before we examine alerts in more detail, I thought I should share a quick, but obvious, note. The reporting of alerts from the client computer to Windows Intune requires an Internet connection from the client computer, so we are unlikely to see an alert saying that the user's PC is having network trouble. However, if a computer has not checked in with Windows Intune for a while, we will see an alert for this from Windows Intune, pointing to a machine that has not been turned on for a while, or with problems! It is more likely that a user will contact us via other means if they are having a networking problem, but we should remember to tell users to do that in that situation rather than them requesting remote assistance and wondering why we don't respond! Monitoring alerts There are two ways to monitor alerts once they have been enabled and the notification has been completed. The two choices are to either look at the console and refresh, or wait for notifications to arrive via e-mail. The e-mail notifications look similar to the one in the following screenshot. Clicking the link takes us to the Windows Intune console To view the alerts in the Windows Intune console, go to the Alerts workspace and go to All Alerts. We can choose which alerts are displayed by changing the Filters selection at the top of the screen. All the filters shown open alerts, except for the filter choice of Closed. The filter choice of None shows all open Critical, Warning, and Informational alerts We can also view alerts specific to the category by selecting one of the items below All Alerts selection tree. For example, in the Monitoring category, we can see one alert at the moment: Finally, we can view alerts that relate to a specific computer by looking at the Alerts tab in the Computers workspace Responding and closing alerts Once we have an alert to deal with, we need to respond in some way. By clicking on the alert, the details pane is displayed. Under the Recommended Actions, there will either be a link to Click here to take action or one to View Troubleshooting Information. If we click the information link, a window will open that, depending on the problem and potential solution, will show either a link to the Windows Intune help file or a link to carry out the action if appropriate. In the following example, the alert is for malware and a link to information on the specific malware that was seen. We can see that the following information does not show us a specific action for malware. We will discuss how to respond to malware a little later in this article Once we have resolved the alert, it needs to be closed to remove it from the console and to enable us to demonstrate that we have resolved an issue with computers that we manage. Windows Intune will not close the alert for us unless one of these criteria is met: Windows Intune can detect that the issues have been resolved 45 days have passed since the alert was opened To manually close an alert, follow these steps, but be careful to close the right one. While we can re-activate a closed alert in Windows Intune, if the alert is closed by mistake then we may miss taking important action: Open up the Windows Intune console and find the alert to close. We can select more than one alert if desired here. Click Close Alert in the toolbar, or right-click on the alert and select Close Alert from the menu. We can also close an alert when we have opened it fully and are looking at the Alert Properties by clicking the Close This Alert link under Tasks. The automated closing of alerts, when an issue has been resolved, can be a little confusing as we see alert e-mails, but then they don't exist in the console. This is most common when malware and policy issues occur as Windows Intune can detect the resolution of these. It is always worth checking the closed alert log to ensure these do not require further action or highlight an underlying issue, such as network or security, that needs resolving. A good example of where we might see this is with the Unable to Update Policies alert which are generated when a user's computer is not in contact with Windows Intune. The alert e-mail looks similar to the following screenshot: This is the type of alert that will be automatically closed once connectivity is resolved and the policies updated.
Read more
  • 0
  • 0
  • 7466
article-image-common-api-liferay-portal-systems-development
Packt
01 Feb 2012
11 min read
Save for later

Common API in Liferay Portal Systems Development

Packt
01 Feb 2012
11 min read
(For more resources on Liferay, see here.) User management The portal has defined user management with a set of entities, such as, User, Contact, Address, EmailAddress, Phone, Website, and Ticket, and so on at /portal/service.xml. In the following section, we're going to address the User entity, its association, and relationship. Models and services The following figure depicts these entities and their relationships. The entity User has a one-to-one association with the entity Contact, which may have many contacts as children. And the entity Contact has a one-to-one association with the entity Account, which may have many accounts as children. The entity Contact can have a many-to-many association with the entities Address, EmailAddress, Phone, Website, and Ticket. Logically, the entities Address, EmailAddress, Phone, Website, and Ticket may have a many-to-many association with the other entities, such as Group, Organization, and UserGroup as shown in the following image: Services The following table shows user-related service interfaces, extensions, utilities, wrappers, and their main methods: Interface Extension Utility/Wrapper Main methods UserService, UserLocalService PersistedModelLocalService User(Local)ServiceUtil, User(Local)ServiceWrapper add*, authenticate*, check*, decrypt*, delete*, get*, has*, search, unset*, update*, and so on. ContactService, ContactLocalService persistedmodellocalservice> Contact(Local)ServiceUtil, Contact(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. AccountService, AccountLocalService Account(Local)ServiceUtil, Account(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. AddressService, AddressLocalService Address(Local)ServiceUtil, Address(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. EmailAddressService, EmailAddressLocalService PersistedModelLocalService Address(Local)ServiceUtil, Address(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. PhoneService, PhoneLocalService PersistedModelLocalService Phone(Local)ServiceUtil, Phone(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. WebsiteService, WebsiteLocalService PersistedModelLocalService Website(Local)ServiceUtil, Website(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. TicketLocalService PersistedModelLocalService TicketLocalServiceUtil, TicketLocalServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on.   Relationships The portal also defined many-to-many relationships between User and Group, User and Organization, User and Team, User and UserGroup, as shown in the following code: <column name="groups" type="Collection" entity="Group" mapping-table="Users_Groups" /> <column name="userGroups" type="Collection" entity="UserGroup" mapping-table="Users_UserGroups" /> In particular, you will be able to find a similar definition at /portal/service.xml. Sample portal service portlet The portal provides a sample portal service plugin called sample-portal-service-portlet (refer to the plugin details at /portlets/sample-portal-service-portlet). The following is the code snippet: List organizations = OrganizationServiceUtil.getUserOrganizations( themeDisplay.getUserId()); // add your logic The previous code shows how to consume Liferay services through regular Java calls. These services include com.liferay.portal.service.OrganizationServiceUtil and the model involves com.liferay.portal.model.Organization. Similarly, you can use other services, for example, com.liferay.portal.service.UserServiceUtil and com.liferay.portal.service.GroupServiceUtil; and models, for example, com.liferay.portal.model.User, com.liferay.portal.model.Group. Of course, you can find other services and models—you will find services located at the com. liferay.portal.service package in the /portal-service/src folder. In the same way, you will find models located at the com.liferay.portal.model package in the /portal-service/src folder. What's the difference between *LocalServiceUtil and *ServiceUtil? The sign * represents models, for example, Organization, User, Group, and so on. Generally speaking, *Service is the remote service interface that defines the service methods available to remote code. *ServiceUtil has an additional permission check, since this method might be called as a remote service. *ServiceUtil is a facade class that combines the service locator with the actual call to the service *Service. While *LocalService is the internal service interface,*LocalServiceUtil is a facade class that combines the service locator with the actual call to the service *LocalService. *Service has a PermissionChecker in each method, and *LocalService usually doesn't have the same. Authorization Authorization is a process of finding out if the user, once identified, is permitted to have access to a resource. The portal implemented authorization by assigning permissions via roles and checking permissions, and this is called Role-Based Access Control (RBAC). The following figure depicts an overview of authorization. A user can be a member of Group, UserGroup, Organization, or Team. And a user or a group of users, such as Group, UserGroup, or Organization can be a member of Role. And the entity Role can have many ResourcePermission entities associated with it, while the entity ResourcePermission may contain many ResourceAction entities, as shown in the following diagram: The following table shows the entities Role, ResourcePermission, and ResourceAction: Interface Extension Wrapper/SOAP Main methods Role RoleModel, PersistedModel RoleWrapper, RoleSoap clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on. ResourceAction ResourceActionModel, PersistedModel ResourceActionWrapper, ResourceActionSoap clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on. ResourcePermission ResourcePermissionModel, PersistedModel ResourcePermissionWrapper, ResourcePermissionSoap clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on. In addition, the portal specifies role constants in the class RoleConstants. The entity ResourceAction gets specified with the columns name, actionId, and bitwiseValue as follows: <column name="name" type="String" /> <column name="actionId" type="String" /> <column name="bitwiseValue" type="long" /> The entity ResourcePermission gets specified with the columns name, scope, primKey, roleId, and actionIds as follows: <column name="name" type="String" /> <column name="scope" type="int" /> <column name="primKey" type="String" /> <column name="roleId" type="long" /> <column name="ownerId" type="long" /> <column name="actionIds" type="long" /> In addition, the portal specified resource permission constants in the class ResourcePermissionConstants Password policy The portal implements enterprise password policies and user account lockout using the entities PasswordPolicy and PasswordPolicyRel, as shown in the following table: Interface Extension Wrapper/Soap Description PasswordPolicy PasswordPolicyModel, PersistedModel PasswordPolicyWrapper, PasswordPolicySoap Columns: name, description, minAge, minAlphanumeric, minLength, minLowerCase, minNumbers, minSymbols, minUpperCase, lockout, maxFailure, lockoutDuration, and so on. PasswordPolicyRel PasswordPolicyRelModel, PersistedModel PasswordPolicyRelWrapper, PasswordPolicyRelSoap Columns: passwordPolicyId, classNameId, and classPK. Ability to associate the entity PasswordPolicy with other entities.   Passwords toolkit The portal has defined the following properties related to the passwords toolkit in portal.properties: passwords.toolkit= com.liferay.portal.security.pwd.PasswordPolicyToolkit passwords.passwordpolicytoolkit.generator=dynamic passwords.passwordpolicytoolkit.static=iheartliferay The property passwords.toolkit defines a class name that extends com.liferay.portal.security.pwd.BasicToolkit, which is called to generate and validate passwords. If you choose to use com.liferay.portal.security.pwd.PasswordPolicyToolkit as your password toolkit, you can choose either static or dynamic password generation. Static is set through the property passwords.passwordpolicytoolkit.static and dynamic uses the class com.liferay.util.PwdGenerator to generate the password. If you are using LDAP password syntax checking, you will also have to use the static generator, so that you can guarantee that passwords obey their rules. The passwords' toolkits get addressed in detail in the following table: Class Interface Utility Property Main methods DigesterImpl Digester DigesterUtil passwords.digest.encoding digest, digestBase64, digestHex, digestRaw, and so on. Base64 None None None decode, encode, fromURLSafe, objectToString, stringToObject, toURLSafe, and so on. PwdEncryptor None None passwords.encryption.algorithm encrypt, default types: MD2, MD5, NONE, SHA, SHA-256, SHA-384, SSHA, UFC-CRYPT, and so on .   Authentication Authentication is the process of determining whether someone or something is, in fact, who or what it is declared to be. The portal defines the class called PwdAuthenticator for authentication, as shown in the following code: public static boolean authenticate( String login, String clearTextPassword, String currentEncryptedPassword) { String encryptedPassword = PwdEncryptor.encrypt( clearTextPassword, currentEncryptedPassword); if (currentEncryptedPassword.equals(encryptedPassword)) { return true; } } As you can see, it encrypts the clear text password first into the variable encryptedPassword. It then tests whether the variable currentEncryptedPassword has the same value as that of the variable encryptedPassword or not. The classes UserLocalServiceImpl (the method authenticate) and EditUserAction (the method updateUser) call the class PwdAuthenticator for authentication. A Message Authentication Code (MAC) is a short piece of information used to authenticate a message. The portal supports MAC through the following properties: auth.mac.allow=false auth.mac.algorithm=MD5 auth.mac.shared.key= To use authentication with MAC, simply post to a URL as follows: It passes the MAC in the password field. Make sure that the MAC gets URL encoded, since it might contain characters not allowed in a URL. Authentication with MAC also requires that you set the following property in system-ext.properties: com.liferay.util.servlet.SessionParameters=false As shown in the previous code, it encrypts session parameters, so that browsers can't remember them. Authentication pipeline The portal provides the authentication pipeline framework for authentication, as shown in the following code: auth.pipeline.pre=com.liferay.portal.security.auth.LDAPAuth auth.pipeline.post= auth.pipeline.enable.liferay.check=true As you can see, the property auth.pipeline.enable.liferay.check is set to true to enable password checking by the internal portal authentication. If it is set to false, essentially, password checking is delegated to the authenticators configured in the auth.pipeline.pre and auth.pipeline.post settings. The interface com.liferay.portal.security.auth.Authenticator defines the constant values that should be used as return code from the classes implementing the interface. If authentication is successful, it returns SUCCESS; if the user exists but the passwords doesn't match, then it returns FAILURE. If the user doesn't exist in the system, it returns DNE. Constants get defined in the interface Authenticator. As shown in the following table, the available authenticator is com.liferay.portal.security.auth.LDAPAuth: Class Extension Involved properties Main Methods PasswordPolicyToolkit BasicToolkit passwords.passwordpolicytoolkit.charset.lowercase, passwords.passwordpolicytoolkit.charset.numbers, passwords.passwordpolicytoolkit.charset.symbols, passwords.passwordpolicytoolkit.charset.uppercase, passwords.passwordpolicytoolkit.generator, passwords.passwordpolicytoolkit.static generate, validate RegExpToolkit BasicToolkit passwords.regexptoolkit.pattern, passwords.regexptoolkit.charset, passwords.regexptoolkit.length generate, validate PwdToolkitUtil None passwords.toolkit Generate, validate PwdGenerator None None getPassword. getPinNumber   Authentication token The portal provides the interface com.liferay.portal.security.auth.AuthToken for the authentication token as follows: auth.token.check.enabled=true auth.token.impl= com.liferay.portal.security.auth.SessionAuthToken As shown in the previous code, the property auth.token.check.enabled is set to true to enable authentication token security checks. The checks can be disabled for specific actions via the property auth.token.ignore.actions or for specific portlets via the init parameter check-auth-token in portlet.xml. The property auth.token.impl is set to the authentication token class. This class must implement the interface AuthToken. The class SessionAuthToken is used to prevent CSRF (Cross-Site Request Forgery) attacks. The following table shows the interface AuthToken and its implementation: Class Interface Properties Main Methods LDAPAuth Authenticator ldap.auth.method, ldap.referral, ldap.auth.password.encryption.algorithm, ldap.base.dn, ldap.error.user.lockout, ldap.error.password.expired, ldap.import.user.password.enabled, ldap.base.provider.url, auth.pipeline.enable.liferay.check, ldap.auth.required authenticateByEmailAddress, authenticateByScreenName, authenticateByUserId   JAAS Java Authentication and Authorization Service (JAAS) is a Java security framework for user-centric security to augment the Java code-based security. The portal has specified a set of properties for JAAS as follows: portal.jaas.enable=false portal.jaas.auth.type=userId portal.impersonation.enable=true The property portal.jaas.enable is set to false to disable JAAS security checks. Disabling JAAS would speed up login. Note that JAAS must be disabled, if administrators are able to impersonate other users. JAAS can authenticate users based on their e-mail address, screen name, user ID, or login, as determined by the property company.security.auth.type. By default, the class com.liferay.portal.security.jaas.PortalLoginModule loads the correct JAAS login module, based on what application server or servlet container the portal is deployed on. You can set a JAAS implementation class to override this behavior. The following table shows this class and its associations: Class Interface Properties Main methods AuthTokenImpl AuthToken auth.token.impl check, getToken AuthTokenWrapper AuthToken None check, getToken AuthTokenUtil None None check, getToken SessionAuthToken AuthToken auth.token.shared.secret check, getToken   As you have noticed, the classes com.liferay.portal.kernel.security.jaas, PortalLoginModule, and com.liferay.portal.security.jaas.PortalLoginModule, implement the interface LoginModule, configured by the property portal.jaas.impl. As shown in the following table, the portal has provided different login module implementation for different application servers or servlet containers: Class Interface/Extension Package Main methods ProtectedPrincipal Principal com.liferay.portal.kernel.servlet getName, equals, hasCode, toString PortalPrincipal ProtectedPrincipal com.liferay.portal.kernel.security.jaas PortalPrincipal PortalRole PortalPrincipal com.liferay.portal.kernel.security.jaas PortalRole PortalGroup PortalPrincipal, java.security.acl.Group com.liferay.portal.kernel.security.jaas addMember, isMember, members, removeMember PortalLoginModule javax.security.auth.spi.LoginModule com.liferay.portal.kernel.security.jaas, com.liferay.portal.security.jaas abort, commit, initialize, login, logout  
Read more
  • 0
  • 0
  • 6602

article-image-article-html5-and-the-mobile-web
Packt
31 Jan 2012
16 min read
Save for later

HTML5 and the Mobile Web

Packt
31 Jan 2012
16 min read
(For more resources on this topic, see here.) Introduction Both HTML5 and mobile web are promising technologies. Both have relatively short histories. In this article, most topics we will be covering are relatively basic. This is to help you get started with mobile development quickly and with minimum effort. Both mobile and HTML5 are still evolving in nature and there could be many questions in your mind. We will clear those doubts and set your mind focused on things that matter. The mobile web is growing fast. We now have mobile Safari which is one of the most used apps on the iPhone, allowing developers to build high performance web applications and enhancing users' browsing experience. You do not need a developer account to host and run a mobile site, you don't need to get approval from any app market to launch a mobile website and you can make updates any time you like without the hassle of waiting for approval. All these are benefits of mobile web development, but at the same time, there are challenges such as inconsistencies among browsers, the lack of certain features compared to native apps, and security. We can't tackle them all, but we sure can solve some of them. And we will see, when developing a mobile site, how we can separate the common practices from the best practices. There are literally thousands of smartphones out there; you don't need every single one of them to test your application on. In fact, you may need fewer than 10. If that's still out of your budget, then two devices are good enough. For the rest, you can use simulators/emulators to do the job. This book focuses on six A-grade mobile devices, with focus specifically on iPhone, Android, and Windows Phone: iOS Android Windows Mobile Blackberry v6.0 and above Symbian 60 Palm webOS There are two browsers that are device-independent that will also be covered in this book. They are: Opera Mobile Firefox Mobile Just because other browsers are not in the list does not mean they won't be covered by the issues and techniques we discuss in this book. Identifying your target mobile devices Target browser: all You can't possibly make a mobile site for every single mobile device. No one has the time or energy to do so. Cross-browser mobile web development can be crazy. It's hard to define the scope of the work, as John Resig (creator of jQuery Mobile) pointed out in his presentation slide describing his experience building jQuery Mobile (http://www.slideshare.net/jeresig/testing-mobile-javascript), he asked three questions: Which platforms and browsers are popular? Which browsers are capable of supporting modern scripting? What devices and simulators do I acquire to test with? When you are building a mobile site, you have to ask yourself similar questions, but not the exact same questions, because remember your site should be specifically tailored to your target audience. So your questions should be: Which platforms and browsers are most commonly used by visitors on my website? How many people access my website from a mobile device that is capable of supporting modern scripting? Which devices and simulators do I need for testing? Which platforms and browsers are most commonly used by visitors on my website? Now let's answer the first question. Before building a mobile website, you must first find out who are your target audience, and what mobile devices they use when visiting your site. There are many analytics tools that can help you answer these questions. One of those is Google Analytics. You can sign up for a free Google Analytics account at: http://www.google.com/analytics/. The way to do it is fairly straightforward: most developers are no strangers to Google Analytics. All you have to do is to include the JavaScript snippet from the the Google Analytics site and embed it in your web pages. JavaScript can be rendered in most modern smartphones, so there is really no difference between using it on a desktop site and on a mobile site. How many people access my website from a mobile device that is capable of supporting modern scripting? Now let's answer the second question. One thing you may want to find out is the number of people using mobile browsers to surf your site. And you also want to find out how many people use a relic mobile browser that doesn't support JavaScript at all. This is because if the percentage of people using low-end smartphones is higher than that of people using high-end smartphones, it may not be worthwhile using HTML5 in the first place (although the chance of this is very low). So if your goal is not just to know the number of people using smartphones, but also the number of people who use older versions of mobile phones, Google Analytics for mobile comes to the rescue. You can download the script from: http://code.google.com/mobile/analytics/download.html#Download_the_Google_Analytics_server_side_package Google Analytics for mobile server-side packages currently supports JSP, ASPX, Perl, and PHP. Let's take a look at one of the examples in PHP. All you have to do is to change the ACCOUNT ID GOES HERE with your GA account ID. But remember to replace 'UA-xx' with 'MO-xx'. Unfortunately, when you use the server-side version, you can't use it on pages where you also use the standard JavaScript tracking code, ga.js. Using the server-side version means that you have to give up the JavaScript version. It can be annoying because the JavaScript version provides a lot of dynamic tracking mechanisms that are lacking in the server-side version: <?php  //  Copyright 2009 Google Inc. All Rights Reserved.  $GA_ACCOUNT = "ACCOUNT ID GOES HERE";  $GA_PIXEL = "ga.php";   function googleAnalyticsGetImageUrl() {    global $GA_ACCOUNT, $GA_PIXEL;    $url = "";    $url .= $GA_PIXEL . "?";    $url .= "utmac=" . $GA_ACCOUNT;    $url .= "&utmn=" . rand(0, 0x7fffffff);     $referer = $_SERVER["HTTP_REFERER"];    $query = $_SERVER["QUERY_STRING"];    $path = $_SERVER["REQUEST_URI"];     if (empty($referer)) {      $referer = "-";    }    $url .= "&utmr=" . urlencode($referer);     if (!empty($path)) {      $url .= "&utmp=" . urlencode($path);    }     $url .= "&guid=ON";     return $url;  }?> Alternatives to Google Analytics Google Analytics is not the only mobile analytics service in the market. There are other services providing more specialized services. For example, PercentMobile is a hosted mobile analytics service that makes your mobile audience and opportunities clear. You can find out more about this service at: http://percentmobile.com/ Accuracy of Google Analytics The location reported by mobile devices may not always be accurate; Google Analytics uses IP addresses to determine user location for Map Overlay reports. They are subject to possible inaccuracy, as mobile IPs originate from the wireless carrier gateway which is not necessarily co-located with mobile users. Server loading speed concern Due to the server-side processing, some additional server load may be incurred. Google recommends you first test the snippet on a few of your pages to ensure all is well before rolling out to an entire site. Setting up mobile development tools Target browser: all Now one question still remains unanswered from the previous recipe: which devices and simulators do I need for testing? We will find this out in this article. If you have figured out what major mobile devices you are going to support, now is the time to see how to set them up. Mobile development can be costly if you test on various mobile devices. Although we have all these mobile simulators and emulators available for testing, it's not as good as testing on a real device. Now let's see how we can maximize the testing coverage and minimize the cost. Getting ready We are going to make some assumptions here. Each case is different, but the idea is the same. Let's assume you have a Windows operating system on your desktop, but the top visitors to your site surf using iOS, Android, and Blackberry. How to do it... Your goal is to maximize the coverage and minimize the cost. All three devices have emulators, but not all support different platforms. Name Compatibility iOS simulator Mac Android emulator Windows, Mac, Linux Blackberry simulator Windows As you can see, since iOS simulator only works for Mac, and if you are running a Windows OS, the best and only choice is to purchase an iPhone for testing. For Android and Blackberry, because they both have emulators for Windows, to save budget, you can download the emulators. How it works... List the top mobile devices people use to surf your site. Know the machine OS you are using for the development. Find out the compatibility of each of these device emulators to your development environment. There's more... If you have the budget for more than one mobile device having a different OS, you can think further about screen sizes and the DPI of the mobile device. You may not need to buy two high-end devices. For instance, it's not necessary to own an iPhone4 and an Android Thunderbolt. You can buy a lower-end of Android just to test out how your site would look on a lower-end device. So the idea is to combine your OS, mobile devices, and emulators to maximize the scenarios to cover. Device simulator/emulator download lookup table The following table shows a list of popular mobile device emulators for mobile web design and development testing: Name Type Compatibility URL iOS Simulator Mac https://developer.apple.com/devcenter/ios/index.action#downloads Android Emulator Mac, Win, Linux http://developer.android.com/sdk/index.html HP webOS Virtual Machine Mac, Win, Linux http://developer.palm.com/index.php?option=com_content&view=article&id=1788&Itemid=55 Nokia Symbian Emulator Win http://www.forum.nokia.com/info/sw.nokia.com/id/ec866fab-4b76-49f6-b5a5-af0631419e9c/S60_All_in_One_SDKs.html Blackberry Emulator Win http://us.blackberry.com/developers/resources/simulators.jsp Windows Mobile 7 Emulator Win http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce Browser simulator/emulator download lookup table Apart from device testing tools, we also have tools for platform-independent browsers, notably Opera and Firefox. These are shown in the table below: Name Type Compatibility URL Opera Mobile Emulator Mac, Win, Linux http://www.opera.com/developer/tools/ Opera Mini Simulator Mac, Win, Linux http://www.opera.com/developer/tools/http://www.opera.com/mobile/demo/ Firefox for Mobile Simulator Mac, Win, Linux http://www.mozilla.com/en-US/mobile/download/ Remote testing Apart from emulators and simulators, there are also test frameworks that give you remote access to REAL devices. One of those tools is DeviceAnywhere; one problem is that it is not free. http://www.deviceanywhere.com/ BlackBerry simulator Target Browser: BlackBerry Most mobile device simulators are easy to install and configure if you follow the instructions on their sites, but BlackBerry simulators work differently from other mobile device simulators. For Blackberry device simulators, to connect to Internet, besides downloading the simulators, you also need to download and install BlackBerry Email and MDS Services Simulator. Getting ready Make sure you have chosen a simulator to download from:http://us.blackberry.com/developers/resources/simulators.jsp How to do it... First, go to the page: https://swdownloads.blackberry.com/Downloads/entry.do?code=A8BAA56554F96369AB93E4F3BB068C22&CPID=OTCSOFTWAREDOWNLOADS&cp=OTC-SOFTWAREDOWNLOADS. There you will see a list of products similar to the following screenshot: Now select BlackBerry Email and MDS Services Simulator Package and then click on Next. After downloading and installing the software, you must first launch the service simulator before the Blackberry simulator, in order to allow it to connect to the Internet.The following is a screenshot of a Blackberry simulator: Setting up the mobile development environment Target browser: all Before we start mobile web development, we have to first set up a development environment. Getting ready Set up localhost on your machine. For Windows, Mac, or Linux, the easiest way to set it up is to use the popular and free XAMPP software: (http://www.apachefriends.org/en/index.html). Make sure you have a wireless connection. Also you should have a mobile device with you. Otherwise, use a mobile simulator/emulator. Ensure your mobile device and your desktop are on the same wireless network. How to do it... Create an HTML file and name it ch01r1.html at the root directory of your localhost: Inside ch01r01.html, type in the following: <html>  <head>  <meta name="viewport" content="width=device-width, initial-scale=1.0">  </head>  <body>    <header>    Main Navigation here    </header>  body content here    <footer>    Footer links here    </footer>  </body></html> Now get your IP address. If you are using Windows, you can type the following line in your command prompt: ipconfig Once you have got your IP address, (for example, 192.168.1.16.), enter it in your mobile browser URL address bar. Now you should see the page load with the text displayed: How it works... Within the same network, your mobile device can access your desktop host through your desktop IP address. There's more... If you don't have a mobile device, you can use one of the simulators for testing. But it's recommended to have at least one or two real mobile devices for testing. A simulator could test most things, but not everything, accurately. Testing on a Safari desktop If your main target audience is iPhone mobile Safari users, you can also do testing on a desktop to save time. To do so, open up Safari, go to Preferences, click on the Advanced tab, check Show Develop menu bar as shown next: Now click on the display menu for the current page, choose Develop | User Agent | Mobile Safari 3.1.3 – iPhone: List of community-based collection of emulators/simulators There is a list of emulators and simulators available if you really don't have a Smartphone at hand. You can find the list on a wiki on the Mobile Boilerplate project: https://github.com/h5bp/mobile-boilerplate/wiki/Mobile-Emulators-&-Simulators List of emulators/simulators collection by Firtman Maximiliano Firtman, a mobile and web developer, also an author, maintains a list of emulators on his site at: http://www.mobilexweb.com/emulators Using HTML5 on the mobile web Target browser: all Now we are going to create a simple HTML5 page for your mobile device. If you already have experience with older versions of HTML, HTML5 should be easy to understand. And if you have made a web page for desktop before, it won't be hard for you to make one for a mobile device. Getting ready Create a new file ch01e2.html. How to do it... Save the following code in the file: <!doctype html><html>  <head>  <meta name="viewport" content="width=device-width, initial-scale=1.0">  </head>  <body>    hello to the HTML5 world!  </body></html> Now render this in your mobile browser, and you should see the text render just as expected. How it works... As you can see, the only difference between HTML5 and other HTML pages is the Document Type Definition (DTD) we used: <!doctype html>. You might have seen the code <meta name="viewport" content="width=devicewidth, initial-scale=1.0"> and are wondering what it does. It helps Mobile Safari to know that the page is as wide as the device. Setting initial-scale=1 tells the browser not to zoom in or out. There's more... Here's a little bit of history of HTML5: there are two versions of HTML5 draft, one created by W3C and the other by WHATWG. The W3C is run by a group that is democratic in nature, but super slow in practice. WHATWG is edited by one person, Ian Hickson (who is also working for Google), and a group of people who are not public. As Ian does most of the decision making, it makes WHATWG's version progress faster. HTML5 and version number You might be wondering why HTML5 is being so ambiguous by using a declaration without even a version number. Well there are many reasons to justify this: Version support of HTML doesn't matter much to browsers. What matters is the feature support. In other words, if the browser supports the HTML5 feature you are using, even if you declare the document as HTML4, it will still render the HTML5 element as expected. It's easier to type! Mobile doctypes One question you may ask is whether it is safe to use the HTML5 DTD <!doctype html>. The answer is DTDs were made for validation, not browser rendering. Your next question might be: what about quirks mode? <!doctype html> is the minimum information required to ensure that a browser renders in standards mode. So you are pretty safe to use <!doctype html>. You may have noticed that we use <!doctype html> instead of <!DOCTYPE html>. The reason is HTML5 is not case sensitive, but for consistency with other HTML tags, we will use lowercase throughout the book. Free resources to learn HTML5 There are many excellent and free books, and articles about basic HTML5 tags. If you are unfamiliar with HTML5, you can check out one of the following: HTML5 Doctor: http://html5doctor.com/ Dive Into HTML5: http://diveintohtml5.org/ HTML5 Rocks:http://www.html5rocks.com/ If you are the kind of person who really wants to know every detail about something, you can read the official HTML5 specs. The W3C version of the spec is at: http://dev.w3.org/html5/spec/Overview.html The WHATWG version of HTML Living Standard is at: http://www.whatwg.org/specs/web-apps/current-work/multipage/
Read more
  • 0
  • 0
  • 2233

article-image-new-features-notesdomino-853-development
Packt
31 Jan 2012
8 min read
Save for later

New Features in Notes/Domino 8.5.3 Development

Packt
31 Jan 2012
8 min read
Composite applications Composite applications are applications that consist of two or more components that may have been independently developed, working together to perform tasks that none of the member applications could perform by itself. Each component publishes and consumes messages from other components, and performs actions based upon user interaction or information received from other components. Support for composite applications is one of the central points for Notes/Domino 8. Composite applications in Notes 8 can wire together multiple components from Notes applications, Lotus Component Designer applications, and Eclipse into a single application context for the end user. Composite applications, whether they are based on Notes/Domino 8, Web Sphere Portal, or Lotus Expeditor, are the frontend or user interface to an enterprise's SOA strategy. They, in effect, consume the services that are offered by the composite architectures put in place to support SOA. An example of a composite application would be a simple customer relationship management application. This application needs to display a list of accounts, opportunities, and contacts to end users. The accounts component should display accounts owned by the end user. When the end user selects an account in the account component, the opportunities for that account should be displayed in the opportunities component, and all of the contacts for the first opportunity should be displayed in the contacts component. In the application described, the components are "communicating" with each other by publishing and consuming properties via a property broker. When the user clicks on an account, the account component publishes the accountkey property to the property broker. The opportunities component has been written to "listen" for the accountkey property to be published, and when it is, it performs a lookup into a data store, pulling back all the specific opportunities for the published account key. Once it has displayed all of the opportunities for the account, it selects the first opportunity for display and then publishes the opportunitykey property to the property broker. The contacts component then performs a lookup to display all of the contacts for the opportunity. When the user selects a different opportunity, the opportunity component again publishes an opportunitykey property and the contacts component receives this new opportunitykey property and displays the correct contacts for the selected opportunity Using component applications, developers can respond quickly to requests from the line of business for functionality changes. For example, in the case of the customer relationship management application described, the line of business may decide to purchase a telephony component to dial the phone and log all phone calls made. The developers of the application would need to simply modify the contact component to publish the phone number of a contact with a name that the new telephony component listens for and the call could be made on behalf of the user. In addition to being used within the customer relationship management application, the components developed could be put together with other components to form entirely different applications. Each component already understands what data it needs to publish and consume to perform its actions, and contains the code to perform those specific actions on backend systems. The reuse of the components will save the developers and the organization time whenever they are reused. Composite applications also require a new programming model for Notes/Domino 8. This model mirrors the model within WebSphere Portal 6, in that multiple components are aggregated into a single UI with the property broker acting as the "glue" that allows the various components to interact and share data, even if the components are from different systems. This programming model is something new in Notes 8 and required some changes to Domino Designer 8. As a side note, the new programming model of composite applications will most probably bring its own set of problems. For example, what happens in a composite application when one of the components fails? In this "composite crash" situation, what does the composite application need to do in order to recover? Additionally, from an infrastructure point of view, composite applications will only be as available as their weakest component. What good would a reservations system, implemented with many components, be if one of the components were not hosted by a highly available infrastructure, while the others were? We see these sorts of issues being dealt with currently by customers venturing into the composite world via SOAs. There are two main categories of change for development related to composite applications in Notes/Domino 8 application design and programming. We will look at both of them in the following sections. Application design In order to allow your Notes or Domino application to participate within a composite application, you must first decide which design elements need to be accessible to other components. To make these components available to other components within your composite application, they are specified within a Web Services Description Language (WSDL) file. The composite application property broker then uses this WSDL file as a map into your application and its published properties and actions. To allow this mapping to occur, the Composite Application Editor is used. Without making changes to legacy Notes/Domino application functionality, the Composite Application Editor can be used to surface the elements of the application such as forms, views, documents, and other Notes elements to the composite application. Another element of composite application design is deciding where the application components will reside. Composite applications can be hosted within a local NSF file on a Notes client, on a Domino 8 application server, in the WebSphere Portal, or in Lotus Expeditor. The Notes/Domino application components are created with the Composite Application Editor, while WebSphere Portal composite applications can be created with the Composite Application Editor or the Portal Application Template Editor. Programming As mentioned earlier, the addition of composite applications to the development strategy for Notes/Domino 8 required some changes and additions to the existing programming model. Within a composite application, the components must be able to interact even if they were defined with different tools and technologies. Some components may even be stored within different database technologies. One component may be NSF-based while another may be stored within a relational database store. The components need a standardized way to define the properties and actions that they support, so that an application developer can wire them together into a composite application. The standard way to define these properties and actions is via a WSDL file. Let's take a quick look at properties, actions, and wires Properties Component properties are the data items that a given component produces. They are either input properties (consumed by the component) or output (produced by the component) properties. Each property is assigned a data type, which is based on the WC3 primitive data types. These include String, Boolean, decimal, time, and date. The primitive data types can also be utilized to build new data types. For example, within Notes 8, some new data types for components will be available that map to common data available within the mail, calendar, and contacts applications. Some of these new data types are listed in the following table: Data type name   Extends data type   Description   Example   mailTo   String   List of people to receive an e-mail   "mailto:suzie@company.com?subject=Our Dogs are Smart&cc=frankie@company.com,domino@company.com&bcc=gromit@company.com"   e-mailAddress822   String   E-mail address following RFC 822   "My Gerbil <shelbie@company.com>" "Little Man <nate@company.com>" Actions Actions are the logic that is used to consume a property. For example, a component may implement an action that sends an e-mail when it receives a mailTo type property from another component. The code within the component that sends the e-mail based on the information consumed from the property is the action for the component. Components can obviously contain multiple actions depending on the business logic required for the component. It is easy to confuse a web services action with a Notes action. The web services action is a name in a WSDL file that represents functionality that will consume a property. Notes actions can be coupled with a web services action so that the Notes action gets called to consume a property. The LotusScript in the Notes action can then implement code to act on the property. The following screenshot shows a Notes action in the Notes 8 mail template that is coupled with a web services action, NewMemoUsingMailtoURL. You can see that in the code, the LotusScript is using a property broker to gain access to the property: Wires Wires are the construct by which components interact within a composite application. A wire is simply a programmatic definition of which components talk to each other. The components must share common properties and then produce and consume them via actions. More simply put, wires connect properties to actions. For example, an application developer could wire together a contact list component with an e-mail component. When the user selects a contact from the contact list, the contact list component would produce and publish a mailTo type property, which could then be consumed by the e-mail component. The e-mail component would consume the published mailTo property and compose an e-mail using the data contained within the property. The following screenshot shows the components available within the Notes 8 mail template that are available for use in other component applications as well, shown from the Component Palette within the new Composite Application Editor:
Read more
  • 0
  • 0
  • 2036
article-image-article-html5-mobile-setup-and-optimization
Packt
30 Jan 2012
18 min read
Save for later

HTML5: Mobile Setup and Optimization

Packt
30 Jan 2012
18 min read
(For more resources on this topic, see here.) Introduction While there are many operating systems (OS) as well as device makers, inevitably there could be cross-browser issues that cost us a lot of headaches. But on the other hand, we developers love the challenges and set out to tackle them! Throughout this article, we will first focus on cross-browser/browser-specific setup and optimizations you may want to consider. We will then go on to look at a couple of general/ browser-specific features you may want to add at the start of your mobile development. Adding a home screen button icon Target devices: iOS, Android, Symbian On modern smartphones, screens are mostly touch based. The iPhone revolutionized the way we think of mobile by making everything on your device an "app"; even SMS and phone dialing behave like apps with an icon on the home screen. For an HTML web app, things are a bit different; users have to go to a browser app first, type in the address and then launch your site. This can be too much hassle from a user perspective, so on certain smartphones, users can bookmark a home screen icon to a particular web app, so they can launch that particular web app site directly from the icon on their home screen. That sounds cool, right? Yes, it does, but there are also issues associated with it. Not all browsers behave the same way when it comes to touch icons. In this recipe, we will examine the behavior of each browser and how to make home screen icons available to as many mobile browsers as possible. Getting ready First, you have to download the icon sets from the chapter code folder. If you open up the folder, you should be able to see the following:apple-touch-icon.png apple-touch-icon-57x57-precomposed.pngapple-touch-icon-72x72-precomposed.png apple-touch-icon-114x114-precomposed.png apple-touch-icon-precomposed.png These images will be used for different devices. Create an HTML document and name it ch02r01.html. How to do it... In your HTML document, use the following code: <!doctype html><html>  <head>    <title>Mobile Cookbook</title>    <meta charset="utf-8">    <meta name="viewport" content="width= device-width,     initial-scale=1.0">    <link rel="apple-touch-icon-precomposed"     sizes="114x114" href="icons/apple-touch-icon-114x114     -precomposed.png">    <link rel="apple-touch-icon-precomposed"      sizes="72x72" href="icons/apple-touch-icon-72x72     -precomposed.png">    <link rel="apple-touch-icon-precomposed"      href="icons/apple-touch-icon-precomposed.png">    <link rel="shortcut icon" href="     icons/apple-touch-icon.png">  </head>  <body>  </body></html>  How it works... Now let's break down the code: As of iOS 4.2.1, it's possible to specify multiple icons for different device resolutions by using the sizes attribute. <link rel="apple-touch-icon-precomposed" sizes="114x114" href="apple-touch-icon-114x114-precomposed.png"> For high resolution retina displays on iPhone 4, a 114 x 114 icon is used. <link rel="apple-touch-icon-precomposed" sizes="72x72" href="apple-touch-icon-72x72-precomposed.png"> For iPad, a 72 x 72 icon can be used. For non-retina iPhone, Android 2.1+ devices, a 57 x 57 low resolution icon is used. <link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png"> For Nokia Symbian 60 devices, a shortcut icon is used in link relation to tell the device about the shortcut icon. <link rel="shortcut icon" href="img/l/apple-touch-icon.png"> Here is what the bookmark looks like on Android: There's more... There must be a couple of questions in your mind after seeing the previous example: Isn't it possible to define more than one value in the rel attribute? So can we combine the last two lines into something as follows? <link rel="shortcut icon apple-touch-icon-precomposed"href="apple-touch-icon-precomposed.png"> It was tested, but somehow mobile browsers couldn't recognize the value. You might have seen people use: <link rel="apple-touch-icon-precomposed" media="screen and (min-resolution: 150dpi)"href="apple-touch-icon-114x114-precomposed.png"> Together with Paul Irish and Divya Manian, we have been working on Mobile Boilerplate (http://www.h5bp.com/mobile) that provides a rock-solid default for frontend mobile development. In Mobile Boilerplate, we have covered all the current scenarios and possible future scenarios: https://github.com/h5bp/mobile-boilerplate/blob/master/index.html#L21 Everything you always wanted to know about touch icons Most ideas presented on this topic are originated from Mathias Bynens. His original article Everything you always wanted to know about touch icons can be found at:http://mathiasbynens.be/notes/touch-icons. Official documentation about Apple touch icons There is a list of official documentation where you can find more information about touch icons for each specific device and browser: Apple touch icon: http://developer.apple.com/library/safari/#documentation/ AppleApplications/Reference/SafariWebContent/ ConfiguringWebApplications/ConfiguringWebApplications.html Official information from WHATWG: http://www.whatwg.org/specs/web-apps/current-work/multipage/ links.html#rel-icon Apple Custom Icon and Image Creation Guidelines Guidelines and articles about how to create a touch icon can be found at the Apple – Custom Icon and Image Creation Guidelines article: http://developer.apple.com/library/ios/#documentation/ userexperience/conceptual/mobilehig/IconsImages/IconsImages html#//apple_ref/doc/uid/TP40006556-CH14-SW11. Preventing text resize Target devices: iOS, Windows Mobile On certain mobile devices like the iPhone and Windows Mobile, browser text may resize when you rotate the device from portrait to landscape mode. This could be problematic to web developers because we want to have full control of the design and rendering of the website. Getting ready Create a new HTML file, and name it ch02r02.html. Enter the following code: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width,  initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  <style>    figure, figcaption, header {      display:block;      margin:0 auto;      text-align:center;    }  </style>  </head>  <body>    <header>      HTML5 Logo    </header>    <figure>      <img src="HTML5_Badge_128.png" alt="HTML5 Badge" />      <figcaption>        It stands strong and true, resilient and         universal as the markup you write.         It shines as bright and as bold as the         forward-thinking, dedicated web developers         you are.         It's the standard's standard, a pennant for         progress.         And it certainly doesn't use tables for layout.      </figcaption>    </figure>      </body></html> Now render this page in portrait mode in iPhone, as you can see, it will be rendered normally as follows: Now if you render it in the landscape mode, the font size will suddenly increase. As we can see when the page is changed to landscape mode, the text will get resized. This is not the desired behavior. The following shows how it looks: How to do it... You can follow these steps to fix the issue: You can add the following lines to the CSS, and then render the page in landscape again: html {  -webkit-text-size-adjust: none;} As You can see, the text now appears normal: How it works... To solve this issue, you have to add a CSS property named text-size-adjust in WebKit, and assign the value to none to prevent the auto adjust. Setting text-size-adjust to none solves the problem for mobile-specific websites, but if we render this on a desktop screen or other non-mobile browser, the desktop browser text zoom feature will be disabled. To prevent this accessibility issue, we can set text-size-adjust to 100% instead of none. So we can tweak this example to: html {  -webkit-text-size-adjust: 100%;} There's more... Apart from iPhone, other devices also have ways to add the text size adjust property. Windows Mobile Windows Mobile IE uses a different prefix. They originally added the WebKit prefix. The intent was adding support for the WebKit-specific property to make web developers' lives a bit easier by not having to add yet another vendor-prefixed CSS property to their pages to control how text was scaled. Even more specifically, they intuited that the most common use case for this property was to explicitly set it to none in order to tell the browser not to scale a particular section of the text. After hearing the community's feedback on this issue (and a couple of face-plants when they realized the broader implications of implementing other browser vendors' CSS properties) they've decided that it's best to only implement the -ms- prefixed version and not the -webkit- one. So to make the preceding example more complete, you can add: html {  -webkit-text-size-adjust: 100%;  -ms-text-size-adjust: 100%;} Making it future proof To make things more future proof, you can add one more line without any prefix, as follows: html {  -webkit-text-size-adjust: 100%;  -ms-text-size-adjust: 100%;  text-size-adjust: 100%;} px em, which is better? The common debate about using px versus em is less of a problem on mobile. Originally Yahoo! User Interface used ems for the reason that IE6 doesn't support page zoom with pixels. On mobile, there isn't such an issue, and even if we want the page to render well on desktop browsers, the likelihood of someone using IE6 is getting lower and lower, so in most cases, you can save the trouble of using ems and all the calculation, and choose instead to use pixels. Optimizing viewport width Target device: cross-browser Different mobile devices have different default mobile viewport widths. Refer to Appendix X for a complete list of default viewport widths for all mobile devices. If you leave it unset, in most cases, it will cause an unexpected result. For example, in an iPhone if the viewport width is left unset, it will be rendered as 980 px. Getting ready Let's create an HTML document and name it ch02r03.html. How to do it... Here is what we can do to optimize the viewport width: Add the following code to ch02r03.html and render it in your mobile browser: <!doctype html><html>  <head>  <meta charset="utf-8">    </head>  <body>    <header>      HTML5 Logo    </header>    <div id="main">    <h1>Lorem ipsum</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.    </div>      </body></html> Here is how it's rendered by default: If we render this example, we can see that everything becomes extremely small. Now, let's set the viewport width to the device width: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width">    </head>  <body>    <header>      HTML5 Logo    </header>  <div id="main">  <h1>Lorem ipsum</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>  </div>          </body></html> Now the content width uses the screen width and the text becomes readable: How it works... When we set viewport width to device-width, it will tell the browser not to scale the page to fix the device area. So for iPhone, the device-width is 320 px in portrait mode and 480 px in landscape mode. There's more... For some really old relic mobile browsers, the meta attribute isn't recognized. To deal with these browsers, you need to use: <meta name="HandheldFriendly" content="true"> This is used by older versions of Palm OS, AvantGo, and Blackberry. <meta name="MobileOptimized" content="320"> For Microsoft PocketPC, a MobileOptimized attribute was introduced. So the most complete code should look like: <meta name="HandheldFriendly" content="true"><meta name="MobileOptimized" content="320"><meta name="viewport" content="width=device-width"> IE for Windows Phone viewport blog post On IE for Windows Phone Team Weblog, there is an article about IE Mobile Viewport on Windows Phone 7. In it, the author has explained important information like how Windows Phone 7 implements "device-width", together with much other very useful information in general. You can read the article here: http://blogs.msdn.com/b/iemobile/ archive/2010/11/22/the-ie-mobile-viewport-on-windows-phone-7.aspx Safari documentation Safari has a reference in the developer's library at:http://developer.apple. com/library/safari/#documentation/appleapplications/reference/ SafariHTMLRef/Articles/MetaTags.html Blackberry documentation There is a Blackberry Browser Content Design Guidelines document. It explains Blackberry's use of viewport width: http://docs.blackberry.com/en/developers/ deliverables/4305/BlackBerry_Browser-4.6.0-US.pdf. Fixing Mobile Safari screen re-flow scale Target device: iOS Mobile Safari has an annoying screen re-flow bug: When you rotate the mobile browser from portrait mode to landscape mode, the text will suddenly jump to a bigger size. During the time I was working on building Mobile Boilerplate, Jeremy Keith and I had a long discussion on this issue. The traditional way of fixing this is to add the following scaling attributes to the meta viewport: <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> This solution was first incorporated into Mobile Boilerplate. Jeremy pointed out that this solves the scale jump problem, but at the same time, it causes another issue with accessibility: When you set the values as shown above, you can no longer zoom the page to enlarge it. For people with eyesight problems, the ability to zoom is essential. But if we let the zoom happen, the text jump will annoy the majority of the users. So, for a long time it was an accessibility versus usability debate. I discovered a method that could tackle the issue and we will discuss this next. Getting ready First, let's create an HTML document and name it ch02r04.html, enter the following code in it: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width,  initial-scale=1.0">  </head>  <body>      <div>  <h1>Lorem ipsum</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>  </div>  </body></html> This page renders perfectly fine in portrait mode: But when displayed in landscape mode, things change: How to do it... All we need to do to solve this problem is to dynamically reset the scale factors to default when the user zooms in on the page. Now put the following code in your HTML document: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width,    initial-scale=1.0">  </head>  <body>          <div>  <h1>Lorem ipsum</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>  </div>    <script>      var metas = document.getElementsByTagName      ('meta');      var i;      if (navigator.userAgent.match(/iPhone/i)) {        for (i=0; i<metas.length; i++) {          if (metas[i].name == "viewport") {            metas[i].content = "width=device-width,             minimum-scale=1.0, maximum-scale=1.0";          }        }        document.addEventListener("gesturestart",         gestureStart, false);      }      function gestureStart() {        for (i=0; i<metas.length; i++) {          if (metas[i].name == "viewport") {            metas[i].content = "width=device-width,             minimum-scale=0.25, maximum-scale=1.6";          }        }      }    </script>  </body></html> Now if we rotate the screen from portrait to landscape, the issue should no longer exist, and if we zoom in on the page, it will react as expected: How it works... Let's have a walk through of the code to see how it works. We need to know the default minimum-scale and maximum-scale values. In the iPhone's official documentation, it states that the minimum-scale value is 0.25, and the maximum-scale value is 1.6. So to replace the default value, we need to set: function gestureStart() {  var metas = document.getElementsByTagName ('meta');  var i;  for (i=0; i if (metas[i].name == "viewport") {    metas[i].content = "width=device-width,     minimum-scale=0.25, maximum-scale=1.6";  }} Next, we need to know when to set this. This is very easy: The iPhone has a gesture event listener we can use to target the document body. Here is how to do so: document.addEventListener("gesturestart", gestureStart, false); Finally, we need to make sure this only happens on iPhone. Again this can be easily done using: if (navigator.userAgent.match(/iPhone/i)) {document.addEventListener("gesturestart", gestureStart, false);} There's more... If you are interested to know the whole story and discussion between Jeremy and I, you can read it at http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewportscale- bug/.Even though this provides a fix for the issue, there are a couple of problems that some people experience: As soon as the user makes a gesture on the document, zooming is enabled again. So if you change the device orientation after that, the zoom bug will still occur. It's reported on iOS4 that users can only effectively start zooming after starting a second gesture. A slightly improved version Mathias Bynens has a revised version with smarter coding. You can see the code at: https://gist.github.com/901295 An even better version John-David Dalton had an even better updated version with smarter and leaner code at:https://gist.github.com/903131 A word for jQuery Mobile Scott Jehl from jQuery Mobile mentioned it might be implemented in jQuery Mobile in the future. Currently, you could see his gist at: https://gist.github.com/1183357
Read more
  • 0
  • 0
  • 1809

article-image-tweet-for-free-lite-ebook
Packt
29 Jan 2012
1 min read
Save for later

Tweet for your free LITE eBook

Packt
29 Jan 2012
1 min read
Oracle 10g/11g Data and Database Management Utilities: LITE EJB 3.0 Database Persistence with Oracle Fusion Middleware 11g: LITE Drupal 6 Site Blueprints: LITE Microsoft Dynamics GP 2010 Cookbook: LITE Middleware Management with Oracle Enterprise Manager Grid Control 10g R5: LITE Joomla! 1.5 Site Blueprints: LITE Amazon SimpleDB: LITE Oracle Siebel CRM 8 User Management: LITE PostgreSQL 9 Administration Cookbook LITE: Configuration, Monitoring and Maintenance Microsoft Silverlight 4 Data and Services Cookbook: LITE MySQL Admin Cookbook LITE: Replication and Indexing PostgreSQL 9 Administration Cookbook: LITE Edition Seam 2 Web Development: LITE CMS Made Simple 1.9 Beginner’s Guide: LITE Edition SAP Business ONE Implementation: LITE Mootools 1.2 Beginners Guide LITE: Getting started IBM Lotus Notes 8.5 User Guide: LITE JSF 2.0 Cookbook: LITE Inkscape 0.48 Essentials for Web Designers: LITE Learning jQuery: LITE Python Text Processing with NLTK 2.0 Cookbook: LITE Joomla! 1.5 Development Cookbook: LITE Unity 3D Game Development by Example Beginner’s Guide: LITE MySQL Admin Cookbook LITE: Configuration, Server Monitoring, Managing Users Processing XML documents with Oracle JDeveloper 11g: LITE #t1{ text-align:left; } td{ text-align:center; width:25%; } table{ table-layout:fixed; word-wrap:break-word; table-align:center; }
Read more
  • 0
  • 0
  • 1198
Modal Close icon
Modal Close icon