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-model-view-controller-pattern-and-configuring-web-scripts-alfresco
Packt
30 Aug 2010
13 min read
Save for later

The Model-View-Controller pattern and Configuring Web Scripts with Alfresco

Packt
30 Aug 2010
13 min read
(For more resources on Alfresco, see here.) One way of looking at the Web Scripts framework is as a platform for implementing RESTful Web Services. Although, as we have seen, your service won't actually be RESTful unless you follow the relevant guiding principles, Web Scripts technology alone does not make your services RESTful as if by magic. Another way of looking at it is as an implementation of the Model-View-Controller, or MVC pattern. Model-View-Controller is a long-established pattern in Computer Science, often used when designing user-facing, data-oriented applications. MVC stipulates that users of the application send commands to it by invoking the controller component, which acts on some sort of data model, then selects an appropriate view for presenting the model to the users. While the applicability of MVC to Web application has often been debated, it is still a useful framework for partitioning concerns and responsibilities and for describing the roles of the various components of the Alfresco Web Scripts framework. In the latter, the role of controller is carried out by the scripting component. It should be stressed that, in the MVC pattern, the controller's role is purely that of governing the user interaction by selecting an appropriate model and a corresponding view for presentation, possibly determining which user actions are applicable given the present state of the application. It is not the controller's role to carry out any kind of business logic or to operate on the model directly. Rather, the controller should always delegate the execution of data manipulation operations and queries to a suitable business logic or persistence layer. In the context of Alfresco Web Scripts, this means that your controller script should avoid doing too many things by using the repository APIs directly. It is the responsibility of the controller to: Validate user inputs Possibly convert them to data types suitable for the underlying logic layers Delegate operations to those layers Take data returned by them Use the data to prepare a model for the view to display and nothing more All complex operations and direct manipulations of repository objects should ideally be carried out by code that resides somewhere else, like in Java Beans or JavaScript libraries, which are included by the present script. In practice, many Web Scripts tend to be quite small and simple, so this strict separation of concerns is not always diligently applied. However, as the size and complexity of controller scripts grows, it is considered as a good practice to modularize an application's logic in order to make it easier to follow and to maintain. Some people also have a preference for the relative safety of a static language like Java, compared to JavaScript, and for the use of modern Java IDEs. Therefore, it is frequent to see Web Scripts applications that place the very minimum of logic in controller scripts that use Java Beans to carry out more complex tasks. Coming to the view, which in Alfresco Web Scripts is implemented as FreeMarker templates, it should be noted that in a departure from the "pure" MVC pattern, the freedom accorded to the controller itself of choice between different possible views is rather limited as which view to use is determined exclusively by selecting a template for the specific output format requested by the user through the format specification in the request URL. The model that the view can access is also only partially the responsibility of the controller. Whereas the latter can add more objects to the model available to the view, it cannot reduce the visibility of the predefined, root-scoped objects. It is therefore possible for the view to perform quite a bit of logic without even having a controller to do it. This is why Web Scripts without a controller are acceptable. Whether this is a good practice or not is open to debate. The following diagram illustrates the steps that are involved when a Web Script is executed: The diagram can be explained as follows: An HTTP request, specifying a method and a URI is received. The dispatcher uses the HTTP method and the URI to select a Web Script to execute and executes the controller script. The controller script accesses the repository services by means of the Alfresco JavaScript API. The model is populated and passed to the FreeMarker template engine for rendering. FreeMarker renders a response using the appropriate template. The response is returned to the client. URL matching We've already seen how the dispatcher selects a particular Web Script by matching the URL of the HTTP request against the value of the url element in the descriptors of the registered Web Scripts. There is actually a bit more to this process than simple, exact matching, as we are going to see. First, let's have a look at the structure of a Web Script's request URL: http[s]://<host>:<port>/[<contextPath>/]/<servicePath>[/ <scriptPath>][?<scriptArgs>] The meaning of host and port should be obvious. contextPath is the name of the web application context, that is, where your application is deployed in your application server or Servlet container. It will often be alfresco, but could be share, as the Share application is able to host Web Scripts. It could be missing, if the application is deployed in the root context, or it could really be anything you want. The value of servicePath will usually be either service or wcservice. Using the former, if the Web Script requires authentication, this is performed using the HTTP Basic method. This means that the browser will pop up a username/password dialog box. When the latter is used, authentication is performed by the Alfresco Explorer (also known as Web Client). This means that no further authentication is required if you are already logged into the Explorer, otherwise you will be redirected to the Explorer login page. scriptPath is the part of the URL that is matched against what is specified in the descriptor. Arguments can optionally be passed to the script by specifying them after the question mark, as with any URL. With this in mind, let's look at the value of the <url> element in the descriptor. This must be a valid URI template, according to the JSR-311 specification. Basically, a URI template is a (possibly relative) URI, parts of which are tokens enclosed between curly braces, such as: /one/two/three /api/login/ticket/{ticket} /api/login?u={username}&pw={password?} Tokens stand for variable portions of the URI and match any value for a path element or a parameter. So, the first template in the previous list only matches /one/two/three exactly, or more precisely: http[s]://<host>:<port>/[<contextPath>/]/<servicePath>/one/two/three The second template here matches any URI that begins with /api/login/ticket/, whereas the third matches the /api/login URI when there is a u parameter present and possibly a pw parameter as well. The ? symbol at the end of a token indicates that the parameter or path element in question is not mandatory. Actually, the mandatory character of a parameter is not enforced by Alfresco, but using the question mark is still valuable for documentation purposes to describe what the Web Script expects to receive. We can now precisely describe the operation of the dispatcher as follows: When the dispatcher needs to select a Web Script to execute, it will select the one matching the specific HTTP method used by the request and whose URI template more specifically matches the script path and arguments contained in the request URL. A Web Script descriptor can also have more than one URI template specified in its descriptor, simply by having more than one <url> element. All of them are consulted for matching. The actual values of the path elements specified as tokens are available to the script as entries in the url.templateArgs map variable. For instance, when the /x/foo URL is matched by the /x/{token} template, the value of the expression url. templateArgs["token"] will be equal to foo. Values of request arguments are accessible from the script or template as properties of the args object, such as args.u and args.pw for the third example here. The format requested, which can be specified in the URL by means of the filename extension or of a format argument, need not be specified in the URI template. Authentication In the last version of our Web Script, we specified a value of user for the <authentication> element. When you use this value, users are required to authenticate when they invoke the Web Script's URL, but they can use any valid credentials. When a value of none is present, the Web Script will not require any authentication and will effectively run anonymously. This tends to not be very useful, as all operations using repository objects will require authentication anyway. If you require no authentication, but try to access the repository anyway, the script will throw an exception. A value of guest requires authentication as the guest user. This can be used for scripts accessed from the Explorer, where users are automatically logged in as guest, unless they log in with a different profile. A value of admin requires authentication as a user with the administrator role, typically admin. Run as Scripts can be run as if they were invoked by a user, other than the one who actually provided the authentication credentials. In order to do this, you need to add a runAs attribute to the <authentication> element: <authentication runAs="admin">user</authentication> This can be used, as in the previous example, to perform operations which require administrator privileges without actually logging in as an admin. As this can be a security risk, only scripts loaded from the Java classpath, and not those loaded from the Data Dictionary, can use this feature. The Login service Web Scripts that render as HTML and are therefore intended to be used by humans directly can either use HTTP Basic authentication or Alfresco Explorer authentication, as it is assumed that some person will fill in a login dialog with his username and password. When a script is meant to implement some form of Web Service that is intended for consumption by another application, HTTP Basic or form-based authentication is not always convenient. For this reason, Alfresco provides the login service, which can be invoked using the following URL: http[s]://<host>:<port>/[<contextPath>/]/service/api/login?u={username }&pw={password?} If authentication is successful, the script returns an XML document with the following type of content: <ticket>TICKET_024d0fd815fe5a2762e40350596a5041ec73742a</ticket> Applications can use the value of the ticket element in subsequent requests in order to avoid having to provide user credentials with each request, simply by adding an alf_ticket=TICKET_024d0fd815fe5a2762e40350596a5041ec73742a argument to the URL. As the username and the password are included, unencrypted, in the request URL, it is recommended that any invocations of the login service be carried out over HTTPS. Transactions Possible values of the transaction element are: none/li> required/li> requiresnew When none is used, scripts are executed without any transactional support. Since most repository operations require a transaction to be active, using none will result in an error whenever the script tries to call repository APIs. required causes the execution of the script to be wrapped in a transaction, which is the normal thing to do. If a transaction is already active when the script is invoked, no new transaction is started. requiresnew, on the other hand, always initiates a new transaction, even if one is already active. Requesting a specific format The format element in the Web Script descriptor indicates how clients are expected to specify which rendering format they require. This is what the element looks like: <format [default="default format"]>extension|argument</format> A value of extension indicates that clients should specify the format as a filename extension appended to the Web Script's path. For example: http://localhost:8080/alfresco/service/myscript.html http://localhost:8080/alfresco/service/myscript.xml A value of argument indicates that the format specification is to be sent as the value of the format URL parameter: http://localhost:8080/alfresco/service/myscript?format=html http://localhost:8080/alfresco/service/myscript?format=xml When the client fails to specify a particular format, the value of the default attribute is taken as the format to use. Once a format has been determined, the corresponding template is selected for rendering the model, after the script finishes its execution, on the basis of the template's filename, which must be of the form: <basename>.<method>.<format>.ftl Status Sometimes it can be necessary for the Web Script to respond to a request with an HTTP status code other than the usual 200 OK status, which indicates that the request has been processed successfully. There might also be a requirement that the response body be different depending on the status code, like, for instance, when you want to display a specific message to indicate that some resource could not be found, together with a status code of 404 Not Found. You can easily do this by manipulating the status object: if (document != null){ status.code = 404 status.message = "No such file found." status.redirect = true} You need to set the value of status.redirect to true in order for Alfresco to use an alternative error handling template. When you do this, the Web Scripts framework goes looking for a template with a file name of <basename>.<method>.<format>.<code>.ftl, like, for instance, myscript.get.html.404.ftl and uses it, if found, instead of the usual myscript.get.html.ftl. In this template, you can access the following properties of the status variable to customize your output: Property name Meaning status.code Numeric value of the HTTP status code (for example, 404) status.codeName String value of the status code (for example, Not Found) status.message Possibly set by the script status.exception The exception that caused this status If your script sets a status code between 300 and 399, which usually means a redirection, you can set the value of status.location to control the value of the location HTTP header: status.code = 301; // Moved permanentlystatus.location = 'http://some.where/else'
Read more
  • 0
  • 0
  • 2761

article-image-silverlight-4-user-interface-date-and-time-input-tables-and-ratings
Packt
30 Aug 2010
6 min read
Save for later

Silverlight 4 User Interface: Date and Time Input, Tables, and Ratings

Packt
30 Aug 2010
6 min read
(For more resources on Microsoft, see here.) Designing date picker interface Dealing with dates is far from simple. Different cultures, a globalized world, and fast information exchange require simple and error-prone ways to keep date formats correct and adjusted to locale and other user preferences. Silverlight and its Toolkit are now equipped with the Date Picker control, enabling you to easily pick and get date formats. This recipe shows you how to implement and design this kind of interface. Getting ready Start your Expression Blend 4 and then select New project... From the dialog that appears select Silverlight and then Silverlight Application, make sure that Language is set to C# and Version is 4.0. At the end hit OK. How to do it... After you have created your new project, under the Objects and Timeline pane you will see UserControl and LayoutRoot. LayoutRoot is a Grid control hosted in UserControl. Go to the Asset library and locate the DatePicker control. Draw two DatePicker controls and add two TextBlock controls above them with Text properties set to Start date: and End date:, respectively. Basically, you need to create a simple UI that looks like this: As this is really a simple recipe without any real coding, let's just go and hit F5 and explore the current, out-of-the-box supported features. If you click on the calendar icon close to the Start date DatePicker you will see that a drop-down calendar control appears, allowing you to select the date from the calendar interface. You can see that the current date is selected and that by clicking on the header part of the calendar you can easily navigate between months or even years. This all allows for a really fast date selection mechanism. Also, after you select the date, note that it will be displayed in the text field part and it will be formatted according to the local computer settings. The next picture shows you example where user has it's settings set to Croatian( Croatia). In this specific setting, dates are being formatted in the following way: dd.mm.yyyy (Date / Month / Year) The same date for the users with Culture settings set to English (United States) looks like this: Of course, the DatePicker control allows for some modifications. Select the DatePicker control and under the Properties pane set the SelectedDateFormat to Long. Your date representation will now look somewhat like this: From the developer's point of view, having different date formats and representations might look cumbersome and difficult when it comes to handling this information. However, no matter how your date is represented it's easy to get all the required information and manipulate them. For example, the following lines of code are responsible for selecting the day, month, and year and it's completely irrelevant which culture settings you might have. txtDay.Text = dtpStart.SelectedDate.Value.Day.ToString();txtMonth.Text = dtpStart.SelectedDate.Value.Month.ToString();txtYear.Text = dtpStart.SelectedDate.Value.Year.ToString(); The result might look like this: Also note that there are a number of different methods available for manipulating the date elements. For example, you can use the AddMonths method and add any number of months to the current selection. This might be useful in scenarios where, for example, end date is always calculated as starting date plus one month. Simple code for that would look like this: txtMonth.Text = dtpStart.SelectedDate.Value.AddMonths(1).Month.ToString(); How it works... The DatePicker control is one of those rich controls providing you with a broad spectrum of functionalities and out-of-the-box supported features. We've added the DatePicker controls and it was easy to interact with them. Just by clicking on the calendar icon users have gained simple and familiar interface for them to select any given date. The current date (today) is clearly marked and navigation through months, years, and even decades is supported. Support for globalization and different time formats is also available. DatePicker will automatically recognize the culture settings on your computer and apply them. Also, by changing the SelectedDateFormat to Long you've been able to see that the date format can also be selected. After that, several lines of simple C# code explains how you can get values for the day, month, or year and even perform some manipulations on them that can be used in real life projects. However, this pattern lacks some more sophisticated support for continuous date range selection. This scenario is explained in the recipe dealing with the Calendar control and related user interface elements. There's more... As I said at the beginning of this recipe, dates come in many different forms depending on the cultures or event on the specific user settings. A good user interface will automatically adjust itself and allow users to input date in the format that is appropriate for the specific needs and depending on the specific culture. However, the simplest and probably the most error prone method is to present the users with the simple and very familiar calendar control. No matter their cultural background, it is safe to assume that everyone is familiar with the calendar metaphor and can easily select the year, month, and a date when presented with one. Date picker in Silverlight comes with a control that looks like a simple text box enabling you to type in the date in a specific format, but it also features the calendar control activated by clicking on the calendar icon. Then, the calendar drops down enabling the users to select a specific date. The rationale behind this pattern is in the calendar metaphor, one that is practically universal and easily understandable. Some guidelines General guidelines regarding the implementation of this specific UX pattern are fairly simple. Mark the current date on the calendar and by default display the current months. Of course, be sure to allow users to select different dates. However, you might want to limit their ability to select dates in the past depending on your particular functionality being implemented in the application itself. This specific control implementation in Silverlight is well done. There are arrows enabling you to jump backwards and forwards for months and selecting the specific date closes the calendar part and the date is then represented and shown in the text box. The specific date format being displayed depends on your locale settings and properties set for the specific control, as explained in the recipe. Please note that confident and experienced users might wish to enter dates directly into the text box part, especially if dates occur far in the past or future, so clicking through the calendar might be somewhat ineffective. Also, take into account that this specific pattern is best used with mouse-oriented users. Navigating through the calendar, though it is supported, is not quite the easiest and fastest way to get around with this control. One thing to consider is regarding the locale of your users and the display of the information on the calendar part. More on that can be found in the following recipe regarding the usage and implementation of the calendar interface itself.
Read more
  • 0
  • 0
  • 1289

article-image-python-multimedia-working-audios
Packt
30 Aug 2010
14 min read
Save for later

Python Multimedia: Working with Audios

Packt
30 Aug 2010
14 min read
(For more resources on Python, see here.) So let's get on with it! Installation prerequisites Since we are going to use an external multimedia framework, it is necessary to install the necessary to install the packages mentioned in this section. GStreamer GStreamer is a popular open source multimedia framework that supports audio/video manipulation of a wide range of multimedia formats. It is written in the C programming language and provides bindings for other programming languages including Python. Several open source projects use GStreamer framework to develop their own multimedia application. Throughout this article, we will make use of the GStreamer framework for audio handling. In order to get this working with Python, we need to install both GStreamer and the Python bindings for GStreamer. Windows platform The binary distribution of GStreamer is not provided on the project website http://www.gstreamer.net/. Installing it from the source may require considerable effort on the part of Windows users. Fortunately, GStreamer WinBuilds project provides pre-compiled binary distributions. Here is the URL to the project website: http://www.gstreamer-winbuild.ylatuya.es The binary distribution for GStreamer as well as its Python bindings (Python 2.6) are available in the Download area of the website: http://www.gstreamer-winbuild.ylatuya.es/doku.php?id=download You need to install two packages. First, the GStreamer and then the Python bindings to the GStreamer. Download and install the GPL distribution of GStreamer available on the GStreamer WinBuilds project website. The name of the GStreamer executable is GStreamerWinBuild-0.10.5.1.exe. The version should be 0.10.5 or higher. By default, this installation will create a folder C:gstreamer on your machine. The bin directory within this folder contains runtime libraries needed while using GStreamer. Next, install the Python bindings for GStreamer. The binary distribution is available on the same website. Use the executable Pygst-0.10.15.1-Python2.6.exe pertaining to Python 2.6. The version should be 0.10.15 or higher. GStreamer WinBuilds appears to be an independent project. It is based on the OSSBuild developing suite. Visit http://code.google.com/p/ossbuild/ for more information. It could happen that the GStreamer binary built with Python 2.6 is no longer available on the mentioned website at the time you are reading this book. Therefore, it is advised that you should contact the developer community of OSSBuild. Perhaps they might help you out! Alternatively, you can build GStreamer from source on the Windows platform, using a Linux-like environment for Windows, such as Cygwin (http://www.cygwin.com/). Under this environment, you can first install dependent software packages such as Python 2.6, gcc compiler, and others. Download the gst-python-0.10.17.2.tar.gz package from the GStreamer website http://www.gstreamer.net/. Then extract this package and install it from sources using the Cygwin environment. The INSTALL file within this package will have installation instructions. Other platforms Many of the Linux distributions provide GStreamer package. You can search for the appropriate gst-python distribution (for Python 2.6) in the package repository. If such a package is not available, install gst-python from the source as discussed in the earlier the Windows platform section. If you are a Mac OS X user, visit http://py26-gst-python.darwinports.com/. It has detailed instructions on how to download and install the package Py26-gst-python version 0.10.17 (or higher). Mac OS X 10.5.x (Leopard) comes with the Python 2.5 distribution. If you are using packages using this default version of Python, GStreamer Python bindings using Python 2.5 are available on the darwinports website: http://gst-python.darwinports.com/ PyGobject There is a free multiplatform software utility library called 'GLib'. It provides data structures such as hash maps, linked lists, and so on. It also supports the creation of threads. The 'object system' of GLib is called GObject. Here, we need to install the Python bindings for GObject. The Python bindings are available on the PyGTK website at: http://www.pygtk.org/downloads.html. Windows platform The binary installer is available on the PyGTK website. The complete URL is: http://ftp.acc.umu.se/pub/GNOME/binaries/win32/pygobject/2.20/?. Download and install version 2.20 for Python 2.6. Other platforms For Linux, the source tarball is available on the PyGTK website. There could even be binary distribution in the package repository of your Linux operating system. The direct link to the Version 2.21 of PyGObject (source tarball) is: http://ftp.gnome.org/pub/GNOME/sources/pygobject/2.21/ If you are a Mac user and you have Python 2.6 installed, a distribution of PyGObject is available at http://py26-gobject.darwinports.com/. Install version 2.14 or later. Summary of installation prerequisites The following table summarizes the packages needed for this article. Package Download location Version Windows platform Linux/Unix/OS X platforms GStreamer http://www.gstreamer.net/ 0.10.5 or later Install using binary distribution available on the Gstreamer WinBuild website: http://www.gstreamer-winbuild.ylatuya.es/doku.php?id=download Use GStreamerWinBuild-0.10.5.1.exe (or later version if available). Linux: Use GStreamer distribution in package repository. Mac OS X: Download and install by following instructions on the website: http://gstreamer.darwinports.com/. Python Bindings for GStreamer http://www.gstreamer.net/ 0.10.15 or later for Python 2.6 Use binary provided by GStreamer WinBuild project. See http://www.gstreamer-winbuild.ylatuya.es for details pertaining to Python 2.6. Linux: Use gst-python distribution in the package repository. Mac OS X: Use this package (if you are using Python2.6): http://py26-gst-python.darwinports.com/. Linux/Mac: Build and install from the source tarball. Python bindings for GObject "PyGObject" Source distribution: http://www.pygtk.org/downloads.html 2.14 or later for Python 2.6 Use binary package from pygobject-2.20.0.win32-py2.6.exe Linux: Install from source if pygobject is not available in the package repository. Mac: Use this package on darwinports (if you are using Python2.6) See http://py26-gobject.darwinports.com/ for details. Testing the installation Ensure that the GStreamer and its Python bindings are properly installed. It is simple to test this. Just start Python from the command line and type the following: >>>import pygst If there is no error, it means the Python bindings are installed properly. Next, type the following: >>>pygst.require("0.10")>>>import gst If this import is successful, we are all set to use GStreamer for processing audios and videos! If import gst fails, it will probably complain that it is unable to work some required DLL/shared object. In this case, check your environment variables and make sure that the PATH variable has the correct path to the gstreamer/bin directory. The following lines of code in a Python interpreter show the typical location of the pygst and gst modules on the Windows platform. >>> import pygst>>> pygst<module 'pygst' from 'C:Python26libsite-packagespygst.pyc'>>>> pygst.require('0.10')>>> import gst>>> gst<module 'gst' from 'C:Python26libsite-packagesgst-0.10gst__init__.pyc'> Next, test if PyGObject is successfully installed. Start the Python interpreter and try importing the gobject module. >>import gobject If this works, we are all set to proceed! A primer on GStreamer In this article, we will be using GStreamer multimedia framework extensively. Before we move on to the topics that teach us various audio processing techniques, a primer on GStreamer is necessary. So what is GStreamer? It is a framework on top of which one can develop multimedia applications. The rich set of libraries it provides makes it easier to develop applications with complex audio/video processing capabilities. Fundamental components of GStreamer are briefly explained in the coming sub-sections. Comprehensive documentation is available on the GStreamer project website. GStreamer Application Development Manual is a very good starting point. In this section, we will briefly cover some of the important aspects of GStreamer. For further reading, you are recommended to visit the GStreamer project website: http://www.gstreamer.net/documentation/ gst-inspect and gst-launch We will start by learning the two important GStreamer commands. GStreamer can be run from the command line, by calling gst-launch-0.10.exe (on Windows) or gst-launch-0.10(on other platforms). The following command shows a typical execution of GStreamer on Linux. We will see what a pipeline means in the next sub-section. $gst-launch-0.10 pipeline_description GStreamer has a plugin architecture. It supports a huge number of plugins. To see more details about any plugin in your GStreamer installation, use the command gst-inspect-0.10 (gst-inspect-0.10.exe on Windows). We will use this command quite often. Use of this command is illustrated here. $gst-inspect-0.10 decodebin Here, decodebin is a plugin. Upon execution of the preceding command, it prints detailed information about the plugin decodebin. Elements and pipeline In GStreamer, the data flows in a pipeline. Various elements are connected together forming a pipeline, such that the output of the previous element is the input to the next one. A pipeline can be logically represented as follows: Element1 ! Element2 ! Element3 ! Element4 ! Element5 Here, Element1 through to Element5 are the element objects chained together by the symbol !. Each of the elements performs a specific task. One of the element objects performs the task of reading input data such as an audio or a video. Another element decodes the file read by the first element, whereas another element performs the job of converting this data into some other format and saving the output. As stated earlier, linking these element objects in a proper manner creates a pipeline. The concept of a pipeline is similar to the one used in Unix. Following is a Unix example of a pipeline. Here, the vertical separator | defines the pipe. $ls -la | more Here, the ls -la lists all the files in a directory. However, sometimes, this list is too long to be displayed in the shell window. So, adding | more allows a user to navigate the data. Now let's see a realistic example of running GStreamer from the command prompt. $ gst-launch-0.10 -v filesrc location=path/to/file.ogg ! decodebin ! audioconvert ! fakesink For a Windows user, the gst command name would be gst-launch-0.10.exe. The pipeline is constructed by specifying different elements. The !symbol links the adjacent elements, thereby forming the whole pipeline for the data to flow. For Python bindings of GStreamer, the abstract base class for pipeline elements is gst.Element, whereas gst.Pipeline class can be used to created pipeline instance. In a pipeline, the data is sent to a separate thread where it is processed until it reaches the end or a termination signal is sent. Plugins GStreamer is a plugin-based framework. There are several plugins available. A plugin is used to encapsulate the functionality of one or more GStreamer elements. Thus we can have a plugin where multiple elements work together to create the desired output. The plugin itself can then be used as an abstract element in the GStreamer pipeline. An example is decodebin. We will learn about it in the upcoming sections. A comprehensive list of available plugins is available at the GStreamer website http://gstreamer.freedesktop.org. In almost all applications to be developed, decodebin plugin will be used. For audio processing, the functionality provided by plugins such as gnonlin, audioecho, monoscope, interleave, and so on will be used. Bins In GStreamer, a bin is a container that manages the element objects added to it. A bin instance can be created using gst.Bin class. It is inherited from gst.Element and can act as an abstract element representing a bunch of elements within it. A GStreamer plugin decodebin is a good example representing a bin. The decodebin contains decoder elements. It auto-plugs the decoder to create the decoding pipeline. Pads Each element has some sort of connection points to handle data input and output. GStreamer refers to them as pads. Thus an element object can have one or more "receiver pads" termed as sink pads that accept data from the previous element in the pipeline. Similarly, there are 'source pads' that take the data out of the element as an input to the next element (if any) in the pipeline. The following is a very simple example that shows how source and sink pads are specified. >gst-launch-0.10.exe fakesrc num-bufferes=1 ! fakesink The fakesrc is the first element in the pipeline. Therefore, it only has a source pad. It transmits the data to the next linkedelement, that is fakesink which only has a sink pad to accept elements. Note that, in this case, since these are fakesrc and fakesink, just empty buffers are exchanged. A pad is defined by the class gst.Pad. A pad can be attached to an element object using the gst.Element.add_pad() method. The following is a diagrammatic representation of a GStreamer element with a pad. It illustrates two GStreamer elements within a pipeline, having a single source and sink pad. Now that we know how the pads operate, let's discuss some of special types of pads. In the example, we assumed that the pads for the element are always 'out there'. However, there are some situations where the element doesn't have the pads available all the time. Such elements request the pads they need at runtime. Such a pad is called a dynamic pad. Another type of pad is called ghost pad. These types are discussed in this section.   Dynamic pads Some objects such as decodebin do not have pads defined when they are created. Such elements determine the type of pad to be used at the runtime. For example, depending on the media file input being processed, the decodebin will create a pad. This is often referred to as dynamic pad or sometimes the available pad as it is not always available in elements such as decodebin. Ghost pads As stated in the Bins section a bin object can act as an abstract element. How is it achieved? For that, the bin uses 'ghost pads' or 'pseudo link pads'. The ghost pads of a bin are used to connect an appropriate element inside it. A ghost pad can be created using gst.GhostPad class. Caps The element objects send and receive the data by using the pads. The type of media data that the element objects will handle is determined by the caps (a short form for capabilities). It is a structure that describes the media formats supported by the element. The caps are defined by the class gst.Caps. Bus A bus refers to the object that delivers the message generated by GStreamer. A message is a gst.Message object that informs the application about an event within the pipeline. A message is put on the bus using the gst.Bus.gst_bus_post() method. The following code shows an example usage of the bus. 1 bus = pipeline.get_bus()2 bus.add_signal_watch()3 bus.connect("message", message_handler) The first line in the code creates a gst.Bus instance. Here the pipeline is an instance of gst.PipeLine. On the next line, we add a signal watch so that the bus gives out all the messages posted on that bus. Line 3 connects the signal with a Python method. In this example, the message is the signal string and the method it calls is message_handler. Playbin/Playbin2 Playbin is a GStreamer plugin that provides a high-level audio/video player. It can handle a number of things such as automatic detection of the input media file format, auto-determination of decoders, audio visualization and volume control, and so on. The following line of code creates a playbin element. playbin = gst.element_factory_make("playbin") It defines a property called uri. The URI (Uniform Resource Identifier) should be an absolute path to a file on your computer or on the Web. According to the GStreamer documentation, Playbin2 is just the latest unstable version but once stable, it will replace the Playbin. A Playbin2 instance can be created the same way as a Playbin instance. gst-inspect-0.10 playbin2 With this basic understanding, let us learn about various audio processing techniques using GStreamer and Python.
Read more
  • 0
  • 0
  • 4728

article-image-microsoft-lightswitch-application-using-sql-azure-database
Packt
30 Aug 2010
3 min read
Save for later

Microsoft LightSwitch Application using SQL Azure Database

Packt
30 Aug 2010
3 min read
(For more resources on Microsoft, see here.) Your computer has to satisfy the system requirements that you can look up at the product site (while downloading) and you should have an account on Microsoft Windows Azure Services. Although this article retrieves data from SQL Azure, you can retrieve database from a local server or other data sources as well. However it is presently limited to SQL Server databases. The article content was developed using Microsoft LightSwitch Beta 1, SQL Azure database, on an Acer 4810TZ-4011 notebook with Windows 7 Ultimate OS. Installing Microsoft LightSwitch The LightSwitch beta is now available at this site here, the file name is vs_vslsweb.exe: http://www.microsoft.com/visualstudio/en-us/lightswitch When you download and install the program you may get into the problem that some requirement not being present. While installing the program for this article there was an initial problem. The Microsoft LightSwitch requires Microsoft SQL Server Compact 3.5 SP2. While this was already present on the computer it did not recognize. However in addition to SP2 there were also present the Microsoft SQL Server Compact 3.5 SP1 as well as SQL Server Compact 4.0. After removing Microsoft SQL Server Compact SP1 and SP2 the program installed without further problems after installing SQL Server Compact 3.5 SP2 again. Please review this link (http://hodentek.blogspot.com/2010/08/are-you-ready-to-see-light-with.html) for more detailed information. The next image shows the Compact products presently installed on this machine. Creating a LightSwitch Program After installation you may not find a shortcut that displays an icon for Microsoft LightSwitch. But you may find a Visual Studio 2010 shortcut as shown. The Visual Studio 2010 Express is a different product which is free to install. You cannot create a LightSwitch application with Visual Studio 2010 Express. Click on Microsoft Visual Studio 2010 shown highlighted. This opens the program with a splash screen. After a while the user interface displays the Start Page as shown. You can have more than one instance open at a time. The Recent Projects is a catalog of all projects in the Visual Studio 2010 default project directory. Just as you cannot develop a LightSwitch application with VS 2010 Express, you cannot open a project developed in VS 2010 Express with the LightSwitch interface as you will encounter the message shown. This means that LightSwitch projects are isolated in the development environment although the same shell program is used. When you click File | New Project you will see the New Project window displayed as shown here. Make sure you set the target to .NET Framework 4.0 otherwise you may not see any projects. It is strictly .NET Framework 4.0 for now. Also trying to create, File | New web site will not show any templates no matter what the .NET Framework you have chosen. In order to see Team Project you must have a Team Foundation Server present. In what follows we will be creating LightSwitch application (default name is Application1 for both C# and VB). From what is displayed you will see more Silverlight project templates than LightSwitch project templates. In fact you have just one template either in C# or in VB. Highlight LightSwitch Application (VB) and change the default name from Application1 to something different. Herein it is named SwitchOn as shown. If you were to look at the project properties in the property window you will see that the filename of the project is SwitchOn.lsproj. This file type is exclusively used by LightSwitch. The folder structure of the project is deceptively simple consisting of Data Sources and Screens.
Read more
  • 0
  • 0
  • 3078

article-image-customizing-avatar-flash-multiplayer-virtual-worlds
Packt
27 Aug 2010
5 min read
Save for later

Customizing an Avatar in Flash Multiplayer Virtual Worlds

Packt
27 Aug 2010
5 min read
(For more resources on Flash, see here.) Customizing your avatar A Flash virtual world is a social community in which players interact with each other and have their own identity. Virtual world usually lets a user decide the avatar's appearance by choosing the combination of different styles and colors. Customizing different styles Each part of the avatar will have different styles and shapes to form different combinations of the appearance of the avatar. Thanks to the timeline and movie clip features in Flash, we can put different styles of each part within the movie clip. For example, the following screenshot shows the head movie clip with different head styles placed frame by frame and we can use gotoAndStop to display the style we want. Customizing the color ActionScript supports changing the color transform for a given movie clip. It supports not only color tint but also applying color filter and detailed RGB transformation. We will use the simple color tint to change the color of the avatar. As the color transform is applying to the whole movie clip, we cannot simply tint the avatar movie clip because that will make the whole avatar tint to one solid color. In order to tint a partial part of the movie clip, we specifically create a movie clip in each part and name it color_area. We later program the ActionScript to change all movie clip names with color_area to the customized color. Adding customization to avatar class We are going to change the style and color by ActionScript in avatar class. We need to import the ColorTransform class in flash.geom package to change the color with ActionScript. import flash.geom.ColorTransform; We need several instance variables to hold the styles and color state. public const totalStyles:Number = 3;public var currentColor:Number = 0x704F4C;public var currentStyle:Number = 1; We wrap the whole block of color transform code into one function. The color transform adds RGB color transformation to the target movie clip. We only use colorTransform to tint the color here but it also supports percentage transform that adds partial color to the target movie clip. We will apply the color transform to the color area inside the head of the avatar in 4 directions. public function changeColor(newColor:Number = 0x000000):void { currentColor = newColor; for each(var avatar:MovieClip in _directionArray){ var avatarColor:ColorTransform = new ColorTransform(); avatarColor.color = newColor; avatar.head.color_area.transform.colorTransform = avatarColor; } } We modified the color by using color transform and used timeline to style the avatar style. Every frame in the head movie clip represents a style with its color tint area. We display the new style by changing the current frame of the avatar movie clip. It is also necessary to change the color again after switching the style because every style contains its own color area. public function changeStyle(styleNumber:int):void { for each(var avatar:MovieClip in _directionArray){ /* display the giving style in all parts of avatar*/ avatar.head.gotoAndStop(styleNumber); avatar.body.gotoAndStop(styleNumber); avatar.lefthand.gotoAndStop(styleNumber); avatar.righthand.gotoAndStop(styleNumber); /* need to apply the color again after changing the style */ var avatarColor:ColorTransform = new ColorTransform(); avatarColor.color = currentColor; avatar.head.color_area.transform.colorTransform = avatarColor; } currentStyle = styleNumber; } The purpose of the avatar class is to control the appearance of the avatar. We just implemented the direction, color, and style switching methods and it is now ready for customization panel to use. Designing a customization panel Avatars in virtual worlds and games often provide players with different kinds of customization. Some games allow users to customize the whole body with lots of options while some games may only provide two to three basic customizations. The layout design of the customization panel is often based on the number of options. There are two common customization panel layouts in the market. One layout displays arrows for a user to select next and previous styles. The other one displays a thumbnail view of the options within the same category. The arrows selection layout is suitable for an avatar that contains limited parts for customization. There may be only two to four categories and not many options in each category. Players can easily loop through different style combinations and choose their favorite one using this layout. The following avatar customization screenshot from the 2D Online RPG called Dragon Fable uses the arrows selection layout: The thumbnail view layout is suitable for avatars that can be highly customized. There are often many categories to customize and each category provides a lot of options for players to choose. Some virtual worlds even provide micro modification so that players can adjust details on the chosen style such as the distance between the eyes. Players do not need to iterate the large amount of styles and can quickly choose a style option among them with the thumbnail view. The following screenshot is an online Mii editor. Mii is the avatar system in the Nintendo Wii console. This is an online clone of the Mii avatar customization. It allows a large amount of avatar customization by the thumbnail view layout with extended features such as scaling and moving the elements.
Read more
  • 0
  • 0
  • 5545

article-image-configuring-and-deploying-ejb-30-entity-weblogic-server
Packt
27 Aug 2010
8 min read
Save for later

Configuring and Deploying the EJB 3.0 Entity in WebLogic Server

Packt
27 Aug 2010
8 min read
(For more resources on Oracle, see here.) Creating a Persistence Configuration file An EJB 3.0 entity bean is required to have a persistence.xml configuration file, which defines the database persistence properties. A persistence.xml file gets added to the META-INF folder when a JPA project is defined. Copy the following listing to the persistence.xml file in Eclipse: <?xml version="1.0" encoding="UTF-8" ?> <persistence xsi_schemaLocation= "http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="em"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/MySQLDS</jta-data-source> <class>ejb3.Catalog</class> <properties> <property name="eclipselink.target-server" value="WebLogic_10" /> <property name="javax.persistence.jtaDataSource" value="jdbc/ MySQLDS" /> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.target-database" value="MySQL" /> </properties> </persistence-unit> </persistence> The persistence-unit is required to be named and may be given any name. We had configured a JDBC data source with JNDI jdbc/MySQLDS in WebLogic Server. Specify the JNDI name in the jta-data-source element. The properties element specifies vendor-specific properties. The eclipselink.ddl-generation property is set to create-tables, which implies that the required database tables will be created unless they are already created . The persistence.xml configuration file is shown in the Eclipse project in the following illustration: (Move the mouse over the image to enlarge.) Creating a session bean For better performance, one of the best practices in developing EJBs is to access entity beans from session beans. Wrapping an entity bean with a session bean reduces the number of remote method calls as a session bean may invoke an entity bean locally. If a client accesses an entity bean directly, each method invocation is a remote method call and incurs an overhead of additional network resources. We shall use a stateless session bean, which consumes less resources than a stateful session bean, to invoke entity bean methods. In this section, we create a session bean in Eclipse. A stateless session bean class is just a Java class annotated with the @Stateless annotation. Therefore, we create Java classes for the session bean and session bean remote interface in Eclipse. To create a Java class, select File | New. In the New window, select Java | Class and click on Next> In the New Java Class window, select the Source folder as EJB3JPA/src, EJB3JPA being the project name. Specify Class Name as CatalogTestBean and click on Finish. Similarly, create a CatalogTestBeanRemote interface by selecting Java | Interface in the New window. The session bean class and the remote interface get added to the EJB3JPA project. The session bean class The stateless session bean class, CatalogTestBean implements the CatalogTestRemote interface. We shall use the EntityManager API to create, find, query, and remove entity instances. Inject an EntityManager using the @PersistenceContext annotation. Specify unitName as the same as the persistence-unit name in the persistence.xml configuration file: @PersistenceContext(unitName = "em") EntityManager em; Next, create a test() method, which we shall invoke from a test client. In the test() method we shall create and persist entity instances, query an entity instance, and delete an entity instance, all using an EntityManager object, which we had injected earlier in the session bean class. Injecting an EntityManager implies that an instance of EntityManager is made available to the session bean. Create an instance of the Entity bean class: Catalog catalog = new Catalog(new Integer(1), "Oracle Magazine", "Oracle Publishing", "September-October 2009", "Put Your Arrays in a Bind","Mark Williams"); Persist the entity instance to the database using the persist() method: em.persist(catalog); Similarly, persist two more entity instances. Next, create a query using the createQuery() method of the EntityManager object. The query string may be specified as a EJB-QL query. Unlike HQL, the SELECT clause is not optional in EJB-QL. Execute the query and return the query result as a List using the getResultList() method. As an example, select the catalog entry corresponding to author David Baum. The FROM clause of a query is directed towards the mapped entity bean class, not the underlying database. List catalogEntry =em.createQuery("SELECT c from Catalog c where c.author=:name").setParameter("name","David Baum"). getResultList(); Iterate over the result list to output the properties of the entity instance: for (Iterator iter = catalogEntry.iterator(); iter.hasNext(); ) { Catalog element = (Catalog)iter.next(); retValue =retValue + "<br/>" + element.getJournal() + "<br/>" + element.getPublisher() +"<br/>" + element.getDate() + "<br/>" + element.getTitle() + "<br/>" + element.getAuthor() +"<br/>"; } The variable retValue is a String that is returned by the test() method. Similarly, create and run a EJB-QL query to return all titles in the Catalog database: List allTitles =em.createQuery("SELECT c from Catalog c"). getResultList(); An entity instance may be removed using the remove() method: em.remove(catalog2); The corresponding database row gets deleted from the Catalog table. Subsequently, create and run a query to list all the entity instances mapped to the database. The session bean class, CatalogTestBean, is listed next: package ejb3; import java.util.Iterator; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; /** * Session Bean implementation class CatalogTestBean */ @Stateless(mappedName = "EJB3-SessionEJB") public class CatalogTestBean implements CatalogTestBeanRemote { @PersistenceContext(unitName = "em") EntityManager em; /** * Default constructor. */ public CatalogTestBean() { // TODO Auto-generated constructor stub } public String test() { Catalog catalog = new Catalog(new Integer(1), "Oracle Magazine", "Oracle Publishing", "September-October 2009", "Put Your Arrays in a Bind","Mark Williams"); em.persist(catalog); Catalog catalog2 = new Catalog(new Integer(2), "Oracle Magazine", "Oracle Publishing", "September-October 2009", "Oracle Fusion Middleware 11g: The Foundation for Innovation", "David Baum"); em.persist(catalog2); Catalog catalog3 = new Catalog(new Integer(3), "Oracle Magazine", "Oracle Publishing", "September-October 2009", "Integrating Information","David Baum"); em.persist(catalog3); String retValue = "<b>Catalog Entries: </b>"; List catalogEntry = em.createQuery("SELECT c from Catalog c where c.author=:name").setParameter("name", "David Baum").getResultList(); for (Iterator iter = catalogEntry.iterator(); iter.hasNext(); ) { Catalog element = (Catalog)iter.next(); retValue = retValue + "<br/>" + element.getJournal() + "<br/>" + element.getPublisher() + "<br/>" + element.getDate() + "<br/>" + element.getTitle() + "<br/>" + element.getAuthor() + "<br/>"; } retValue = retValue + "<b>All Titles: </b>"; List allTitles = em.createQuery("SELECT c from Catalog c").getResultList(); for (Iterator iter = allTitles.iterator(); iter.hasNext(); ) { Catalog element = (Catalog)iter.next(); retValue = retValue + "<br/>" + element.getTitle() + "<br/>"; } em.remove(catalog2); ); retValue = retValue + "<b>All Entries after removing an entry: </b>"; List allCatalogEntries = em.createQuery("SELECT c from Catalog c"). getResultList(); for (Iterator iter = allCatalogEntries.iterator(); iter.hasNext(); ) { Catalog element = (Catalog)iter.next(); retValue = retValue + "<br/>" + element + "<br/>"; } return retValue; } } We also need to add a remote or a local interface for the session bean: package ejb3; import javax.ejb.Remote; @Remote public interface CatalogTestBeanRemote { public String test(); } The session bean class and the remote interface are shown next: We shall be packaging the entity bean and the session bean in a EJB JAR file, and packaging the JAR file with a WAR file for the EJB 3.0 client into an EAR file as shown next: EAR File | | |-WAR File | |-EJB 3.0 Client |-JAR File | |-EJB 3.0 Entity Bean EJB 3.0 Session Bean Next, we create an application.xml for the EAR file. Create a META-INF folder for the application.xml. Right-click on the EJB3JPA project in Project Explorer and select New>Folder. In the New Folder window, select the EJB3JPA folder and specify the new Folder name as META-INF. Click on Finish. Right-click on the META-INF folder and select New | Other. In the New window, select XML | XML and click on Next. In the New XML File window, select the META-INF folder and specify File name as application.xml. Click on Next. Click on Finish. An application.xml file gets created. Copy the following listing to application.xml: <?xml version = '1.0' encoding = 'windows-1252'?> <application> <display-name></display-name> <module> <ejb>ejb3.jar</ejb> </module> <module> <web> <web-uri>weblogic.war</web-uri> <context-root>weblogic</context-root> </web> </module> </application> The application.xml in the Project Explorer is shown next:
Read more
  • 0
  • 3
  • 9206
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-designing-avatar-flash-multiplayer-virtual-worlds
Packt
27 Aug 2010
9 min read
Save for later

Designing an Avatar in Flash Multiplayer Virtual Worlds

Packt
27 Aug 2010
9 min read
(For more resources on Flash, see here.) Designing an avatar Avatar is very important in a virtual world because most of the features are designed around avatars. Users interact with each other via their avatars, they explore the virtual world via avatars, and they complete challenges to level up their avatars. An avatar is composited by graphics and animation. The avatar graphics are its looks. It is not a static image but a collection of images to display the directions and appearance. There are different approaches of drawing the avatar graphics depending on the render methods and how many directions and animations the avatar needs. Animations represent different actions of the avatar. The most basic animation is walking. Other animations such as hand waving and throwing objects are also common. There will be different animation sets for different virtual world designs. A fighting topic virtual world will probably contain a collection of fighting animation sets. A hunting topic virtual world will contain animations of collection items and using hunting tools. Determining the direction numbers of avatars' views Isometric tile is composed by diamond shapes with four-edge connection to the other tiles. It is not hard to imagine that every avatar in the isometric view may face towards four directions. They are the north east, south east, south west, and north west. However, sometimes using only these four directions may not be enough; some game designs may require the avatar to face the user or walk to the other isometric tile a cross the diamond corner. In this case, eight directions are required. The direction number of the avatars affects the artwork drawing directly. Just imagine that we are building a virtual world where players can fight with each other. How many animations are there for an avatar to fight? Say, five sets of animations. How many directions can the avatar faces? 4? 8? Or even 12? For example, we are now talking about five sets of animations with 8 directions of each avatar. That's already 40 animations for only one avatar. We may design the virtual world to have 12 kinds of avatars and each avatar to have different clothes for customization. The graphics workload keeps increasing when only one of these aspects increases. That's why I often consider different approaches that reduce the graphic workload of the avatars. Take four directions as an example. In most cases, we have very similar animations when the avatar is facing south-east and south-west. And the animation of north-east and north-west are similar too. Therefore, it is a common technique that mirrors the animation of west side into east side. It can be easily done in Flash by just changing the x-axis of the scaling property to between -1 and 1. This property results in the avatar flipping from one side to another side. For a 4-directions animation set, only 2 directions need to be drawn. In an 8-directions animation set, only 5 directions need to be drawn. Next, we will discuss the rendering methods that will conclude how the amount of directions, animations, and customization affect the graphic workload. Rendering avatars in Flash virtual world There are different approaches to render avatars in Flash virtual world. Each rendered method comes with both advantages and disadvantages. Some methods take more time to draw with fancy outlook while others may take more time to program. It is important to decide which rendering methods of the avatar are required in predevelopment stage. It will be much more difficult to change the rendering method after the project is in development. We will discuss different rendering methods and the pros and cons of them. Drawing an avatar using vector animation It is convenient to use the Flash native vector drawing for avatar because every drawing can be done within the Flash. The output can be cute and cartoon style. One advantage of using vector is that color customization is easy to implement by using the native ActionScript color transform. We can easily assign different colors to different parts of the avatar without extra graphic drawing. Another advantage of using vector animation is that we can scale up and down the avatars whenever needed. It is useful when we need to zoom in or out of the map and the avatars in the virtual world. The following graph shows the comparison of scaling up a vector and bitmap graphic: The disadvantage is that we need to draw the animation of every part of the avatar in every direction frame by frame. Flash tweening can help but the workload is heavier than other methods. We can prerender the animations or control them by ActionScript in methods discussed later. In vector animation, every animation is hand-drawn and thus any late modification on the avatar design can cost quite a lot of workload. There may not be too many directions of the avatars meaning the rotation of the avatars will not be very smooth. Rendering avatars using bitmap sprite sheet Sprite sheet is a graphics technique that is used in almost all game platforms. Sprite sheet is a large bitmap file that contains every frame of animation. Bitmap data from each frame is masked and rendered to the screen. A Flash developer may think that there is a timeline with frame one on the top left and counting the frame from left to right in each row from top to bottom. This technique is useful when the avatar graphic designer has experience in other game platforms. Another advantage of using bitmap data is faster rendering than vector in Flash player. The other advantage is the sprite sheet can be rendered from 3D software. For example, we can make an avatar model in Maya (http://autodesk.com/maya) or 3Ds Max (http://autodesk.com/3dsmax) with animations set up. Then we set up eight cameras with orthographic perspective. The orthographic perspective ensures the rendered image fits the isometric world. After setting up the scene, just render the whole animation with eight different cameras and we will get all the bitmap files of the avatar. The benefit is that the rendering process is automatic so that we can reduce the workload a lot. Later if we want to modify the character, we only need to modify it in the 3D software and render it again. One big disadvantage of using sprite sheet is the file size. The sprite sheets are in bitmap format and one set of animation can cost up to several hundred kilobytes. The file size can be very large when there are many animations and many more bitmaps for switching styles of the avatar. The other disadvantage is that changing color is quite difficult. Unlike vector rendering where color replacement can be done by ActionScript, we need to replace another bitmap data to change the color. That means every available color doubles the file size. Rendering avatars using real-time 3D engine We described how to use 3D software to prerender graphics of the avatars in the previous section. Instead of prerendering the graphics into 2D bitmap, we can integrate a Flash 3D engine to render the 3D model into isometric view in real time. Real-time 3D rendering is the next trend of Flash. There are several 3D engines available in the market that support rendering complex 3D models with animations. Papervision3D (http://blog.papervision3d.org/) and Away3D (http://away3d.com/) are two examples among them. The advantage of using 3D rendering in isometric is that the rotation of avatars can be very smooth. Also different textures can share the same model and different models can share the same animation skeleton. Thanks to this great graphic reusability, 3D rendering virtual world can create different combinations of avatar appearance and animations without adding extra graphic workload in development. However, one disadvantage of using 3D rendering is the Flash player performance. The latest version of Flash player is 10.1 at the time of writing. The following screenshots show that the CPU resources usage is very high when rendering the isometric 3D environment with three avatars on screen: Rendering avatars using 2D bone skeleton Bone skeleton used to be an uncommon method to render avatar. What it does is creates an animated skeleton and then glues different parts of body together onto the skeleton. It is somehow similar to the skeleton and mesh relationship in 3-D software but in two dimensions instead. A lot of mathematics is needed to calculate the position and rotation of each part of the body and make the implementation difficult. Thanks to the introduction of bone tool and inverse kinematics in Flash CS4, this technique is becoming more mature and easier to be used in the Flash world. Adobe has posted a tutorial about using bone tool to create a 2D character (http://www.adobe.com/devnet/flash/articles/character_animation_ik.html). The following screenshot shows another bone skeleton example from gotoAndPlay demonstrating how to glue the parts into a walking animation. The post can be found in this link: http://www.gotoandplay.it/_articles/2007/04/skeletal_animation.php The advantage of using 2D bone skeleton is that animations are controlled by ActionScript. The reusing of animations means this technique fits those game designs that require many animations. A dancing virtual world that requires a lot of different unique animations is one example that may need this technique. One disadvantage is that the large amount of mathematic calculation for the animations makes it difficult to implement. Every rendering methods has its own advantages and disadvantages and not one of the methods fits all type of games. It is the game designer's job to decide a suitable rendering method for a game or virtual world project. Therefore, it is important to know their limitations and consider thoughtfully before getting started with development. We can take a look at how other Flash virtual worlds render avatars by checking the showcase of the SmartFoxServer (http://www.smartfoxserver.com/showcase/).
Read more
  • 0
  • 0
  • 5461

article-image-developing-ejb-30-entity-weblogic-server
Packt
27 Aug 2010
3 min read
Save for later

Developing an EJB 3.0 entity in WebLogic Server

Packt
27 Aug 2010
3 min read
(For more resources on Oracle, see here.) Setting the environment In the following sections, we will learn how to set up the environment. Installing required products First, download and install the following required products; when installing the MySQL database, select the option to add the MySQL bin directory to the Windows system PATH environment variable: Oracle WebLogic Server 11g (http://www.oracle.com/technology/software/products/ias/htdocs/wls_main.html). Oracle Enterprise Pack for Eclipse All-In-One edition (http://www.oracle.com/technology/software/products/oepe/oepe_11113.html). MySQL 5.x database (http://www.oracle.com/us/products/mysql/index.html). Creating a MySQL database table Next, create a database table in the MySQL database as follows: Log in to the MySQL database with the following command: >mysql Set database as test: mysql>use test Run the following SQL script, which creates a Catalog table for the EJB 3 entity: CREATE TABLE Catalog (id INT PRIMARY KEY NOT NULL, journal VARCHAR(100), publisher VARCHAR(100), date VARCHAR(100), title VARCHAR(100), author VARCHAR(100)); The output from the CREATE TABLE SQL script is shown in the following screenshot: The table description may be listed with the desc command, as shown in the following illustration: Configuring WebLogic Server with MySQL database We shall be using a MySQL database for persistence. Therefore, we need to create a data source in WebLogic Server. Start the WebLogic Server and log in to the Administration Console. Creating a data source Select the base_domain | Services | JDBC | Data Sources. Click on New in the Data Sources table. Specify a data source name and a JNDI Name (jdbc/MySQLDS) for the data source. Select Database Type as MySQL and Database Driver as MySQL's Driver (Type 4): com.mysql.jdbc.Driver. Click on Next, as shown in the following screenshot: (Move the mouse over the image to enlarge.) In the Transaction Options window, select Supports Global Transactions and One-Phase Commit. Click on Next, as shown in the following screenshot: Specify the connection properties: Database Name as test, Host Name as localhost, Port as 3306, and Database User Name as root. Specify the Password used when installing MySQL and click on Next, as shown in the following screenshot: In the Test Database Connection window, the Driver Class Name and connection URL are specified, normally filled from the information you entered in the previous screen. Click on Test Configuration to test the connection. Click on Finish, as shown in the following screenshot: A data source gets added to the Data Sources table with its data source JNDI Name as jdbc/MySQLDS, as shown in the following screenshot: Deploying the data source Next, we deploy the data source to a target server. Click on the data source link in the Data Sources table and select the Targets tab. Select the AdminServer checkbox and click on Save, as shown in the following screenshot: The target server changes get applied and saved: Testing the data source To test the data source, click on Test Data Source. If the data source tests without an error, a message indicating the same gets displayed as shown next:
Read more
  • 0
  • 0
  • 2531

article-image-building-ejb-30-persistence-model-oracle-jdeveloper
Packt
27 Aug 2010
5 min read
Save for later

Building an EJB 3.0 Persistence Model with Oracle JDeveloper

Packt
27 Aug 2010
5 min read
(For more resources on Oracle, see here.) WebLogic server 10.x provides some value-added features to facilitate EJB 3 development. WebLogic server 10.x supports automatic deployment of a persistence unit based on the injected variable's name. The @javax.persistence. PersistenceContext and @javax.persistence.PersistenceUnit annotation s are used to inject the persistence context in an EntityManager or EntityManagerFactory variable . A persistence context is a set of entities that are mapped to a database with a global JNDI name. If the name of the injected variable is the same as the persistence unit, the unitName attribute of the @PersistenceContext or @PersistenceUnit is not required to be specified. The EJB container automatically deploys the persistence unit and sets its JNDI name to be the same as the persistence unit name in persistence.xml. For example, if the persistence unit name in the persistence.xml file is em, an EntityManager variable may be injected with the persistence context as follows: @PeristenceContextprivate EntityManager em; We did not need to specify the unitName attribute in the @PersistenceContext because the variable name is the same as the persistence unit. Similarly, an EntityManagerFactory variable may be injected with the persistence context as follows, emf being also the persistence unit name: @PersistenceUnitprivate EntityManagerFactory emf; Another value-added feature in WebLogic server 10.x is support for vendor-specific subinterfaces of the EntityManager interface. For example, the BEA Kodo persistence provider provides the KodoEntityManager subinterface, which may be injected with the persistence context as follows: @PersistenceContextprivate KodoEntityManager em; Setting the environment Before getting started, we need to install Oracle JDeveloper 11g, which may be downloaded from http://www.oracle.com/technology/products/jdev/index.html. Download the Studio Edition, which is the complete version of JDevloper with all the features. Oracle JDeveloper 11g is distributed as a GUI self-extractor application. Click on the jdevstudio11110 install application. The Oracle Installer gets started. Click on Next in the Oracle Installer. Choose a middleware home directory and click on Next: Choose the Install Type as Complete, which includes the integrated WebLogic Server, and click on Next: Confirm the default Product Installation directories and click on Next: The WebLogic Server installation directory is the wlserver_10.3 folder within the middleware home directory. Choose a shortcut location and click on Next. The Installation Summary lists the products that are installed, which include the WebLogic Server and the WebLogic JDBC drivers. Click on Next to install Oracle JDeveloper 11g and the integrated WebLogic Server 10.3. We also need to install the Oracle database 10g/11g or the lightweight Oracle XE, which may be downloaded from http://www.oracle.com/technology/software/products/database/index.html. When installing Oracle database, also install the sample schemas. Creating a datasource in JDeveloper Next, we create a JDBC datasource in JDeveloper. We shall use the datasource in the EJB 3.0 entity bean for database persistence. First, we need to create a database table in some sample schema, OE for example. Run the following SQL script in SQL *Plus: CREATE TABLE Catalog (id INTEGER PRIMARY KEY NOT NULL,journal VARCHAR(100), publisher VARCHAR(100), edition VARCHAR(100),title VARCHAR(100), author VARCHAR(100)); A database table gets created in the OE sample schema. Next, we need to create a JDBC connection in JDeveloper with Oracle database. Open the Database Navigator or select the Database Navigator tab if already open. Right-click on the IDE Connections node and select New Connection: In the Create Database Connection window, specify a Connection Name, select Connection Type as Oracle (JDBC), specify Username as OE, which is the schema in which the Catalog table is created, and specify the password for the OE schema. Select Driver as thin, Host Name as localhost, SID as ORCL, and JDBC Port as 1521. Click on the Test Connection button to test the connection. If the connection gets established, click on OK: The OracleDBConnection gets added to the Database Navigator view. The CATALOG table that we created is listed in the Tables: (Move the mouse over the image to enlarge.) Creating an EJB 3 application In this section, we create an EJB 3.0 application in JDeveloper. Select New Application: Specify an Application Name, select the Java EE Web Application template, which consists of a Model project and a ViewController project, and click on Next: Next, specify the name (EJB3ViewController) for the View and Controller project. In the Project Technologies tab, transfer the EJB project technology from the Available list to the Selected list using the > button. We have selected the EJB project technology, as we shall be creating an EJB 3.0 model. Click on Next: Select the default Java settings for the View project and click on Next: Configure the EJB Settings for the View project. Select EJB Version as Enterprise JavaBeans 3.0 and select Using Annotations. Click on Next. Next, create the Model project. Specify the Project Name (EJB3Model for example), and in the Project Technologies tab transfer the EJB project technology from the Available list to the Selected list using the > button. We have added the EJB project technology, as the EJB 3.0 application client is created in the View project. Click on Next: Select the default Java settings for the Model project and click on Next: Similar to the View project, configure the EJB settings for the Model project. Select EJB Version as Enterprise JavaBeans 3.0, select Using Annotations and click on Finish. As we won't be using a jndi.properties file or an ejb-jar.xml file , we don't need to select the generate option for the jndi.properties file and the ejb-jar.xml file: An EJB 3.0 application, which consists of a Model project and a ViewController project, get added in the Application tab: Select the EJB3Model project in the Application navigator and select Tools | Project Properties. In the Project Properties window, select the Libraries and Classpath node. The EJB 3.0 library should be in the Classpath Entries: Select the EJB Module node and select the OracleDBConnection in the Connection drop-down list. The datasource corresponding to the OracleDBConnection is jdbc/OracleDBConnectionDS.
Read more
  • 0
  • 0
  • 3263

article-image-styling-your-joomla-form-using-chronoforms
Packt
27 Aug 2010
11 min read
Save for later

Styling your Joomla! form using ChronoForms

Packt
27 Aug 2010
11 min read
(For more resources on ChronoForms, see here.) Introduction Styling forms is more a subject for a book on Joomla! templating, but as not all templates handle it very well, ChronoForms has some basic formatting capabilities that we will look at here. We'll look at two areas—applying CSS to change the "look and feel" of a form and some simple layout changes that may be helpful. We'll be assuming here that you have some knowledge of both CSS and HTML. Using ChronoForms default style ChronoForms recognizes that many Joomla! templates are not strong in their provision of form styling, so it offers some default styling that you can apply (or not) and edit to suit your needs. Getting ready It might be helpful to have a form to look at. Try creating a test form using the ChronoForms Wizard to add "one of each" of the main inputs to a new form and then save it. How to do it... Each of the five steps here describes a different way to style your forms. You can choose the one (or more) that best meets your needs: When you create a form with the Wizard, ChronoForms does three things: Adds some <div> tags to the form HTML to give basic structure Adds classes to the <div> tags and to the input tags to allow CSS styling Loads some default CSS that uses the classes to give the form a presentable layout If you look at the Form HTML created by the Wizard you will see something like this (this is a basic text input): <div class="form_item"> <div class="form_element cf_textbox"> <label class="cf_label" style="width: 150px;"> Click Me to Edit</label> <input class="cf_inputbox" maxlength="150" size="30" title="" id="text_2" name="text_2" type="text" /> </div> <div class="cfclear">&nbsp;</div></div> This example uses the default values from the Wizard. The label text, size, and name may have been changed in the Wizard Properties box. There is a wrapper <div> with a class of form_item. Then, there is a second wrapper around the <label> and <input> tags with two classes—form_element and cf_textbox. There are the <label> and <input> tags themselves with classes of cf_label and cf_inputbox respectively. And lastly there is an "empty" <div> with a class of cfclear that is used to end any CSS floats used in styling the previous tags. The coding for other types of input is very similar, and usually the only difference is the class of the input tag and the <div> tag wrapped around the label and the input. There is nothing very special about any of this; it provides a basic framework for styling. You can't change the default styling used by the Wizard but you can use your own HTML, or edit the Form HTML created by the Wizard. If you change the class names or override the ChronoForms CSS styling with your own styles, then the ChronoForms CSS will no longer apply. Here's what the test form looks like with the default ChronoForms styling: To see the effect of the ChronoForms CSS, open the form in the Form Editor. Go to the General tab, open Core/View Form Settings, and change Load Chronoforms CSS/ JS Files to No. Save the form and refresh the front-end view. Here is the same form without the ChronoForms CSS styling loaded. Not so pretty, but still fully functional. Note: If you create your form in the Form Editor rather than the Wizard, the default setting for Load Chronoforms CSS/JS Files is No. So, you need to turn it on if you want to use the default styling. See also W3Schools CSS tutorials and references at http://www.w3schools.com/css/ default.asp provide a useful online introduction to CSS Switching styles with "Transform Form" The ChronoForms default styling doesn't always suit. So, ChronoForms provides a basic form theming capability. There are only two themes provided—"default" and "theme1". Getting ready We're using the same form as in the previous recipe. How to do it... In the Forms Manager, check the box next to your form name and then click the Transform Form icon in the toolbar. You will see a warning that using Transform Form will overwrite any manual changes to the Form HTML and two form images—one for the "default" theme and one for "theme1". There's a radio button under each theme, and Preview and Transform & Save buttons at the bottom left. The Preview button allows you to see your form with the theme applied. This will not overwrite manual changes; Transform & Save will! Warning: Using Transform & Save will recreate the Form HTML from the version that ChronoForms has saved in the database table. Any manual changes that you have made to the Form HTML will be lost. Applying "theme1" changes the Form HTML structure significantly. Select the "theme1" radio button and click the Preview button to see the result. You can't see this from the preview screen but here's what the text input block now looks like: <div class="cf_item"> <h3 class="cf_title" style="width: 150px;"> Click Me to Edit</h3> <div class="cf_fields"> <input name="text_2" type="text" value="" title="" class="cf_inputtext cf_inputbox" maxlength="150" size="30" id="text_2" /> <br /> <label class="cf_botLabel"></label> </div></div> The wrapping <div> tags and the input are still the same; the old label is now an <h3> tag and there's a new <label> after the input with a cf_botlabel class. The <div> with the cfclear class has gone. This theme may work better with forms that need narrower layouts or where the cfclear <div> tags cause large breaks in the form layout. Neither theme creates a very accessible form layout, and "theme1" is rather less accessible than the "default" theme. If this is important for you then you can create your own form theme. How it works... A ChronoForms theme has two parts—a PHP file that defines the form elements and a CSS file that sets the styling. The Transform Form gets the "Wizard" version of your form that is saved in the database, and regenerates the form HTML using the element structures from the PHP file. When the file is loaded, the theme CSS file will be loaded instead of the default ChronoForms CSS. See also The article "Accessible Forms using WCAG 2.0" (http://www.usability.com.au/resources/wcag2/) is a practical introduction to the topic of web form accessibility. Adding your own CSS styling Many users will want to add their own styling to their forms. This is a short guide about ways to do that. It's not a guide to create the CSS. To add your own Form CSS, you will need to have a working knowledge of HTML and CSS. Getting ready You need nothing to follow the recipe, but when you come to it out, you'll need CSS and a form or two. How to do it... Adding CSS directly in the Form HTML: The quickest and least desirable way of styling is to add CSS directly to the Form HTML. The HTML is accessible on the Form Code tab in the Form Editor. You can type directly into the text area. For example: <input name="text_2" type="text" value="" title="" class="cf_inputtext cf_inputbox" maxlength="150" size="30" id="text_2" style="border: 1px solid blue;" /> The only time when you might need to use this approach is to mark one or two inputs in some special way. Even then it might be better to use a class and define the style outside the Form HTML. Using the Form CSS styles box: In the Form Code tab, ChronoForms has a CSS Styles box, which is opened by clicking the [+/-] link beside CSS Styles. You can add valid CSS definitions in this box (without <style> or </style> tags) and the CSS will be included in the page when it is loaded. For example, you could put this definition into the box: cf_inputbox { border: 1px solid blue; } This will add the following script snippet to the page. If you look at the page source for your form in the front-end you'll find it correctly loaded inside the <head> section. <style type="text/css">cf_inputbox { border: 1px solid blue; } </style> Editing the ChronoForms default CSS: If you have Load Chronoforms CSS/JS Files? set to Yes, then ChronoForms will apply one of its themes, the default one unless you have picked another. The theme CSS files that are used in the front-end are in the components/com_ chronocontact/themes/{theme_name}/css/ folder. Usually there are three files in the folder. The style1-ie6.css file is loaded if the browser detected is IE6; style1-ie7. css is loaded as well for IE7 or IE8; Lstyle1.css is loaded for other browsers. If you edit the ChronoForms CSS, you may need to edit all three files. Note: The themes are duplicated in the Administrator part of ChronoForms, but those files are used in the Transform Form page only. Editing the template CSS: If you want to apply styling more broadly across your site then you may want to integrate the Form CSS with your template style sheets. This is entirely possible; the only thing to make sure of is that the classes in your Form HTML are reflected in the template CSS. You can either manually edit the Form HTML or add the ChronoForms classes to your template styles sheets. Note that this is a much better approach than editing the ChronoForms theme CSS files. Upgrading ChronoForms could well overwrite the theme files. If you have the styles in your template's style sheets, this is not a problem. Creating a new ChronoForms theme is a better solution than editing the default themes as it is protected against overwriting, and allows you to change the layout of the HTML elements in the form. The simplest way to do this is to copy one of the existing theme folders, rename the copy, and edit the files in the new folder. The CSS files are straightforward, but the elements.php file needs a little explanation. If you open the file in an editor, you will find a series of code blocks that define the way in which ChronoForms will structure each of the form elements in the Wizard. Here is an example of a text input: <!--start_cf_textbox--><div class="form_item"> <div class="form_element cf_textbox"> <label class="cf_label"{cf_labeloptions}>{cf_labeltext} </label> <input class="{cf_class}" maxlength="{cf_maxlength}" size="{cf_size}" title="{cf_title}" id="{cf_id}" name="{cf_name}" type="{cf_type}" /> {cf_tooltip} </div> <div class="cfclear">&nbsp;</div></div><!--end_cf_textbox--> The comment lines at the beginning and end mark out this element and must be left intact. Between the comment lines you may add any valid HTML body tags that you like, except that the text input element must include <input type='text' . . . /> and so on. The entries in curly brackets, for example {cf_labeltext}, will be replaced by the corresponding values from the Properties box for this element in the Form Wizard. If they appear they must be exactly the same as the entries in the ChronoForms default theme. Most of the time you will not need to create a new theme, but if you are building Joomla! applications, this provides a very flexible way of letting users create forms with a predetermined structure and style. Note that if you create a new theme, you need to ensure that the files are the same in both theme folders (administrator/ components/com_chronocontact/themes/ and components/com_chronocontact/themes/). Maybe a future version of ChronoForms will remove the duplication.
Read more
  • 0
  • 0
  • 4337
article-image-syntax-validation-javascript-testing
Packt
26 Aug 2010
10 min read
Save for later

Syntax Validation in JavaScript Testing

Packt
26 Aug 2010
10 min read
(For more resources on JavaScript, see here.) So without further ado, let us get started with a lighter topic—the difference between validating and testing. The difference between validating and testing There's a thin line separating validating and testing. If you have some idea about sets (as in sets from mathematics), I would say that validation can lead to better testing results, while testing does not necessarily lead to a valid code. Let us consider the scenario—you wrote a JavaScript program and tested it on major browsers such as the Internet Explorer and Firefox; and it worked. In this case, you have tested the code to make sure that it is functional. However, the same code that you have created may or may not be valid; valid code is akin to writing a code that has the following characteristics: Well formed Has good coding style (such as proper indentation, well-commented code, properly spaced) Meets the specification of the language (in our case, JavaScript) There may come a point in time where you will notice that good coding style is highly subjective—there are various validators that may have different opinions or standards as to what is known as "good coding style". Therefore, if you do use different validators to validate your code, do not freak out if you see different advice for your coding style. This does not mean that valid code leads to code that is functional (as you will see later) and that code that is functional leads to validated code as both have different standards for comparison. However, valid code often leads to less errors, and code that is both functional and valid is often quality code. This is due to the fact that writing a piece of JavaScript code, that is both valid and correct, is much more difficult than just writing a code that is correct. Testing often means that we are trying to get the code working correctly; while validation is making sure that the code is syntactically correct, with good style and that it meets the specification of the language. While good coding styles may be subjective, there is often a coding style that is accepted by most programmers, such as, making sure that the code is properly commented, indented, and there is no pollution of the global namespace (especially in the case of JavaScript). To make the case clearer, following are three situations that you can consider: Code that is valid but wrong–validation doesn't find all the errors This form of errors would most probably be caused by logic errors in JavaScript. Logic errors can be syntactically correct but they may be logically flawed. A classic example would be an infinite for loop or infinite while loop. Code that is invalid but right This would most probably be the case for most functional code; a piece of JavaScript may be functionally correct and working, but it may be invalid. This may be due to poor coding style or any other characteristics in a valid code that are missing. Later on in this article, you will see a full working example of a piece of JavaScript code that is right but invalid. Code that is invalid and wrong–validation finds some errors that might be difficult to spot any other way In this case, the code error can be caused by all three forms of JavaScript errors that are mentioned in the article such as loading errors, runtime errors, and logic errors. While it is more likely that errors caused by syntax errors might be spotted by good validators, it is also possible that some errors are buried deep inside the code, such that it is difficult to spot them using manual methods. Now that we have some common understanding as to what validation and testing is about, let us move on to the next section which discusses the issues surrounding quality code. Code quality While there are many views as to what is quality code, I personally believe that there are a few agreed standards. Some of the most commonly mentioned standards may include code readability, ease of extension, efficiency, good coding style, and meeting language specifications, and so on. For our purpose here, we will focus on the factors that make a piece of code valid—coding style and meeting specifications. In general, good coding style almost guarantees that the code is highly readable (even to third parties) and this will help us to spot errors manually. Most importantly, having a good coding style allows us to quickly understand the code, specially if we need to work in teams or are required to debug the code on our own. You will notice that we will focus on the importance of code validity for testing purposes in later parts of the article. But now, let us start with the first building block of quality code—valid HTML and CSS. HTML and CSS needs to be valid before you start on JavaScript We have a common understanding that JavaScript breathes life into a web page by manipulating the Document Object Model (DOM) of the HTML documents. This means that the DOM must be present in the code before JavaScript can operate on it. Here's an important fact that is directly related to HTML, CSS, and browsers—browsers are generally forgiving towards invalid HTML and CSS code as compared to compilers for languages like C or Python. This is because, all browsers have to do is parse the HTML and CSS so as to render the web page for its browsers. On the other hand, compilers are generally unforgiving towards invalid code. Any missing tag, declarations, and so on will lead to a compilation error. Therefore, it is ok to write invalid or even buggy HTML and CSS, yet get a "usual" looking web page. Based on the previous explanation, we should see that we would need to have valid HTML and CSS in order to create quality JavaScript code. A short list of reasons, based on my personal experience, as to why valid HTML and CSS is an important prerequisite before you start working on JavaScript are as follows: Valid HTML and CSS helps ensure that JavaScript works as intended. For example, consider a situation where you might have two div elements that have the same id , code that is supposed to work on the above mentioned HTML element with the id. This will result in unintended consequences. Valid HTML and CSS helps improve the predictability on how your web page will work; there is no point trying to fi x buggy HTML or CSS using JavaScript. You are most probably better off if you start with valid HTML and CSS, and then apply JavaScript. Invalid HTML and CSS may result in different behaviour in different browsers. For example, an HTML tag that is not enclosed may be rendered differently in different browsers. In short, one of the most important building blocks of creating quality JavaScript code is to have valid HTML and CSS. What happens if you don't validate your code You may disagree with me on the previous section as to why HTML and CSS should be valid. In general, validation helps you to prevent errors that are related to coding style and specifications. However, do take note that using different validators may give you different results since validators might have different standards in terms of code style. In case you are wondering if invalid code can affect your JavaScript code, I would advise you to make your code as valid as possible; invalid code may lead to sticky issues such as cross-browser incompatibility, difficulty in reading code, and so on. Invalidated code means that your code may not be foolproof; in the early days of the Internet, there were websites that were dependent on the quirks of the early Netscape browser. Back track to the time where the Internet Explorer 6 was widely used, there were also many websites that worked in quirks mode to support Internet Explorer 6. Now, most browsers are supporting or are moving towards supporting web standards (though slightly different, they are supporting in subtle manners), writing valid code is one of the best ways to ensure that your website works and appears the way it is intended to. How validation can simplify testing While invalid code may not cause your code to be dysfunctional, valid code often simplifies testing. This is due to the focus on coding style and specifications; codes that are valid and have met specifications are typically more likely to be correct and much easier to debug. Consider the following code that is stylistically invalid: function checkForm(formObj){alert(formObj.id)//alert(formObj.text.value);var totalFormNumber = document.forms.length;// check if form elements are empty and are digitsvar maxCounter = formObj.length; // this is for checking for emptyvaluesalert(totalFormNumber);// check if the form is properly filled in order to proceedif(checkInput(formObj)== false){alert("Fields cannot be empty and it must be digits!");// stop executing the code since the input is invalidreturn false;}else{;}var i = 0;var formID;while(i < totalFormNumber){if(formObj == document.forms[i]){formID = i;alert(i);}i++;}if(formID<4){formID++;var formToBeChanged = document.forms[formID].id;// alert(formToBeChanged);showForm(formToBeChanged);}else{// this else statement deals with the last form// and we need to manipulate other HTML elementsdocument.getElementById("formResponse").style.visibility = "visible";}return false;} The previous code is an extreme example of poor code style, especially in terms of indentation. Imagine if you have to manually debug the second code snippet that you saw earlier! I am pretty sure that you will find it frustrating to check the code, because you will have little visual sense of what is going on. More importantly, if you are working in a team, you will be required to write legible code; in short, writing valid code typically leads to code that is more legible, easier to follow, and hence, less erroneous. Validation can help you debug your code As mentioned in the previous section, browsers are in general forgiving towards invalid HTML and CSS. While this is true, there may be errors that are not caught, or are not rendered correctly or gracefully. This means that while the invalid HTML and CSS code may appear fine on a certain platform or browser, it may not be supported on others. This means that using valid code (valid code typically means standard code set by international organizations such as W3C) will give you a much greater probability of having your web page rendered correctly on different browsers and platforms. With valid HTML and CSS, you can safely write your JavaScript code and expect it to work as intended, assuming that your JavaScript code is equally valid and error free. Validation helps you to code using good practices Valid code typically requires coding using good practices. As mentioned frequently in this article, good practices include the proper enclosing of tags, suitable indentation to enhance code readability, and so on. If you need more information about good practi ces when using JavaScript, feel free to check out the creator of JSLint, Douglas Crockford, at http://crockford.com.. Or you can read up John Resigs blog (the creator of JQuery) at http://ejohn.org. Both are great guys who know what great JavaScript is about. Validation To summarize the above sections, the DOM is provided by HTML, and both CSS and JavaScript are applied to the DOM. This means that if there is an invalid DOM, there is a chance that the JavaScript that is operating on the DOM (and sometimes the CSS) might result in errors. With this summary in mind, we'll focus on how you can spot validation errors by using color coding editors.
Read more
  • 0
  • 0
  • 3764

article-image-playback-audio-video-and-create-media-playback-component-using-javafx
Packt
26 Aug 2010
5 min read
Save for later

Playback Audio with Video and Create a Media Playback Component Using JavaFX

Packt
26 Aug 2010
5 min read
(For more resources on Java, see here.) Playing audio with MediaPlayer Playing audio is an important aspect of any rich client platform. One of the celebrated features of JavaFX is its ability to easily playback audio content. This recipe shows you how to create code that plays back audio resources using the MediaPlayer class. Getting ready This recipe uses classes from the Media API located in the javafx.scene.media package. As you will see in our example, using this API you are able to load, configure, and playback audio using the classes Media and MediaPlayer. For this recipe, we will build a simple audio player to illustrate the concepts presented here. Instead of using standard GUI controls, we will use button icons loaded as images. If you are not familiar with the concept of loading images, review the recipe Loading and displaying images with ImageView in the previous article. In this example we will use a JavaFX podcast from Oracle Technology Network TechCast series where Nandini Ramani discusses JavaFX. The stream can be found at http://streaming.oracle.com/ebn/podcasts/media/8576726_Nandini_Ramani_030210.mp3. How to do it... The code given next has been shortened to illustrate the essential portions involved in loading and playing an audio stream. You can get the full listing of the code in this recipe from ch05/source-code/src/media/AudioPlayerDemo.fx. def w = 400;def h = 200;var scene:Scene;def mediaSource = "http://streaming.oracle.com/ebn/podcasts/media/ 8576726_Nandini_Ramani_030210.mp3";def player = MediaPlayer {media:Media{source:mediaSource}}def controls = Group { layoutX:(w-110)/2 layoutY:(h-50)/2 effect:Reflection{ fraction:0.4 bottomOpacity:0.1 topOffset:3 } content:[ HBox{spacing:10 content:[ ImageView{id:"playCtrl" image:Image{url:"{__DIR__}play-large.png"} onMouseClicked:function(e:MouseEvent){ def playCtrl = e.source as ImageView; if(not(player.status == player.PLAYING)){ playCtrl.image = Image{url:"{__DIR__}pause-large.png"} player.play(); }else if(player.status == player.PLAYING){ playCtrl.image = Image{url:"{__DIR__}play-large.png"} player.pause(); } } } ImageView{id:"stopCtrl" image:Image{url:"{__DIR__}stop-large.png"} onMouseClicked:function(e){ def playCtrl = e.source as ImageView; if(player.status == player.PLAYING){ playCtrl.image = Image{url:"{__DIR__}play-large.png"} player.stop(); } } } ]} ]} When the variable controls is added to a scene object and the application is executed, it produces the screen shown in the following screenshot: How it works... The Media API is comprised of several components which, when put together, provides the mechanism to stream and playback the audio source. To playback audio requires two classes, including Media and MediaPlayer. Let's take a look at how these classes are used to playback audio in the previous example. The MediaPlayer—the first significant item in the code is the declaration and initialization of a MediaPlayer instance assigned to the variable player. To load the audio file, we assign an instance of Media to player.media. The Media class is used to specify the location of the audio. In our example, it is a URL that points to an MP3 file. The controls—the play, pause, and stop buttons are grouped in the Group object called controls. They are made of three separate image files: play-large.png, pause-large.png, and stop-large.png, loaded by two instances of the ImageView class. The ImageView objects serve to display the control icons and to control the playback of the audio: When the application starts, imgView displays image play-large.png. When the user clicks on the image, it invokes its action-handler function, which firsts detects the status of the MediaPlayer instance. If it is not playing, it starts playback of the audio source by calling player.play() and replaces the play-large.png with the image pause-large.png. If, however, audio is currently playing, then the audio is stopped and the image is replaced back with play-large.png. The other ImageView instance loads the stop-large.png icon. When the user clicks on it, it calls its action-handler to first stop the audio playback by calling player.stop(). Then it toggles the image for the "play" button back to icon play-large.png. As mentioned in the introduction, JavaFX will play the MP3 file format on any platform where the JavaFX format is supported. Anything other than MP3 must be supported natively by the OS's media engine where the file is played back. For instance, on my Mac OS, I can play MPEG-4, because it is a supported playback format by the OS's QuickTime engine. There's more... The Media class models the audio stream. It exposes properties to configure the location, resolves dimensions of the medium (if available; in the case of audio, that information is not available), and provides tracks and metadata about the resource to be played. The MediaPlayer class itself is a controller class responsible for controlling playback of the medium by offering control functions such as play(), pause(), and stop(). It also exposes valuable playback data including current position, volume level, and status. We will use these additional functions and properties to extend our playback capabilities in the recipe Controlling media playback in this article. See also Accessing media assets Loading and displaying images with ImageView  
Read more
  • 0
  • 0
  • 3619

article-image-manipulating-images-javafx
Packt
25 Aug 2010
4 min read
Save for later

Manipulating Images with JavaFX

Packt
25 Aug 2010
4 min read
(For more resources on Java, see here.) One of the most celebrated features of JavaFX is its inherent support for media playback. As of version 1.2, JavaFX has the ability to seamlessly load images in different formats, play audio, and play video in several formats using its built-in components. To achieve platform independence and performance, the support for media playback in JavaFX is implemented as a two-tiered strategy: Platform-independent APIs—the JavaFX SDK comes with a media API designed to provide a uniform set of interfaces to media functionalities. Part of the platform-independence offerings include a portable codec (On2's VP6), which will play on all platforms where JavaFX media playback is supported. Platform-dependent implementations—to boost media playback performance, JavaFX also has the ability to use the native media engine supported by the underlying OS. For instance, playback on the Windows platform may be rendered by the Windows DirectShow media engine (see next recipe). This two-part article shows you how to use the supported media rendering components, including ImageView, MediaPlayer, and MediaView. These components provide high-level APIs that let developers create applications with engaging and interactive media content. Accessing media assets You may have seen the use of variable __DIR__ when accessing local resources, but may not fully know about its purpose and how it works. So, what does that special variable store? In this recipe, we will explore how to use the __DIR__ special variable and other means of loading resources locally or remotely. Getting ready The concepts presented in this recipe are used widely throughout the JavaFX application framework when pointing to resources. In general, classes that point to a local or remote resource uses a string representation of a URL where the resource is stored. This is especially true for the ImageView and MediaPlayer classes discussed in this article. How to do it... This recipe shows you three ways of creating a URL to point to a local or remote resource used by a JavaFX application. The full listing of the code presented here can be found in ch05/source-code/src/UrlAccess.fx. Using the __DIR__ pseudo-variable to access assets as packaged resources: var resImage = "{__DIR__}image.png"; Using a direct reference to a local file: var localImage = "file:/users/home/vladimir/javafx/ch005/source-code/src/image.png"; Using a URL to access a remote file: var remoteImage = "http://www.flickr.com/3201/2905493571_a6db13ce1b_d.jpg" How it works... Loading media assets in JavaFX requires the use of a well-formatted URL that points to the location of the resources. For instance, both the Image and the Media classes (covered later in this article series) require a URL string to locate and load the resource to be rendered. The URL must be an absolute path that specifies the fully-realized scheme, device, and resource location. The previous code snippets show the following three ways of accessing resources in JavaFX: __DIR__ pseudo-variable—often, you will see the use of JavaFX's pseudo variable __DIR__, used when specifying the location of a resource. It is a special variable that stores the String value of the directory where the executing class that referenced __DIR__ is located. This is valuable, especially when the resource is embedded in the application's JAR file. At runtime, __DIR__ stores the location of the resource in the JAR file, making it accessible for reading as a stream. In the previous code, for example, the expression {__DIR__}image.png explodes as jar:file:/users/home/vladimir/javafx/ch005/source-code/dist/source-code.jar!/image.png. Direct reference to local resources—when the application is deployed as a desktop application, you can specify the location of your resources using URLs that provides the absolute path to where the resources are located. In our code, we use file:/users/home/vladimir/javafx/ch005/source-code/src/image.png as the absolute fully qualified path to the image file image.png. Direct reference to remote resources—finally, when loading media assets, you are able to specify the path of a fully-qualified URL to a remote resource using HTTP. As long as there are no subsequent permissions required, classes such as Image and Media are able to pull down the resource with no problem. For our code, we use a URL to a Flickr image http://www.flickr.com/3201/2905493571_a6db13ce1b_d.jpg. There's more... Besides __DIR__, JavaFX provides the __FILE__ pseudo variable as well. As you may well guess, __FILE__ resolves to the fully qualified path of the of the JavaFX script file that contains the __FILE__ pseudo variable. At runtime, when your application is compiled, this will be the script class that contains the __FILE__ reference.
Read more
  • 0
  • 0
  • 5839
article-image-building-facebook-clone-using-ruby
Packt
25 Aug 2010
8 min read
Save for later

Building the Facebook Clone using Ruby

Packt
25 Aug 2010
8 min read
(For more resources on Ruby, see here.) This is the largest clone and has many components. Some of the less interesting parts of the code are not listed or described here. To get access to the full source code please go to http://github.com/sausheong/saushengine. Configuring the clone We use a few external APIs in Colony so we need to configure our access to these APIs. In a Colony all these API keys and settings are stored in a Ruby file called config.rb as below. S3_CONFIG = {}S3_CONFIG['AWS_ACCESS_KEY'] = '<AWS ACCESS KEY>'S3_CONFIG['AWS_SECRET_KEY'] = '<AWS SECRET KEY>'RPX_API_KEY = '<RPX API KEY>' Modeling the data You will find a large number of classes and relationships in this article. The following diagram shows how the clone is modeled: User The first class we look at is the User class. There are more relationships with other classes and the relationship with other users follows that of a friends model rather than a followers model. class User include DataMapper::Resource property :id, Serial property :email, String, :length => 255 property :nickname, String, :length => 255 property :formatted_name, String, :length => 255 property :sex, String, :length => 6 property :relationship_status, String property :provider, String, :length => 255 property :identifier, String, :length => 255 property :photo_url, String, :length => 255 property :location, String, :length => 255 property :description, String, :length => 255 property :interests, Text property :education, Text has n, :relationships has n, :followers, :through => :relationships, :class_name => 'User', :child_key => [:user_id] has n, :follows, :through => :relationships, :class_name => 'User', :remote_name => :user, :child_key => [:follower_id] has n, :statuses belongs_to :wall has n, :groups, :through => Resource has n, :sent_messages, :class_name => 'Message', :child_key => [:user_id] has n, :received_messages, :class_name => 'Message', :child_key => [:recipient_id] has n, :confirms has n, :confirmed_events, :through => :confirms, :class_name => 'Event', :child_key => [:user_id], :date.gte => Date.today has n, :pendings has n, :pending_events, :through => :pendings, :class_name => 'Event', :child_key => [:user_id], :date.gte => Date.today has n, :requests has n, :albums has n, :photos, :through => :albums has n, :comments has n, :activities has n, :pages validates_is_unique :nickname, :message => "Someone else has taken up this nickname, try something else!" after :create, :create_s3_bucket after :create, :create_wall def add_friend(user) Relationship.create(:user => user, :follower => self) end def friends (followers + follows).uniq end def self.find(identifier) u = first(:identifier => identifier) u = new(:identifier => identifier) if u.nil? return u end def feed feed = [] + activities friends.each do |friend| feed += friend.activities end return feed.sort {|x,y| y.created_at <=> x.created_at} end def possessive_pronoun sex.downcase == 'male' ? 'his' : 'her' end def pronoun sex.downcase == 'male' ? 'he' : 'she' end def create_s3_bucket S3.create_bucket("fc.#{id}") end def create_wall self.wall = Wall.create self.save end def all_events confirmed_events + pending_events end def friend_events events = [] friends.each do |friend| events += friend.confirmed_events end return events.sort {|x,y| y.time <=> x.time} end def friend_groups groups = [] friends.each do |friend| groups += friend.groups end groups - self.groups endend As mentioned in the design section above, the data used in Colony is user-centric. All data in Colony eventually links up to a user. A user has following relationships with other models: A user has none, one, or more status updates A user is associated with a wall A user belongs to none, one, or more groups A user has none, one, or more sent and received messages A user has none, one, or more confirmed and pending attendances at events A user has none, one, or more user invitations A user has none, one, or more albums and in each album there are none, one, or more photos A user makes none, one, or more comments A user has none, one, or more pages A user has none, one, or more activities Finally of course, a user has one or more friends Once a user is created, there are two actions we need to take. Firstly, we need to create an Amazon S3 bucket for this user, to store his photos. after :create, :create_s3_bucketdef create_s3_bucket S3.create_bucket("fc.#{id}")end We also need to create a wall for the user where he or his friends can post to. after :create, :create_walldef create_wall self.wall = Wall.create self.saveend Adding a friend means creating a relationship between the user and the friend. def add_friend(user) Relationship.create(:user => user, :follower => self) end Colony treats the following relationship as a friends relationship. The question here is who will initiate the request to join? This is why when we ask the User object to give us its friends, it will add both followers and follows together and return a unique array representing all the user's friends. def friends (followers + follows).uniqend In the Relationship class, each time a new relationship is created, an Activity object is also created to indicate that both users are now friends. class Relationship include DataMapper::Resource property :user_id, Integer, :key => true property :follower_id, Integer, :key => true belongs_to :user, :child_key => [:user_id] belongs_to :follower, :class_name => 'User', :child_key => [:follower_id] after :save, :add_activity def add_activity Activity.create(:user => user, :activity_type => 'relationship', :text => "<a href='/user/#{user.nickname}'>#{user.formatted_name}</a> and <a href='/user/#{follower.nickname}'>#{follower.formatted_name}</a> are now friends.") end end Finally we get the user's news feed by taking the user's activities and going through each of the user's friends, their activities as well. def feed feed = [] + activities friends.each do |friend| feed += friend.activities end return feed.sort {|x,y| y.created_at <=> x.created_at}end Request We use a simple mechanism for users to invite other users to be their friends. The mechanism goes like this: Alice identifies another Bob whom she wants to befriend and sends him an invitation This creates a Request class which is then attached to Bob When Bob approves the request to be a friend, Alice is added as a friend (which is essentially making Alice follow Bob, since the definition of a friend in Colony is either a follower or follows another user) class Request include DataMapper::Resource property :id, Serial property :text, Text property :created_at, DateTime belongs_to :from, :class_name => User, :child_key => [:from_id] belongs_to :user def approve self.user.add_friend(self.from) endend Message Messages in Colony are private messages that are sent between users of Colony. As a result, messages sent or received are not tracked as activities in the user's activity feed. class Message include DataMapper::Resource property :id, Serial property :subject, String property :text, Text property :created_at, DateTime property :read, Boolean, :default => false property :thread, Integer belongs_to :sender, :class_name => 'User', :child_key => [:user_id] belongs_to :recipient, :class_name => 'User', :child_key => [:recipient_id] end A message must have a sender and a recipient, both of which are users. has n, :sent_messages, :class_name => 'Message', :child_key => [:user_id]has n, :received_messages, :class_name => 'Message', :child_key => [:recipient_id] The read property tells us if the message has been read by the recipient, while the thread property tells us how to group messages together for display. Album An activity is logged, each time an album is created. class Album include DataMapper::Resource property :id, Serial property :name, String, :length => 255 property :description, Text property :created_at, DateTime belongs_to :user has n, :photos belongs_to :cover_photo, :class_name => 'Photo', :child_key => [:cover_photo_id] after :save, :add_activity def add_activity Activity.create(:user => user, :activity_type => 'album', :text => "<a href='/user/#{user.nickname}'>#{user.formatted_name}</a> created a new album <a href='/album/#{self.id}'>#{self.name}</a>") end end
Read more
  • 0
  • 0
  • 2431

article-image-basics-exception-handling-mechanism-javascript-testing
Packt
25 Aug 2010
6 min read
Save for later

Basics of Exception Handling Mechanism in JavaScript Testing

Packt
25 Aug 2010
6 min read
(For more resources on JavaScript, see here.) Issues with combining scripts Consider the real-life situation where we typically use external JavaScript; what happens if we use more than one JavaScript file? What kind of issues can we expect if we use more than one external JavaScript file? We'll cover all of this in the subsections below. We'll start with the first issue—combining event handlers. JavaScript helps to bring life to our web page by adding interactivity. Event handlers are the heartbeat of interactivity. For example, we click on a button and a pop-up window appears, or we move our cursor over an HTML div element and the element changes color to provide visual feedback. To see how we can combine event handlers, consider the following example, which is found in the source code folder in the files combine-event-handlers.html and combine-event-handlers.js as shown in the following code: In combine-event-handlers.html, we have: <html> <head> <title>Event handlers</title> <script type="text/javascript" src="combine-event- handlers.js"></script> </head> <body> <div id="one" onclick="changeOne(this);"><p>Testing One</p></div> <div id="two" onclick="changeTwo(this);"><p>Testing Two</p></div> <div id="three" onclick="changeThree(this);"><p>Testing Three</p></div> </body></html> Notice that each of the div elements is handled by different functions, namely, changeOne(), changeTwo(), and changeThree() respectively. The event handlers are found in combine-event-handlers.js: function changeOne(element) { var id = element.id; var obj = document.getElementById(id); obj.innerHTML = ""; obj.innerHTML = "<h1>One is changed!</h1>"; return true;}function changeTwo(element) { var id = element.id; var obj = document.getElementById(id); obj.innerHTML = ""; obj.innerHTML = "<h1>Two is changed!</h1>"; return true;}function changeThree(element) { var id = element.id; var obj = document.getElementById(id); obj.innerHTML = ""; obj.innerHTML = "<h1>Three is changed!</h1>"; return true;} You might want to go ahead and test the program. As you click on the text, the content changes based on what is defined in the functions. However, we can rewrite the code such that all of the events are handled by one function. We can rewrite combine-event-handlers.js as follows: function combine(element) { var id = element.id; var obj = document.getElementById(id); if(id == "one"){ obj.innerHTML = ""; obj.innerHTML = "<h1>One is changed!</h1>"; return true;}else if(id == "two"){ obj.innerHTML = ""; obj.innerHTML = "<h1>Two is changed!</h1>"; return true;}else if(id == "three"){ obj.innerHTML = ""; obj.innerHTML = "<h1>Three is changed!</h1>"; return true;}else{ ; // do nothing }} When we use if else statements to check the id of the div elements that we are working on, and change the HTML contents accordingly, we will save quite a few lines of code. Take note that we have renamed the function to combine(). Because we have made some changes to the JavaScript code, we'll need to make the corresponding changes to our HTML. So combine-event-handlers.html will be rewritten as follows: <html> <head> <title>Event handlers</title> <script type="text/javascript" src="combine-event- handlers.js"></script> </head> <body> <div id="one" onclick="combine(this);"><p>Testing One</p></div> <div id="two" onclick="combine(this);"><p>Testing Two</p></div> <div id="three" onclick="combine(this);"><p>Testing Three</p></div> </body></html> Notice that the div elements are now handled by the same function, combine(). These rewritten examples can be found in combine-event-handlers-combined.html and combine-event-handlers-combined.js. Naming clashes Removing name clashes is the next issue that we need to deal with. Similar to the issue of combining event handlers, naming clashes occur when two or more variables, functions, events, or other objects have the same name. Although these variables or objects can be contained in different files, these name clashes do not allow our JavaScript program to run properly. Consider the following code snippets: In nameclash.html, we have the following code: <html> <head> <title>testing</title> <script type="text/javascript" src="nameclash1.js"></script> </head> <body> <div id="test" onclick="change(this);"><p>Testing</p></div> </body></html> In nameclash1.js, we have the following code: function change(element) { var id = element.id; var obj = document.getElementById(id); obj.innerHTML = ""; obj.innerHTML = "<h1>This is changed!</h1>"; return true;} If you run this code by opening the file in your browser and clicking on the text Testing, the HTML contents will be changed as expected. However, if we add &ltscript type="text/javascript" src="nameclash2.js"></script> after the &lttitle></title> tag, and if the content of nameclash2.js is as follows: function change(element) { alert("so what?!");} Then we will not be able to execute the code properly. We will see the alert box instead of the HTML contents being changed. If we switch the arrangement of the external JavaScript, then the HTML contents of the div elements will be changed and we will not be able to see the alert box. With such naming clashes, our program becomes unpredictable; the solution to this is to use unique names in your functions, classes, or events. If you have a relatively large program, it would be advisable to use namespaces, which is a common strategy in several JavaScript libraries such as YUI and jQuery.
Read more
  • 0
  • 0
  • 1985
Modal Close icon
Modal Close icon