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-tips-tricks-ext-js-3x
Packt
30 Nov 2010
3 min read
Save for later

Tips & Tricks for Ext JS 3.x

Packt
30 Nov 2010
3 min read
  Learning Ext JS 3.2 Build dynamic, desktop-style user interfaces for your data-driven web applications using Ext JS Learn to build consistent, attractive web interfaces with the framework components Integrate your existing data and web services with Ext JS data support Enhance your JavaScript skills by using Ext's DOM and AJAX helpers Extend Ext JS through custom components An interactive tutorial packed with loads of example code and illustrative screenshots           Read more about this book       (For more resources on Ext JS, see here.) Objective: Button focus and tab orders are built in. Tip: Button focus and tab orders are built into Ext JS Components. For the MessageBox Component, the OK or Yes button will be the default action, so pressing Enter on our keyboard when a MessageBox appears will trigger that button, and pressing Tab will move us through the buttons and other items in the MessageBox. Windows have the ESC key mapped to the Close tool. When using button bars in other Componenets, tabbing through the buttons is enabled by default and in Toolbars like the PagingToolbar tabbing is also built in. Objective: Duplicate Component ID's must be avoided. Tip: Having duplicate IDs in our document can lead to strange behavior, such as a widgets always showing up in the upper-left corner of the browser, and must therefore be avoided. Objective: Other uses of Button config on a MessageBox. Tip: The buttons config for a MessageBox can also specify the text to display on the button. Instead of passing a Boolean value, just pass it the desired text to display, for example, {yes: 'Maybe'}. Objective: Ext does not require any pre-existing markup. Tip: Ext does not require any pre-existing markup for it to function, this is because it generates everything it needs on its own. This let's us start with a very simple HTML document containing an empty body. Objective: Avoid using the built in JavaScript alert messages. Tip: Standard JavaScript alert messages pause code execution, which can cause unexpected results. You should not be using the built in JavaScript alert messages, and instead use Ext's MessageBox widget or console messages (when available), which does not pause that code execution. Objective: Creating form Field validation types (vType). Tip: A search of the Ext JS forum is likely to come back with a vType that someone else has created with exactly what you need, or close enough to use as a starting point for your own requirements, so search the Ext JS Forums before trying to write your own. Objective: Simple and quick static options for a ComboBox. Tip:; A quick way to specify a few static options for a ComboBox is to pass an array to the store config, which will auto-create the store for you. So if we wanted a ComboBox that had 'Yes' and 'No' as options, we would provide ['Yes','No'] as the store config value.
Read more
  • 0
  • 0
  • 3093

article-image-web-services-microsoft-azure
Packt
29 Nov 2010
8 min read
Save for later

Web Services in Microsoft Azure

Packt
29 Nov 2010
8 min read
A web service is not one single entity and consists of three distinct parts: An endpoint, which is the URL (and related information) where client applications will find our service A host environment, which in our case will be Azure A service class, which is the code that implements the methods called by the client application A web service endpoint is more than just a URL. An endpoint also includes: The bindings, or communication and security protocols The contract (or promise) that certain methods exist, how these methods should be called, and what the data will look like when returned A simple way to remember the components of an endpoint is A/B/C, that is, address/bindings/contract. Web services can fill many roles in our Azure applications—from serving as a simple way to place messages into a queue, to being a complete replacement for a data access layer in a web application (also known as a Service Oriented Architecture or SOA). In Azure, web services serve as HTTP/HTTPS endpoints, which can be accessed by any application that supports REST, regardless of language or operating system. The intrinsic web services libraries in .NET are called Windows Communication Foundation (WCF). As WCF is designed specifically for programming web services, it's referred to as a service-oriented programming model. We are not limited to using WCF libraries in Azure development, but we expect it to be a popular choice for constructing web services being part of the .NET framework. A complete introduction to WCF can be found at http://msdn.microsoft.com/en-us/netframework/aa663324.aspx. When adding WCF services to an Azure web role, we can either create a separate web role instance, or add the web services to an existing web role. Using separate instances allows us to scale the web services independently of the web forms, but multiple instances increase our operating costs. Separate instances also allow us to use different technologies for each Azure instance; for example, the web form may be written in PHP and hosted on Apache, while the web services may be written in Java and hosted using Tomcat. Using the same instance helps keep our costs much lower, but in that case we have to scale both the web forms and the web services together. Depending on our application's architecture, this may not be desirable. Securing WCF Stored data are only as secure as the application used for accessing it. The Internet is stateless, and REST has no sense of security, so security information must be passed as part of the data in each request. If the credentials are not encrypted, then all requests should be forced to use HTTPS. If we control the consuming client applications, we can also control the encryption of the user credentials. Otherwise, our only choice may be to use clear text credentials via HTTPS. For an application with a wide or uncontrolled distribution (like most commercial applications want to be), or if we are to support a number of home-brewed applications, the authorization information must be unique to the user. Part of the behind-the-services code should check to see if the user making the request can be authenticated, and if the user is authorized to perform the action. This adds additional coding overhead, but it's easier to plan for this up front. There are a number of ways to secure web services—from using HTTPS and passing credentials with each request, to using authentication tokens in each request. As it happens, using authentication tokens is part of the AppFabric Access Control, and we'll look more into the security for WCF when we dive deeper into Access Control. Jupiter Motors web service In our corporate portal for Jupiter Motors, we included a design for a client application, which our delivery personnel will use to update the status of an order and to decide which customers will accept delivery of their vehicle. For accounting and insurance reasons, the order status needs to be updated immediately after a customer accepts their vehicle. To do so, the client application will call a web service to update the order status as soon as the Accepted button is clicked. Our WCF service is interconnected to other parts of our Jupiter Motors application, so we won't see it completely in action until it all comes together. In the meantime, it will seem like we're developing blind. In reality, all the components would probably be developed and tested simultaneously. Creating a new WCF service web role When creating a web service, we have a choice to add the web service to an existing web role or create a new web role. This helps us deploy and maintain our website application separately from our web services. And in order for us to scale the web role independently from the worker role, we'll create our web service in a role separate from our web application. Creating a new WCF service web role is very simple—Visual Studio will do the "hard work" for us and allow us to start coding our services. First, open the JupiterMotors project. Create the new web role by right-clicking on the Roles folder in our project, choosing Add, and then select the New Web Role Project… option. When we do this, we will be asked what type of web role we want to create. We will choose a WCF Service Web Role, call it JupiterMotorsWCFRole, and click on the Add button. Because different services must have unique names in our project, a good naming convention to use is the project name concatenated with the type of role. This makes the different roles and instances easily discernable and complies with the unique naming requirement. This is where Visual Studio does its magic. It creates the new role in the cloud project, creates a new web role for our WCF web services, and creates some template code for us. The template service created is called "Service1". You will see both, a Service1.svc file as well as an IService1.vb file. Also, a web.config file (as we would expect to see in any web role) is created in the web role and is already wired up for our Service1 web service. All of the generated code is very helpful if you are learning WCF web services. This is what we should see once Visual Studio finishes creating the new project: We are going to start afresh with our own services—we can delete Service1.svc and IService1.vb. Also, in the web.config file, the following boilerplate code can be deleted (we'll add our own code as needed): <system.serviceModel> <services> <service name="JupiterMotorsWCFRole.Service1" behaviorConfiguration="JupiterMotorsWCFRole. Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="basicHttpBinding" contract="JupiterMotorsWCFRole.IService1"> <!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="JupiterMotorsWCFRole.Service1Behavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> Let's now add a WCF service to the JupiterMotorsWCFRole project. To do so, right-click on the project, then Add, and select the New Item... option. We now choose a WCF service and will name it as ERPService.svc: Just like the generated code when we created the web role, ERPService.svc as well as IERPService.vb files were created for us, and these are now wired into the web.config file. There is some generated code in the ERPService.svc and IERPService.vb files, but we will replace this with our code in the next section. When we create a web service, the actual service class is created with the name we specify. Additionally, an interface class is automatically created. We can specify the name for the class; however, being an interface class, it will always have its name beginning with letter I. This is a special type of interface class, called a service contract. The service contract provides a description of what methods and return types are available in our web service.
Read more
  • 0
  • 0
  • 7497

article-image-introduction-drupal-web-services
Packt
29 Nov 2010
13 min read
Save for later

Introduction to Drupal Web Services

Packt
29 Nov 2010
13 min read
  Drupal Web Services Integrate social and multimedia Web services and applications with your Drupal Web site. Explore different Web services and how they integrate with the Drupal CMS. Reuse the applications without coding them again using the Web services protocols on your Drupal site. Configure your Drupal site to consume various web services by using contributed Drupal modules for each specific task or application. Drive the content from your Drupal site to Facebook, Twitter and LinkedIn using effective Drupal Web services An easy to follow guide that opens up a method of easily sharing data and content resources between applications and machines that are running different platforms and architecture.       What are web services? In order for our Drupal site to communicate and interact with other web applications, such as Flickr, Amazon, Mollom, or Twitter, we need to use standard communication protocols in the web development world called web services. Web service protocols will allow applications that reside on external websites and servers to interact and communicate with our Drupal website that is running on our own server. Web services will also allow our Drupal site to pass along content and data to external web applications existing on remote servers. When we define web services, we need to point out that this type of communication provides for interoperability. This means that a web service communication can happen between two completely different environments but still work because we use standard protocols to make it happen. Web services allow us to call another application on a remote server. A good analogy to this is using your cell phone to call a friend or colleague. You have one type of cell phone using one type of cell phone service. You call your colleague's cell phone. They have another type of cell with a different service provider, but the call goes through and is successful because the two services communicate with each other using standard cell phone communication protocols. The web service call happens through coded protocols that are translated into a language and standard protocol that both computers can understand. Generally, this is done by using the XML language to translate the programmed request into the other external applications. Web applications have a standard in which they can usually read XML files. XML is a text-based format, so nearly all computer systems and applications can work with the XML format. The web services protocol also uses a concept called remoting or Remote Procedure Calling (RPC) that allows one application to initiate or "call" a function inside of an application on a remote server. Our Drupal site can communicate with an application on a remote server and call a function in that application. For example, we might want to make our Drupal website call and interact with our Flickr photo gallery, or we may want to take all of our Drupal home page content and push it over to our Facebook account. We can do both of these actions using the web service protocols. XML and web services As mentioned above, the base foundation for web services is a protocol or code called XML. For our Drupal site residing on our server, to talk and interact with a website or application on another server, we need to use XML, which is a language commonly understood between different applications. Our site and server understands XML as does the application we want to communicate with. We can do this over the standard HTTP protocol for website communication, as HTTP is the most standard protocol for Internet communication. The reason we use XML for communication between the applications and the sites is because XML replaces the proprietary function (whether the function is in RPC or another programming language or interface) and formats it into the standard XML code format. This allows applications to understand each other easily. An analogy to this is: if we have two people, one from Germany and the other from France, speaking to one another, and neither person knows the other's language but both of them know English, then they must speak in English, as it's a language they both understand and can easily communicate in. It's a similar situation when XML is used to translate a web service's function into a commonly understood format. So first we need to send the function call to a remote application. Our calling application or website creates the XML document that will represent the programmed function we want to execute. The XML is then transmitted over HTTP to the remote application and it can then be interpreted and understood by the remote application. The remote application then executes the function based on the XML formatting. Some examples of web service's methods are SOAP (Simple Object Access Protocol), UDDI (Universal Description, Discovery and Integration), WSDL (Web Services Description Language), XML-RPC (XML Remote Procedure Call), JSON (JavaScript Object Notation), JSON-RPC, REST (Representational State Transfer), and AMF (Action Message Format). We are not going to look at these interfaces in detail now. For now, it's helpful for us to understand that these protocols and platforms exist and that our Drupal site can provide web services to other applications via these multiple interfaces and platforms. Here's a diagram that outlines a simple web service request and response. This is a request sent from our Drupal site (client) over HTTP to an external server to request data. The data exists on the server (remote) in the form of a URI (Uniform Resource Identifier) item. The response is sent back to our Drupal site through XML. The REST protocol Let's look briefly at one web service protocol and technology, and define it. As mentioned before, there are many technologies you can use to implement web services. REST (Representational State Transfer) is one such technology. The reason REST is a preferred technology within the web development and Drupal community is due to its flexibility and standards. REST allows us to do the following when we initiate a web service using its protocol: Use a standard method such as XML as our message format Send the message over standard protocol such as HTTP Provide or connect to specific resources where each resource (image, document, page, and node) is given a unique resource identifier (a URI) We can take this concept and try it out on our Drupal site by writing some PHP code that makes an HTTP request to another web application resource. For example, we may want to make a call to a Picasa photo gallery and feed a select number and type of photos back to our Drupal site and display the photos in a Drupal node on our site. The request targets this specific resource by making a GET request to the URI of the resource. The application we are communicating with sends a response back to us in XML format. That XML can then be integrated into our Drupal site using a module, for example. The request might be made to a user's Flickr or Picasa photo gallery. The request gets returned to our Drupal site as XML and we parse this XML into our Drupal site and the user's photos or gallery then get displayed on our site. This is just one protocol example. Greg Hines of pingVision provides a good introductory resource on REST and Drupal in the document titled RESTful Web Services and Drupal. The document is available on pingVision's website as a PDF download from: http://pingvision.com/files/restful_web_services_and_drupal.pdf Standards compliance As discussed in the REST protocol's example, web services and Drupal's use of web services follow specific standards. In order to maintain as much interoperability and flexibility as possible, all of the protocols used respond for the most part using XML as the standard response mechanism and format. Additionally, all the communication between services, in our example between a client and a server, happens over HTTP (the standard web protocol). This is a uniform protocol that is used for transport and communication of the service. All transports take place uniformly using GET, POST, PUT, and DELETE requests, for example. The HTTP requests are stateless, meaning that the request over HTTP happens once at one given moment and is isolated from all other activated requests. So the request stands alone. If it succeeds, it gets a response. If it fails, it gets no response from the server or application it's communicating with. The request can be repeated an infinite number of times. Finally, all of the resources we try and access are those that we are sending to another application using a unique resource identifier (URI) to identify and define what they are. So images on our site have unique identifiers as well as those residing in another web application. Each of these unique identifiers allows for addresses or locations for each node or file in question. So each resource in a web service's communication has an address. Each resource has one URI and each address has one URI. Some examples of this would be the following locations on my Drupal site: http://variantcube.com/ http://variantcube.com/recommended-drupal-resources http://variantcube.com/node/68 http://variantcube.com/search/node/podcast http://variantcube.com/rss.xml Another reason we want to be standards compliant, when writing or working with web services, is for simplicity. We do not need any special tools to program web services as long as we follow these standards. We can use the web application modules and PHP, and stick to these coding standards and protocols. Why are web services useful? Web services are useful for a number of reasons, especially when it comes to Drupal and Drupal's relationship and interaction with other web content management systems and applications. The web has a huge number of web applications, so web developers and content developers can pass their content to the web browsers and make it available to the web visitors. This is why the Internet is useful to us. We can go to a website and view the content. Whenever we do that, we're looking at content that is proprietary to a specific web application. In Drupal, our content is in the form of nodes, for example. We may want to share these nodes with other websites that are non-Drupal, such as a Wordpress-powered site. Web services are useful because they present us with an architecture where a resource on a site (an image, textual content, such as a node ID or block ID, a video or audio file) is given a unique identifier. For example, in Drupal, every node has an ID. Every file you upload to a Drupal site also has a unique path to it. This is extremely useful since all applications share this common semantic standard. We name things similarly on all of our web applications. We can then leverage this by writing code in PHP, for example, the one that calls these resources. The application server that houses the resource then responds to our request using an XML document. Why use web services in Drupal? With web services, we can take our Drupal content and share this content with other web applications and, essentially, with the web at large. Our content is no longer just our content and it is not specific to our Drupal website. It can be shared and integrated. Drupal's codebase is PHP-based and many of the popular web applications being used today, including Wordpress, Joomla!, and Flickr, are also PHP-based. So we have a common programming language we can work with and use to integrate these applications. Here are some concrete examples. Perhaps your Human Resources Department wants to integrate its job postings and applications with another web application such as Monster.com. Web services can allow this to happen. Your office's payroll department may want to connect to its bank account in order to pass data from the payroll reports over to its bank reporting mechanism. Web services can allow this to happen. You may want to take all of the photos you upload to your Drupal site in image galleries built with the Views module, and take these photos and send them to Flickr so that they automatically show up in your Flickr account or on Flickr's public site. Web services can make this happen. This leads to another advantage of using web services with Drupal and why we would choose to use Drupal in the first place. Instead of having to upload our photos twice—once to our Drupal site and then repeating the procedure to our Flickr site—web services allows us to upload the images to our Drupal site once and then automatically send that data over to Flickr without having to upload one (or even a batch of images) again. It saves us time and speeds up the entire process of generating web-based content. Additionally, there may be applications we want to use in our Drupal site, for example applications where we want to consume content without having to code again. We can just reuse these applications using the web services protocols and get this application content into our Drupal site. So we can consume web services. Examples of this would be converting currency on our site, feeding weather reports and other weather data into our site, feeding natural disaster scientific data into our site from services that provide it, feeding language translation services, feeding music podcasts, and more. Instead of having to reprogram this type of content, we can grab it from another web application and show it automatically on our site using web services Simply put, this opens up a method of easily sharing data and content resources between applications and machines that are running on different platforms and architecture. We have opened up a gold mine of capabilities here because we can talk to applications that run different software from our Drupal site and on different computing platforms. How Drupal uses web services Drupal can use web services following any of the protocols mentioned earlier, including XML-RPC, REST, and SOAP. Drupal can consume web services by requesting data from other web applications using RSS and XML-formatted requests. As a web developer, you can write your own service code in Drupal using PHP. You can also use the Services module as well as other service-specific contributed modules to create these web service requests. In this next section, we're going to look at both these examples. First, we'll see how Drupal works as a service consumer, where basically it is a client requesting data from an external server. We'll also look at how Drupal can provide services using the Services module, RSS, AMFPHP, and XML-RPC. Drupal as a service consumer Let's outline some brief examples of how Drupal consumes content and data from other web applications, including Mollom, Flickr, and Facebook. You can configure your Drupal site to consume various web services by using contributed Drupal modules for each specific task or application you are trying to consume. Drupal can consume services from applications that will help your website prevent spam, integrate photos, integrate taxonomy and tags, and enhance your Drupal free tagging and autotagging abilities, and integrate with applications such as Facebook and Twitter.
Read more
  • 0
  • 0
  • 3731

article-image-portal-and-drag-and-drop-features-ext-gwt
Packt
29 Nov 2010
5 min read
Save for later

Portal and Drag-and-Drop Features of Ext GWT

Packt
29 Nov 2010
5 min read
  Ext GWT 2.0: Beginner's Guide Portlet class The Portlet class extends ContentPanel to provide a special type of panel that can be repositioned in the Viewport by the user with a Portal container. It may appear similar to a window in a desktop application. Creating a Portlet is similar to creating other containers. This code: Portlet portlet = new Portlet(); portlet.setHeight(150); portlet.setHeading("Example Portlet"); creates a Portlet like this: A Portlet can be excluded from being repositioned by pinning it using: portal.setPinned(true); Apart from that, a Portlet inherits all the features of a standard ContentPanel. The Portal class A Portal is a special container for Portlet components. In fact, it is a Container containing a collection of LayoutContainer components arranged using ColumnLayout. Each of those LayoutContainer components in turn is able to contain Portlet components, arranged using a RowLayout. Portal also supports dragging and dropping of Portlet components, both in terms of changing the row it is in within a column and the column within the Portal. When creating a Portal, we need to set the number of columns the Portal should create in the constructor. We also need to set the widths of each column before using the setColumnWidth method of the Portal. So to create a Portal with two columns, (one using 30 percent of the width and the second 70 percent) we would define it as follows: Portal portal = new Portal(2); portal.setColumnWidth(0, 0.3); portal.setColumnWidth(1, 0.7); We can then add a Portlet to each column like this: Portlet portlet1 = new Portlet(); portlet1.setHeight(150); portlet1.setHeading("Example Portlet 1"); portal.add(portlet1, 0); Portlet portlet2 = new Portlet(); portlet2.setHeight(150); portlet2.setHeading("Example Portlet 2"); portal.add(portlet2, 1); This will produce the following output: Both Portlet components can be dragged and dropped into different positions. The Portlet turns into a blue box while being dragged as shown in the following screenshot: A Portlet will automatically resize and ft into the column in which it is dropped, as seen in the next screenshot: ToolButton Like ContentPanel that Portlet extends, we can add ToolButton components to the header. These can be very useful for making a Portlet look and behave even more like windows in a desktop application. portlet.getHeader().addTool(new ToolButton("x-tool-minimize")); portlet.getHeader().addTool(new ToolButton("x-tool-maximize")); portlet.getHeader().addTool(new ToolButton("x-tool-close")); The output can be seen as shown in the following screenshot: At the moment, we are using ContentPanel components in our example application and laying them out using a BorderLayout. We shall now see that it does not take much to change the ContentPanel components into Portlet components and manage them using a Portal. Portlet components are ideally suited to being independent, self-contained user interface elements that respond to the data passed to them. Rather than tying them into a Portal directly, we can use the MVC components to cause the Portal to respond to the creation of a new Portlet to preserve that independence. Time for action – creating a Portal Controller and a Portlet View The first thing we need to do is add a new EventType to the existing AppEvents class named NewPortletCreated. We will fire this when we create a new Portlet. public static final EventType NewPortletCreated = new EventType(); Create a new class named PortalController that extends Controller. public class PortalController extends Controller { Create a new class named PortalView that extends View. public class PortalView extends View { Create a constructor that sets the Controller of the PortalView. public PortalView(PortalController portalController) { super(portalController); } Returning to PortalController, create a variable to hold the PortalView and override the initialize method to set the view. private PortalView portalView; @Override public void initialize() { super.initialize(); portalView = new PortalView(this); } Create a constructor that registers each EventType the PortalController should observe, specifically NewPortletCreated creation and Error. public PortalController() { registerEventTypes(AppEvents.NewPortletCreated ); registerEventTypes(AppEvents.Error); } Override the handleEvent method to forward any events to the View apart from errors which for the time being we will just log to the GWT log. @Override public void handleEvent(AppEvent event) { EventType eventType = event.getType(); if (eventType.equals(AppEvents.error)) { GWT.log("Error", (Throwable) event.getData()); } else { forwardToView(portalView, event); } } Returning to PortalView, create a new portal field consisting of a Portal component with two columns. private final Portal portal = new Portal(2); Override the initialize method to set the width of the two columns, the first to 30 percent of the width of the Portal and the second to 70 percent. @Override protected void initialize() { portal.setColumnWidth(0, 0.3); portal.setColumnWidth(1, 0.7); } Now create a Viewport, set the layout to FitLayout, add the Portal, and then add the Viewport to GWT's RootPanel. @Override protected void initialize() { portal.setColumnWidth(0, 0.3); portal.setColumnWidth(1, 0.7); final Viewport viewport = new Viewport(); viewport.setLayout(new FitLayout()); viewport.add(portal); RootPanel.get().add(viewport); } We also need to implement the handleEvent method of the View. For now, we will catch the NewPortletCreated event, but we will not do anything with it yet. @Override protected void handleEvent(AppEvent event) { EventType eventType = event.getType(); if (eventType.equals(AppEvents.NewPortletCreated )) { } } Finally, go to the onModuleLoad method of the EntryPoint RSSReader class and instead of creating an AppController, create a PortalController, and remove the line that forwards an Init AppEvent, as we will not be using it. The onModuleLoad method will now look like this: public void onModuleLoad() { final FeedServiceAsync feedService = GWT.create(FeedService.class); Registry.register(RSSReaderConstants.FEED_SERVICE, feedService); Dispatcher dispatcher = Dispatcher.get(); dispatcher.addController(new PortalController()); } What just happened? We created the basic framework for a Portal layout of our application. However, if we started it now, we would just get a blank screen. What we need to do is add Portlet components. The actual Portlet components are not too complicated. They will just act as wrappers.
Read more
  • 0
  • 0
  • 1841

article-image-article-campaign-customer-delight-3
Packt
26 Nov 2010
1 min read
Save for later

test- December Campaign 2

Packt
26 Nov 2010
1 min read
            Packt Customer Delight Fest        Packt is pleased to announce its ‘Customers Delight Fest’ this festival season.  This season mainly aims to appreciate, recognize and reward its valued customers.  As a token of appreciation we are pleased to announce an exclusive offer empowering you to purchase any 5 eBooks of your own choice for only $40. Joomla! E-Commerce with VirtueMart Build feature-rich online stores with Joomla! 1.0/1.5 and VirtueMart 1.1.x. Read more. Joomla! 1.5 Multimedia Build media-rich Joomla! web sites by learning to embed and display Multimedia content. Read more Joomla! 1.5 Development Cookbook   Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes. Read more Joomla! 1.5x Customization: Create and customize a professional Joomla! site that suits your business requirements. Read more Joomla! 1.5 Templates  Cookbook Over 60 simple but incredibly effective recipes for taking control of Joomla! templates. Read more
Read more
  • 0
  • 0
  • 629

article-image-article-campaign-customer-delight-1
Packt
26 Nov 2010
1 min read
Save for later

test- December Campaign

Packt
26 Nov 2010
1 min read
                                             Packt Customer Delight Fest                                                      Packt is pleased to announce its ‘Customers Delight Fest’ this festival season.  This season mainly aims to appreciate, recognize and reward its valued customers.  As a token of appreciation we are pleased to announce an exclusive offer empowering you to purchase any 5 eBooks of your own choice for only $40. Joomla! E-Commerce with VirtueMart Build feature-rich online stores with Joomla! 1.0/1.5 and VirtueMart 1.1.x. Read more. Joomla! 1.5 Multimedia Build media-rich Joomla! web sites by learning to embed and display Multimedia content. Read more Joomla! 1.5 Development Cookbook Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes. Read more Joomla! 1.5x Customization: Make Your Site Adapt to Your Needs Create and customize a professional Joomla! site that suits your business requirements. Read more Joomla! 1.5 Templates  Cookbook Over 60 simple but incredibly effective recipes for taking control of Joomla! templates. Read more
Read more
  • 0
  • 0
  • 865
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-replication-alert-monitor-monitoring-management
Packt
26 Nov 2010
10 min read
Save for later

Replication Alert Monitor: Monitoring Management

Packt
26 Nov 2010
10 min read
IBM InfoSphere Replication Server and Data Event Publisher Design, implement, and monitor a successful Q replication and Event Publishing project Covers the toolsets needed to implement a successful Q replication project Aimed at the Linux, Unix, and Windows operating systems, with many concepts common to z/OS as well A chapter dedicated exclusively to WebSphere MQ for the DB2 DBA Detailed step-by-step instructions for 13 Q replication scenarios with troubleshooting and monitoring tips Written in a conversational and easy to follow manner We use the ASNMCMD command to manage a running RAM monitor. When we issue the asnmcmd command, we need to specify: The monitor server name The monitor name And then one of the following keywords: chgparms <parameters>, reinit, status, stop, qryparms, suspend, resume. Where <parameters> can be: monitor_interval=<n>, autoprune= [yn], alert_prune_limit=<n>, trace_limit=<n>, max_notifications_per_alert=<n>, max_notifications_minutes=<n>| We can issue this command from a different screen from which the monitor was started. Checking which monitors are active To check which monitors are active, we can use the ASNMCMD command with the STATUS parameter. So to check the status of the monac1 monitor on mondb, we would issue: $ asnmcmd MONITOR_SERVER=mondb MONITOR_QUAL=monac1 STATUS ASN0600I "AsnMcmd" : "" : "Initial" : Program "asnmcmd 9.1.0" is starting. ASN0520I "AsnMcmd" : "MONAC1" : "Initial" : The STATUS command response: "HoldLThread" thread is in the "is resting" state. ASN0520I "AsnMcmd" : "MONAC1" : "Initial" : The STATUS command response: "AdminThread" thread is in the "is resting" state. ASN0520I "AsnMcmd" : "MONAC1" : "Initial" : The STATUS command response: "WorkerThread" thread is in the "is resting" state. If there is nothing running, then we get the following messages: ASN0600I "AsnMcmd" : "" : "Initial" : Program "asnmcmd 9.1.0" is starting. ASN0506E "AsnMcmd" : "ASN" : "Initial" : The command was not processed. The "Monitor" program is presumed down. Note that there is a slight delay of a few seconds between the ASN0600I message and the ASN0506E message. We can check when a monitor last ran using the following query: $ db2 "SELECT SUBSTR(monitor_qual,1,10) AS monqual, last_monitor_time, start_monitor_time, end_monitor_time, lastrun, lastsuccess, status FROM asn.ibmsnap_monservers" MONQUAL LAST_MONITOR_TIME START_MONITOR_TIME MONAC1 2007-03-16-10.18.57.750000 2007-03-16-10.18.57.750000 END_MONITOR_TIME 2007-03-16-10.18.59.765000 LASTRUN LASTSUCCESS STATUS 2007-03-16-10.18.57.750000 2007-03-16-10.18.57.750000 0 Changing or reinitializing a monitor If we change any of the following while the monitor is running such as contact information, alert conditions, or parameter values: $ asnmcmd MONITOR_SERVER=mondb MONITOR_QUAL=monac1 CHGPARMS MONITOR_INTERVAL=10 Then we do not have to stop and start the monitor, we can just reinitialize it as follows: $ asnmcmd MONITOR_SERVER=mondb MONITOR_QUAL=monac1 REINIT Stopping a monitor To stop a monitor called monac1, we would issue the following command: $ asnmcmd MONITOR_SERVER=mondb MONITOR_QUAL=monac1 STOP Suspending or resuming a monitor We cannot suspend a monitor from the Replication Center, we can only use ASNCLP scripts. We can stop checking Q Capture and Q Apply for all defined alert conditions using the ASNMCMD SUSPEND command. When we want to resume monitoring again, then we issue the ASNMCMD RESUME command. Note that using the ANSMCMD command is an all or nothing approach. The SUSPEND option will suspend all monitoring qualifiers. So what happens if we just want to suspend monitoring one monitored sever (DB2A or DB2B)? In this case, we would have to create a monitor suspension. We can suspend a monitor once only or on a repeatable basis. If we want to suspend a monitor on a repeatable basis, then it's best to first create a suspension template and then create a monitor suspension. If we want to suspend a monitor server once only, then we just need to create a monitor suspension. All dates and times for monitor suspensions are based on the clock at the system where the monitor is running (MONDB). The time format is HH:MM:SS and the date format is YYYY-MM-DD. The ASNCLP command to create a monitor suspension template is: CREATE MONITOR SUSPENSION TEMPLATE <template_name> START TIME <starting_time> REPEATS occ-clause Where occ_clause can be: DAILY FOR DURATION <n> [HOURS | MINUTES] Or: WEEKLY DAY OF WEEK <day> FOR DURATION <n> [HOURS/MINUTES/DAYS] Where <day> can be Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, or Saturday. The ASNCLP command to create a monitor suspension is: CREATE MONITOR SUSPENSION <name> [FOR SERVER <server_name> | ALIAS <server_alias>] STARTING DATE <date> [USING TEMPLATE <template_name> | STARTING TIME <starting_time>] ENDING DATE <date> ENDING TIME <ending_time> So when should we use templates? We should use them: If we want to suspend more than one monitor at the same date or time. If we want to suspend a monitor on anything but a daily basis. Note that, we can specify a day of week when we create a monitor suspension template, which is not possible in the monitor suspension definition. There are eight ASNCLP commands which deal with monitor suspensions: ASNCLP command:Description:LIST MONITOR SUSPENSIONGenerates a list of suspensions on a monitor control server.ALTER MONITOR SUSPENSIONAllows us to change the following properties of a monitor suspension: • The template that is used • The start or end date for using a template • The start or end date for suspending the monitor program one timeDROP MONITOR SUSPENSIONDeletes a monitor suspension from the monitor control tables.LIST MONITOR SUSPENSION TEMPLATEGenerates a list of monitor suspension templates on a monitor control server.ALTER MONITOR SUSPENSION TEMPLATEAllows us to change the frequency and length of monitor suspensions as defined in a suspension template.DROP MONITOR SUSPENSION TEMPLATEDeletes a monitor suspension template from the monitor control tables.CREATE MONITOR SUSPENSION TEMPLATECreates a monitor suspension template.CREATE MONITOR SUSPENSIONCreates a monitor suspension. Even though we want to monitor Q replication, we need to specify SQL replication in the ASNCLP SESSION line. So let's look at the ASNCLP command to create a monitor suspension template called LUNCH which starts daily at 12:00 and lasts for one hour: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; CREATE MONITOR SUSPENSION TEMPLATE lunch START TIME 12:00:00 REPEATS DAILY FOR DURATION 1 HOURS; In the preceding command, we have not specified a server on which to apply the suspension—we have only defined the monitor server where to store the metadata. We have also not specified a start and end date—only a start and end time. Once we have created a monitor suspension template, we can define a monitor suspension for a specific server (that is, source or target) and a specific date range, which uses the template we defined previously. ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; SET SERVER TARGET TO DB db2b; CREATE MONITOR SUSPENSION NAME s1 FOR SERVER db2b STARTING DATE 2007-03-20 USING TEMPLATE lunch ENDING DATE 2007-12-31; In the above monitor suspension code, we do not have to specify a time value, because the time value is specified in the template definition. Note that now we have to specify a server for the template to work against. We can also define a monitor suspension without making reference to a template by specifying all the information that we need (this would be the once only processing model): CREATE MONITOR SUSPENSION NAME s2 FOR SERVER db2a STARTING DATE 2007-03-20 STARTING TIME 12:00:00 ENDING DATE 2007-12-31 ENDING TIME 13:00:00 In the above monitor suspension definition we have not specified a template, so we have included the start and end dates and times. We can list our monitor suspension templates and monitor suspensions using the following ASNCLP command: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; LIST MONITOR SUSPENSION TEMPLATE; LIST MONITOR SUSPENSION; This produces the following output: ==== CMD: LIST MONITOR SUSPENSION TEMPLATE; ==== TEMPLATE NAME START TIME FREQUENCY DURATION UNITS ------------------ ---------- --------- -------- ------- LUNCH 12:00:00 SUNDAY 1.0 HOURS 1 Template(s) found. ==== CMD: LIST MONITOR SUSPENSION; ==== SUSPENSION NAME SERVER NAME TEMPLATE NAME FREQUENCY DURATION ------------------ ------------------ ------------------ --------- S1 TARGET LUNCH SUNDAY 1.0 SUSPENDUNITS FIRST SUSPENSION STOP -------- ------- ------------------- ------------------- HOURS 2007-03-20-12:00:00 2007-12-31-00:00:00 1 Suspension(s) found. We can see the monitor suspension template called LUNCH, which we created and the monitor suspension S1. We can alter a monitor suspension template by using the ASNCLP command ALTER MONITOR SUSPENSION. Suppose we want to change the suspension day from Sunday to Monday, then the ASNCLP command would be: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; ALTER MONITOR SUSPENSION TEMPLATE lunch; LIST MONITOR SUSPENSION TEMPLATE; To drop a monitor suspension, we would use the DROP MONITOR SUSPENSION ASNCLP command: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; SET SERVER TARGET TO DB db2b; DROP MONITOR SUSPENSION s1; Dropping a monitor suspension involves running the following SQL: DELETE FROM ASN.IBMSNAP_SUSPENDS WHERE SUSPENSION_NAME = 'S1' To drop a monitor suspension template, we would use the DROP MONITOR SUSPENSION TEMPLATE ASNCLP command: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; DROP MONITOR SUSPENSION TEMPLATE lunch; Dropping a monitor suspension template involves running the following SQL: DELETE FROM ASN.IBMSNAP_TEMPLATES WHERE TEMPLATE_NAME = 'LUNCH' So let's look at an example in a bidirectional scenario as shown in the following diagram: In this example, we have created four monitors to monitor Q Capture and Q Apply on each of the two servers. The monitor_qual are MONAC1, MONAA1, MONBA1, and MONBC1. The monitor_server is MONDB. If we want to perform maintenance on the DB2B database every Sunday afternoon at 16:00 for one hour, we would create a monitor suspension template as follows: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; CREATE MONITOR SUSPENSION TEMPLATE tmaintbaft START TIME 16:00:00 REPEATS WEEKLY DAY OF WEEK SUNDAY FOR DURATION 1 HOURS; And then, we would create a monitor suspension as follows: ASNCLP SESSION SET TO SQL REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER MONITOR TO DB mondb; SET SERVER TARGET TO DB db2b; CREATE MONITOR SUSPENSION NAME maintbaft FOR SERVER DB2B STARTING DATE 2007-03-20 USING TEMPLATE tmaintbaft ENDING DATE 2007-12-31; The ibmsnap_alerts table The IBMSNAP_ALERTS table contains a record of all the alerts issued by the Replication Alert Monitor. The table records what alert condition occurred, at which server, and when they were detected. Some common errors in the ALERT_CODE column are: ASN5153W MONITOR "<monitor_qualifier>". The latency exceeds the threshold value for program "<program_name>". The server is "<server_name>". The schema is "<schema>". The latency is "<latency>" seconds. The threshold is "<threshold>" seconds. ASN5157W MONITOR "<monitor_qualifier>". The Q subscription "<subscription_name>" is inactive. The server is "<server_name>". The schema is "<schema>". State information: "<stateinfo>". Summary In this article we described the Replication Alert Monitor and how to monitor the Q replication setup. Further resources on this subject: Lotus Notes Domino 8: Upgrader's Guide [Book] Q Replication Components in IBM Replication Server [Article] IBM WebSphere MQ commands [Article] WebSphere MQ Sample Programs [Article] Q Subscription Maintenance in IBM Infosphere [Article]
Read more
  • 0
  • 0
  • 2278

article-image-drupal-web-services-twitter-and-drupal
Packt
26 Nov 2010
10 min read
Save for later

Drupal Web Services: Twitter and Drupal

Packt
26 Nov 2010
10 min read
Drupal Web Services Integrate social and multimedia Web services and applications with your Drupal Web site. Explore different Web services and how they integrate with the Drupal CMS. Reuse the applications without coding them again using the Web services protocols on your Drupal site. Configure your Drupal site to consume various web services by using contributed Drupal modules for each specific task or application. Drive the content from your Drupal site to Facebook, Twitter and LinkedIn using effective Drupal Web services An easy to follow guide that opens up a method of easily sharing data and content resources between applications and machines that are running different platforms and architecture. Introduction Twitter is a popular and widely used micro-blogging application and website. You can sign up for a Twitter account and post tiny snippet-based blog entries, 140 characters or less, to your Twitter home page. You can log in to your Twitter account and post your 140 character entry into the What's happening? text area box and then click on the Tweet button to publish it. The tweet will appear on your account's home page—your default Twitter home page—and it will be shared on the main Twitter home pages of your followers. To send a tweet to another user, you can use the hash tag in front of their username in your post. So, for example, if I was going to send myself a tweet, I would add this in my text area box before adding my post: #jamesweblabs. For more on the history and functionality of Twitter, check out the Wikipedia entry at: http://en.wikipedia.org/wiki/Twitter. Twitter also has a detailed Help and support documentation section on its main site at http://support.twitter.com/.   You may want to integrate Twitter with your Drupal site, to do things such as posting all of your most recent tweets into a Drupal block that will appear on your home page. You also may want to run this block automatically via a web service integration so that the block updates automatically whenever you post a new tweet to your Twitter account. Drupal and Twitter can easily integrate through these web services by using contributed modules. In this article, we're going to install, configure, and use the Twitter module so that we can integrate our Twitter account with our Drupal user account; we can also post tweets to the sidebar block on our site. With the Twitter module, we'll also expose some of its fields to the Views module and be able to create more powerful and dynamic listings of Twitter-based content. We'll also look at other contributed modules including Tweet. The Twitter API The Twitter API and service integration with Drupal uses the REST (Representational State Transfer) API protocol and a Streaming API protocol. Twitter does state in its API documentation that the service does not offer unlimited usage. Twitter does impose limits on the number of requests and updates made to its service API. The REST service is HTTP-based and uses GET and POST requests. GET is used to retrieve data so, in our case, this will be used when our Drupal site tries to receive the latest Tweet posted to your Twitter account. POST requests are used when you submit, update, or delete node data that you have sent over to Twitter and posted as a Tweet using the Twitter module. Using REST as the protocol, the API does support various formats for data transfer including XML, JSON, RSS, and Atom. For more details on the Twitter API and how to use it, see the Twitter API documentation for developers at: http://dev.twitter.com/pages/every_developer. The Twitter module The Twitter module is available via its Drupal project page at http://drupal.org/project/twitter. The module allows for integration with Twitter's API web service. It allows you to integrate your Twitter account with your Drupal user account; post Tweets to a block in Drupal; and allows your Drupal users to post to their Twitter account using Drupal node content. Drupal Views also integrates with the module and you can create your own customized Views-based listings of Twitter content. The module gives you a default block called User Tweets and also a user profile page titled user's tweets. We'll set both of these up in the examples that follow. Integrating the Twitter module with Drupal Download the 6.x-3.0-beta2 version of the Twitter module. This is the Other release version, not the recommended release. The reason we're going to install the Other release version is that recently Twitter changed their web service API to use authentication provided by the OAuth protocol. This change happened recently, in September 2010, when Twitter redesigned their website and made other security improvements and enhancements to their API. In order to support OAuth in the integration, you need to make sure to use the 3.0-beta2 version of the Twitter module. You can download it from: http://drupal.org/project/twitter It's listed under the Other releases heading: Once downloaded, upload this Twitter module folder to your /sites/all/modules location on your web server. You also need to download the OAuth module and add that to your /sites/all/modules. OAuth is required by the Twitter module, so you must install it. The OAuth module is available at: http://drupal.org/project/oauth. Again, with this module, you need to make sure to use the other release (earlier version) of 6.x-2.02. This 2.x version is the version that works with the Twitter 3.0-beta2 module. Make sure you have the correct versions of both of these modules before uploading to your site. This is very important. If the module versions are not the ones mentioned here, you may run into errors or other issues with functionality. So, make sure to install these exact versions. Go ahead and upload both of these modules to your /sites/all/modules. Once uploaded, browse to your modules admin page and look for the OAuth and Twitter module suites under the Other modules fieldset. For OAuth, you're looking for the Oauth and the OAuth Client Test modules. Enable the OAuth module as shown in the following screenshot: Then, scroll down and look for the Twitter, Twitter actions, Twitter Post, and Twitter Signin modules. Enable all four of these modules: Save your module configuration. Registering your website with Twitter Now that we've installed the necessary modules on our Drupal site, we need to set up the Twitter side of our functionality. In order to integrate the Twitter module with the Twitter web service, you need to create two Twitter-related items. The first is a Twitter account. If you do not already have a Twitter account, you can go to twitter.com and sign up for a brand new Twitter account. Go to: https://twitter.com/ Click on the Sign Up button and then proceed through the account sign-up steps. Setting up a Twitter application Now, we need to configure a new Twitter developer application. Once you have a Twitter account, log in to your Twitter account and then go to the twitter.com/apps URL to sign up for a new developer's application on Twitter. Make sure you are signed into your Twitter account already when you go to the apps URL. Launch the apps URL from: https://twitter.com/apps This page will show you any applications you have configured in Twitter. For our site, we're going to set up a brand new application, so, click on the Register a new application hyperlink: Clicking on that link will load a Register an Application form as shown in the following screenshot. Let's fill that out with the following info: Application Name Description of application Application Website (this is the URL of your website) Organization Name Website address (again this is the URL/home domain of your website) Scroll down on the form and then complete the form by adding and completing the following fields: Application Type—make sure to select Browser here Callback URL—this is the callback URL that the Drupal Twitter module provides The Callback URL is information that is provided by your Twitter module settings inside your Drupal site. To locate the correct Callback URL to add to the application sign-up form, go to your Twitter setup configuration settings in your Drupal site by browsing to: Site configuration | Twitter setup (admin/settings/twitter). On this page, you will see the Callback URL noted at the top of the OAuth Settings fieldset. You should see something similar to this: Go back to your Twitter application sign-up form and add this Callback URL. Now, make sure the Default Access type is set to Read & Write. Finally, make sure to check the Yes, Use Twitter for login. This will allow you to authenticate your posts to your Twitter account username and password when you try to post Drupal content to your Twitter account. So, make sure that box is checked. Your app form should now look like this: Complete the reCAPTCHA field at the bottom of the form and then click on the Save button. Twitter will load a page confirming your application is successfully configured and show you your application details. This includes your Consumer key, Consumer secret, Request token URL, Access Token URL, and Authorize URL. For integration with our Drupal site, we're going to need the Consumer key and secret. Leave this app details confirmation page open and then open up your Drupal site in another browser tab. Configuring the Twitter module once you have your app setup With your Drupal site open, go back to your Twitter module configuration form in your Drupal site at the following path: admin/settings/twitter. Here, you want to copy and paste your Twitter Consumer key and secret code into the respective fields for OAuth Consumer key and OAuth Consumer secret. Also, make sure to check the box next to Import Twitter Statuses. This will allow for your Drupal site to request posts from your Twitter account and add links to these tweets on your user account page, and also in a User Tweets block in one of your site's regions. This is what allows for the total cross-pollination and integration of your Drupal site with your Twitter account. It's very powerful and flexible for running the Twitter import functionality on your site. Finally, set the Delete old statuses drop down to 1 week. This will keep your Tweets block up to date on your Drupal site and show only updated and recent tweets. Let's go ahead and do that. You should have a screen that looks like this: Go ahead and Save configuration. Now, let's check and tweak some of the other Twitter module settings before we test our posts. Click on the Post link at the top of your Twitter setup page. On this page, you can specify what content types and respective Drupal content you want to announce and post to your Twitter account. Let's make sure we check the boxes next to the Blog entry, Page, and Story types. Of course, you can enable all of your content types if you need to, but for this example, we'll just post our new blog entries over to our Twitter account. The Default format string field shows you the format of the link that will be posted over to your Twitter account announcing your new Drupal content. So, when you post a node to your Drupal site using the blog type, the post will appear on your Twitter account in the following format as a hyperlink back to your post on Drupal: New post: !title !tinyurl This will show the Drupal node title, !title, value along with a tinyurl formatted hyperlink back to your Drupal post. So, for example, the resulting post on Twitter will look like this: ·New post: Testing post to Twitter http://tinyurl.com/33jnclx — 1 hour 53 min ago Your Post screen should now look like this: Save your Post page configuration.
Read more
  • 0
  • 0
  • 4503

article-image-user-extensions-and-add-ons-selenium-10-testing-tools
Packt
26 Nov 2010
6 min read
Save for later

User Extensions and Add-ons in Selenium 1.0 Testing Tools

Packt
26 Nov 2010
6 min read
Important preliminary points If you are creating an extension that can be used by all, make sure that it is stored in a central place, like a version control system. This will prevent any potential issues in the future when others in your team start to use it. User extensions Imagine that you wanted to use a snippet of code that is used in a number of different tests. You could use: type | locator | javascript{ .... } However, if you had a bug in the JavaScript you would need to go through all the tests that reused this snippet of code. This, as we know from software development, is not good practice and is normally corrected with a refactoring of the code. In Selenium, we can create our own function that can then be used throughout the tests. User extensions are stored in a separate file that we will tell Selenium IDE or Selenium RC to use. Inside there the new function will be written in JavaScript. Because Selenium's core is developed in JavaScript, creating an extension follows the standard rules for prototypal languages. To create an extension, we create a function in the following design pattern. Selenium.prototype.doFunctionName = function(){ . . . } The "do" in front of the function name tells Selenium that this function can be called as a command for a step instead of an internal or private function. Now that we understand this, let's see this in action. Time for action – installing a user extension Now that you have a need for a user extension, let's have a look at installing an extension into Selenium IDE. This will make sure that we can use these functions in future Time for action sections throughout this article. Open your favorite text editor. Create an empty method with the following text: Selenium.prototype.doNothing = function(){ . . . } Start Selenium IDE. Click on the Options menu and then click on Options. Place the path of the user-extension.js file in the textbox labeled Selenium IDE extensions. Click on OK. Restart Selenium IDE. Start typing in the Command textbox and your new command will be available, as seen in the next screenshot: What just happened? We have just seen how to create our first basic extension command and how to get this going in Selenium IDE. You will notice that you had to restart Selenium IDE for the changes to take effect. Selenium has a process that finds all the command functions available to it when it starts up, and does a few things to it to make sure that Selenium can use them without any issues. Now that we understand how to create and install an extension command let's see what else we can do with it. In the next Time for action, we are going to have a look at creating a randomizer command that will store the result in a variable that we can use later in the test. Time for action – using Selenium variables in extensions Imagine that you are testing something that requires some form of random number entered into a textbox. You have a number of tests that require you to create a random number for the test so you can decide that you are going to create a user extension and then store the result in a variable. To do this we will need to pass in arguments to our function that we saw earlier. The value in the target box will be passed in as the first argument and the value textbox will be the second argument. We will use this in a number of different examples throughout this article. Let's now create this extension. Open your favorite text editor and open the user-extension.js file you created earlier. We are going to create a function called storeRandom. The function will look like the following: Selenium.prototype.doStoreRandom = function(variableName){ random = Math.floor(Math.random()*10000000); storedVars[variableName] = random; } Save the file. Restart Selenium IDE. Create a new step with storeRandom and the variable that will hold the value will be called random. Create a step to echo the value in the random variable. What just happened? In the previous example, we saw how we can create an extension function that allows us to use variables that can be used throughout the rest of the test. It uses the storedVars dictionary that we saw in the previous chapter. As everything that comes from the Selenium IDE is interpreted as a string, we just needed to put the variable as the key in storedVars. It is then translated and will look like storedVars['random'] so that we can use it later. As with normal Selenium commands, if you run the command a number of times, it will overwrite the value that is stored within that variable, as we can see in the previous screenshot. Now that we know how to create an extension command that computes something and then stores the results in a variable, let's have a look at using that information with a locator. Time for action – using locators in extensions Imagine that you need to calculate today's date and then type that into a textbox. To do that you can use the type | locator | javascript{...} format, but sometimes it's just neater to have a command that looks like typeTodaysDate | locator. We do this by creating an extension and then calling the relevant Selenium command in the same way that we are creating our functions. To tell it to type in a locator, use: this.doType(locator,text); The this in front of the command text is to make sure that it used the doType function inside of the Selenium object and not one that may be in scope from the user extensions. Let's see this in action: Use your favorite text editor to edit the user extensions that you were using in the previous examples. Create a new function called doTypeTodaysDate with the following snippet: Selenium.prototype.doTypeTodaysDate = function(locator){ var dates = new Date(); var day = dates.getDate(); if (day < 10){ day = '0' + day; } month = dates.getMonth() + 1; if (month < 10){ month = '0' + month; } var year = dates.getFullYear(); var prettyDay = day + '/' + month + '/' + year; this.doType(locator, prettyDay); } Save the file and restart Selenium IDE. Create a step in a test to type this in a textbox. Run your script. It should look similar to the next screenshot: What just happened? We have just seen that we can create extension commands that use locators. This means that we can create commands to simplify tests as in the previous example where we created our own Type command to always type today's date in the dd/mm/yyyy format. We also saw that we can call other commands from within our new command by calling its original function in Selenium. The original function has do in front of it. Now that we have seen how we can use basic locators and variables, let's have a look at how we can access the page using browserbot from within an extension method.
Read more
  • 0
  • 0
  • 5401

article-image-advanced-activities-bpel
Packt
25 Nov 2010
7 min read
Save for later

Advanced Activities in BPEL

Packt
25 Nov 2010
7 min read
Loops When defining business processes, we will sometimes want to perform a certain activity or a set of activities in a loop; for example, perform a calculation or invoke a partner web service operation several times, and so on. BPEL supports three types of loops: <while> loops <repeatUntil> loops <forEach> loops The <while> and <repeatUntil> loops are very similar to other programming languages. The <forEach> loop, on the other hand, provides the ability to start the loop instances in parallel. Loops are helpful when dealing with arrays. In BPEL, arrays can be simulated using XML complex types where one or more elements can occur more than once (using the maxOccurs attribute in the XML Schema definition). To iterate through multiple occurrences of the same element, we can use XPath expressions. Let us now look at the <while> loop. While The <while> loop repeats the enclosed activities until the Boolean condition no longer holds true. The Boolean condition is expressed through the condition element, using the selected expression language (the default is XPath 1.0). The syntax of the <while> activity is shown in the following code excerpt: <while> <condition> boolean-expression </condition> <!-- Perform an activity or a set of activities enclosed by <sequence>, <flow>, or other structured activity --> </while Let us consider a scenario where we need to check flight availability for more than one person. Let us also assume that we need to invoke a web service operation for each person. In addition to the variables already present in the example, we would need two more NoOfPassengers to hold the number of passengers and Counter to use in the loop. The code excerpt with variable declarations is as follows: <variables> <variable name="NoOfPassengers" type="xs:int"/> <variable name="Counter" type="xs:int"/> </variables> We also need to assign values to the variables. The NoOfPassengers can be obtained from the Employee Travel web service. In the following code, we initialize both variables with static values: <assign> <copy> <from>number(5)</from> <to variable="NoOfPassengers"/> </copy> <copy> <from>number(0)</from> <to variable="Counter"/> </copy> </assign> The loop to perform the web service invocation is shown in the following code excerpt. Please remember that this excerpt is not complete: <while> <condition>$Counter &lt; $NoOfPassengers</condition> <sequence> <!-- Construct the FlightDetails variable with passenger data --> ... <!-- Invoke the web service --> <invoke partnerLink="AmericanAirlines" portType="aln:FlightAvailabilityPT" operation="FlightAvailability" inputVariable="FlightDetails" /> <receive partnerLink="AmericanAirlines" portType="trv:FlightCallbackPT" operation="FlightTicketCallback" variable="FlightResponseAA" /> ... <!-- Process the results ... --> ... <!-- Increment the counter --> <assign> <copy> <from>$Counter + 1</from> <to variable="Counter"/> </copy> </assign> </sequence> </while> Repeat Until The <repeatUntil> loop repeats the enclosed activities until the Boolean condition becomes true. The Boolean condition is expressed through the condition element, the same way as in the <while> loop. The syntax of the <repeatUntil> activity is shown in the following code excerpt: <repeatUntil> <!-- Perform an activity or a set of activities enclosed by <sequence>, <flow>, or other structured activity --> <condition> boolean-expression </condition> </repeatUntil> A similar example of a loop as mentioned in the previous section, but using <repeatUntil>, is as follows: <repeatUntil> <sequence> <!-- Construct the FlightDetails variable with passenger data --> ... <!-- Invoke the web service --> <invoke partnerLink="AmericanAirlines" portType="aln:FlightAvailabilityPT" operation="FlightAvailability" inputVariable="FlightDetails" /> <receive partnerLink="AmericanAirlines" portType="trv:FlightCallbackPT" operation="FlightTicketCallback" variable="FlightResponseAA" /> ... <!-- Process the results ... --> ... <!-- Increment the counter --> <assign> <copy> <from>$Counter + 1</from> <to variable="Counter"/> </copy> </assign> </sequence> <condition>$Counter &gt;= $NoOfPassengers</condition> </repeatUntil> For Each The <forEach> loop is a for type loop, with an important distinction. In BPEL the <forEach> loop can execute the loop branches in parallel or serially. The serial <forEach> is very similar to the for loops from various programming languages, such as Java. The parallel <forEach> executes the loop branches in parallel (similar to <flow>), which opens new possibilities in relatively simple parallel execution (for example, invocation of services). The <forEach> loop requires us to specify the BPEL variable for the counter (counterName), the startCounterValue, and the finalCounterValue. The <forEach> loop will execute (finalCounterValue – startCounterValue + 1) times. The <forEach> requires that we put all activities, which should be executed within the branch, into a <scope>. The <scope> allows us to perform group-related activities. The syntax of <forEach> is shown in the following: <forEach counterName="BPELVariableName" parallel="yes|no"> <startCounterValue>unsigned-integer-expression</startCounterValue> <finalCounterValue>unsigned-integer-expression</finalCounterValue> <scope> <!-- The activities that are performed within forEach have to be nested within a scope. --> </scope> </forEach> Such a <forEach> loop will complete when all branches (<scope>) have completed. A similar example of a loop as in the previous section is as follows: <forEach counterName="Counter" parallel="no"> <startCounterValue>number(1)</startCounterValue> <finalCounterValue>$NoOfPassengers</finalCounterValue> <scope> <sequence> <!-- Construct the FlightDetails variable with passenger data --> ... <!-- Invoke the web service --> <invoke partnerLink="AmericanAirlines" portType="aln:FlightAvailabilityPT" operation="FlightAvailability" inputVariable="FlightDetails" /> <receive partnerLink="AmericanAirlines" portType="trv:FlightCallbackPT" operation="FlightTicketCallback" variable="FlightResponseAA" /> ... <!-- Process the results ... --> ... </sequence> </scope> </forEach> Sometimes it would be useful if the <forEach> loop would not have to wait for all branches to complete. Rather, it would wait until at least some branches complete. In <forEach> we can specify that the loop will complete after at least N branches have completed. We do this using the <completionCondition> . We specify the number N of <branches>. The <forEach> will complete after at least N branches have completed. We can specify if we would like to count only successful branches or all branches. We do this using the successfulBranchesOnly attribute. If set to yes, only successful branches will count. If set to no (default), successful and failed branches will count. The syntax is as shown in the following: <forEach counterName="BPELVariableName" parallel="yes|no"> <startCounterValue>unsigned-integer-expression</startCounterValue> <finalCounterValue>unsigned-integer-expression</finalCounterValue> <completionCondition> <!-- Optional --> <branches successfulBranchesOnly="yes|no"> unsigned-integer-expression </branches> </completionCondition> <scope> <!-- The activities that are performed within forEach have to be nested within a scope. --> </scope> </forEach>
Read more
  • 0
  • 0
  • 2809
article-image-materials-ogre-3d
Packt
25 Nov 2010
7 min read
Save for later

Materials with Ogre 3D

Packt
25 Nov 2010
7 min read
OGRE 3D 1.7 Beginner's Guide Create real time 3D applications using OGRE 3D from scratch Easy-to-follow introduction to OGRE 3D Create exciting 3D applications using OGRE 3D Create your own scenes and monsters, play with the lights and shadows, and learn to use plugins Get challenged to be creative and make fun and addictive games on your own A hands-on do-it-yourself approach with over 100 examples Creating a white quad We will use this to create a sample quad that we can experiment with. Time for action – creating the quad We will start with an empty application and insert the code for our quad into the createScene() function: Begin with creating the manual object: Ogre::ManualObject* manual = mSceneMgr- >createManualObject("Quad"); manual->begin("BaseWhiteNoLighting", RenderOperation::OT_TRIANGLE_ LIST); Create four points for our quad: manual->position(5.0, 0.0, 0.0); manual->textureCoord(0,1); manual->position(-5.0, 10.0, 0.0); manual->textureCoord(1,0); manual->position(-5.0, 0.0, 0.0); manual->textureCoord(1,1); manual->position(5.0, 10.0, 0.0);manual->textureCoord(0,0); Use indices to describe the quad: manual->index(0); manual->index(1); manual->index(2); manual->index(0); manual->index(3); manual->index(1); Finish the manual object and convert it to a mesh: manual->end(); manual->convertToMesh("Quad"); Create an instance of the entity and attach it to the scene using a scene node: Ogre::Entity * ent = mSceneMgr->createEntity("Quad"); Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()- >createChildSceneNode("Node1"); node->attachObject(ent); Compile and run the application. You should see a white quad. What just happened? We used our knowledge to create a quad and attach to it a material that simply renders everything in white. The next step is to create our own material. Creating our own material Always rendering everything in white isn't exactly exciting, so let's create our first material. Time for action – creating a material Now, we are going to create our own material using the white quad we created. Change the material name in the application from BaseWhiteNoLighting to MyMaterial1: manual->begin("MyMaterial1", RenderOperation::OT_TRIANGLE_LIST); Create a new file named Ogre3DBeginnersGuide.material in the mediamaterialsscripts folder of our Ogre3D SDK. Write the following code into the material file: material MyMaterial1 { technique { pass { texture_unit { texture leaf.png } } } } Compile and run the application. You should see a white quad with a plant drawn onto it. What just happened? We created our first material file. In Ogre 3D, materials can be defined in material files. To be able to find our material files, we need to put them in a directory listed in the resources.cfg, like the one we used. We also could give the path to the file directly in code using the ResourceManager. To use our material defined in the material file, we just had to use the name during the begin call of the manual object. The interesting part is the material file itself. Materials Each material starts with the keyword material, the name of the material, and then an open curly bracket. To end the material, use a closed curly bracket—this technique should be very familiar to you by now. Each material consists of one or more techniques; a technique describes a way to achieve the desired effect. Because there are a lot of different graphic cards with different capabilities, we can define several techniques and Ogre 3D goes from top to bottom and selects the first technique that is supported by the user's graphic cards. Inside a technique, we can have several passes. A pass is a single rendering of your geometry. For most of the materials we are going to create, we only need one pass. However, some more complex materials might need two or three passes, so Ogre 3D enables us to define several passes per technique. In this pass, we only define a texture unit. A texture unit defines one texture and its properties. This time the only property we define is the texture to be used. We use leaf.png as the image used for our texture. This texture comes with the SDK and is in a folder that gets indexed by resources.cfg, so we can use it without any work from our side. Have a go hero – creating another material Create a new material called MyMaterial2 that uses Water02.jpg as an image. Texture coordinates take two There are different strategies used when texture coordinates are outside the 0 to 1 range. Now, let's create some materials to see them in action. Time for action – preparing our quad We are going to use the quad from the previous example with the leaf texture material: Change the texture coordinates of the quad from range 0 to 1 to 0 to 2. The quad code should then look like this: manual->position(5.0, 0.0, 0.0); manual->textureCoord(0,2); manual->position(-5.0, 10.0, 0.0); manual->textureCoord(2,0); manual->position(-5.0, 0.0, 0.0); manual->textureCoord(2,2); manual->position(5.0, 10.0, 0.0); manual->textureCoord(0,0); Now compile and run the application. Just as before, we will see a quad with a leaf texture, but this time we will see the texture four times. What just happened? We simply changed our quad to have texture coordinates that range from zero to two. This means that Ogre 3D needs to use one of its strategies to render texture coordinates that are larger than 1. The default mode is wrap. This means each value over 1 is wrapped to be between zero and one. The following is a diagram showing this effect and how the texture coordinates are wrapped. Outside the corners, we see the original texture coordinates and inside the corners, we see the value after the wrapping. Also for better understanding, we see the four texture repetitions with their implicit texture coordinates. We have seen how our texture gets wrapped using the default texture wrapping mode. Our plant texture shows the effect pretty well, but it doesn't show the usefulness of this technique. Let's use another texture to see the benefits of the wrapping mode. Using the wrapping mode with another texture Time for action – adding a rock texture For this example, we are going to use another texture. Otherwise, we wouldn't see the effect of this texture mode: Create a new material similar to the previous one, except change the used texture to: terr_rock6.jpg: material MyMaterial3 { technique { pass { texture_unit { texture terr_rock6.jpg } } } } Change the used material from MyMaterial1 to MyMaterial3: manual->begin("MyMaterial3", RenderOperation::OT_TRIANGLE_LIST) Compile and run the application. You should see a quad covered in a rock texture. What just happened? This time, the quad seems like it's covered in one single texture. We don't see any obvious repetitions like we did with the plant texture. The reason for this is that, like we already know, the texture wrapping mode repeats. The texture was created in such a way that at the left end of the texture, the texture is started again with its right side and the same is true for the lower end. This kind of texture is called seamless. The texture we used was prepared so that the left and right side fit perfectly together. The same goes for the upper and lower part of the texture. If this wasn't the case, we would see instances where the texture is repeated.
Read more
  • 0
  • 0
  • 10092

article-image-ogre-3d-double-buffering
Packt
25 Nov 2010
5 min read
Save for later

Ogre 3D: Double Buffering

Packt
25 Nov 2010
5 min read
  OGRE 3D 1.7 Beginner's Guide Create real time 3D applications using OGRE 3D from scratch Easy-to-follow introduction to OGRE 3D Create exciting 3D applications using OGRE 3D Create your own scenes and monsters, play with the lights and shadows, and learn to use plugins Get challenged to be creative and make fun and addictive games on your own A hands-on do-it-yourself approach with over 100 examples Images         Read more about this book       (For more resources on this subject, see here.) Introduction When a scene is rendered, it isn't normally rendered directly to the buffer, which is displayed on the monitor. Normally, the scene is rendered to a second buffer and when the rendering is finished, the buffers are swapped. This is done to prevent some artifacts, which can be created if we render to the same buffer, which is displayed on the monitor. The FrameListener function, frameRenderingQueued, is called after the scene has been rendered to the back buffer, the buffer which isn't displayed at the moment. Before the buffers are swapped, the rendering result is already created but not yet displayed. Directly after the frameRenderingQueued function is called, the buffers get swapped and then the application gets the return value and closes itself. That's the reason why we see an image this time. Now, we will see what happens when frameRenderingQueued also returns true. Time for action – returning true in the frameRenderingQueued function Once again we modify the code to test the behavior of the Frame Listener Change frameRenderingQueued to return true: bool frameRenderingQueued (const Ogre::FrameEvent& evt){ std::cout << «Frame queued» << std::endl; return true;} Compile and run the application. You should see Sinbad for a short period of time before the application closes, and the following three lines should be in the console output: Frame started Frame queued Frame ended What just happened? Now that the frameRenderingQueued handler returns true, it will let Ogre 3D continue to render until the frameEnded handler returns false. Like in the last example, the render buffers were swapped, so we saw the scene for a short period of time. After the frame was rendered, the frameEnded function returned false, which closes the application and, in this case, doesn't change anything from our perspective. Time for action – returning true in the frameEnded function Now let's test the last of three possibilities. Change frameRenderingQueued to return true: bool frameEnded (const Ogre::FrameEvent& evt){ std::cout << «Frame ended» << std::endl; return true;} Compile and run the application. You should see the scene with Sinbad and an endless repetition of the following three lines: Frame started Frame queued Frame ended What just happened? Now, all event handlers returned true and, therefore, the application will never be closed; it would run forever as long as we aren't going to close the application ourselves. Adding input We have an application running forever and have to force it to close; that's not neat. Let's add input and the possibility to close the application by pressing Escape. Time for action – adding input Now that we know how the FrameListener works, let's add some input. We need to include the OIS header file to use OIS: #include "OISOIS.h" Remove all functions from the FrameListener and add two private members to store the InputManager and the Keyboard: OIS::InputManager* _InputManager;OIS::Keyboard* _Keyboard; The FrameListener needs a pointer to the RenderWindow to initialize OIS, so we need a constructor, which takes the window as a parameter: MyFrameListener(Ogre::RenderWindow* win){ OIS will be initialized using a list of parameters, we also need a window handle in string form for the parameter list; create the three needed variables to store the data: OIS::ParamList parameters;unsigned int windowHandle = 0;std::ostringstream windowHandleString; Get the handle of the RenderWindow and convert it into a string: win->getCustomAttribute("WINDOW", &windowHandle);windowHandleString << windowHandle; Add the string containing the window handle to the parameter list using the key "WINDOW": parameters.insert(std::make_pair("WINDOW", windowHandleString.str())); Use the parameter list to create the InputManager: _InputManager = OIS::InputManager::createInputSystem(parameters); With the manager create the keyboard: _Keyboard = static_cast<OIS::Keyboard*>(_InputManager->createInputObject( OIS::OISKeyboard, false )); What we created in the constructor, we need to destroy in the destructor: ~MyFrameListener(){ _InputManager->destroyInputObject(_Keyboard); OIS::InputManager::destroyInputSystem(_InputManager);} Create a new frameStarted function, which captures the current state of the keyboard, and if Escape is pressed, it returns false; otherwise, it returns true: bool frameStarted(const Ogre::FrameEvent& evt){ _Keyboard->capture(); if(_Keyboard->isKeyDown(OIS::KC_ESCAPE)) { return false; } return true;} The last thing to do is to change the instantiation of the FrameListener to use a pointer to the render window in the startup function: _listener = new MyFrameListener(window);_root->addFrameListener(_listener); Compile and run the application. You should see the scene and now be able to close it by pressing the Escape key. What just happened? We added input processing capabilities to our FrameListener but we didn't use any example classes, except our own versions.
Read more
  • 0
  • 0
  • 3039

article-image-ogre-3d-fixed-function-pipeline-and-shaders
Packt
25 Nov 2010
13 min read
Save for later

Ogre 3D: Fixed Function Pipeline and Shaders

Packt
25 Nov 2010
13 min read
  OGRE 3D 1.7 Beginner's Guide Create real time 3D applications using OGRE 3D from scratch Easy-to-follow introduction to OGRE 3D Create exciting 3D applications using OGRE 3D Create your own scenes and monsters, play with the lights and shadows, and learn to use plugins Get challenged to be creative and make fun and addictive games on your own A hands-on do-it-yourself approach with over 100 examples Introduction Fixed Function Pipeline is the rendering pipeline on the graphics card that produces those nice shiny pictures we love looking at. As the prefix Fixed suggests, there isn't a lot of freedom to manipulate the Fixed Function Pipeline for the developer. We can tweak some parameters using the material files, but nothing fancy. That's where shaders can help fill the gap. Shaders are small programs that can be loaded onto the graphics card and then function as a part of the rendering process. These shaders can be thought of as little programs written in a C-like language with a small, but powerful, set of functions. With shaders, we can almost completely control how our scene is rendered and also add a lot of new effects that weren't possible with only the Fixed Function Pipeline. Render Pipeline To understand shaders, we need to first understand how the rendering process works as a whole. When rendering, each vertex of our model is translated from local space into camera space, then each triangle gets rasterized. This means, the graphics card calculates how to represent the model in an image. These image parts are called fragments. Each fragment is then processed and manipulated. We could apply a specific part of a texture to this fragment to texture our model or we could simply assign it a color when rendering a model in only one color. After this processing, the graphics card tests if the fragment is covered by another fragment that is nearer to the camera or if it is the fragment nearest to the camera. If this is true, the fragment gets displayed on the screen. In newer hardware, this step can occur before the processing of the fragment. This can save a lot of computation time if most of the fragments won't be seen in the end result. The following is a very simplified graph showing the pipeline: With almost each new graphics card generation, new shader types were introduced. It began with vertex and pixel/fragment shaders. The task of the vertex shader is to transform the vertices into camera space, and if needed, modify them in any way, like when doing animations completely on the GPU. The pixel/fragment shader gets the rasterized fragments and can apply a texture to them or manipulate them in other ways, for example, for lighting models with an accuracy of a pixel. Time for action – our first shader application Let's write our first vertex and fragment shaders: In our application, we only need to change the used material. Change it to MyMaterial13. Also remove the second quad: manual->begin("MyMaterial13", RenderOperation::OT_TRIANGLE_LIST); Now we need to create this material in our material file. First, we are going to define the fragment shader. Ogre 3D needs five pieces of information about the shader: The name of the shader In which language it is written In which source file it is stored How the main function of this shader is called In what profile we want the shader to be compiled All this information should be in the material file: fragment_program MyFragmentShader1 cg { source Ogre3DBeginnersGuideShaders.cg entry_point MyFragmentShader1 profiles ps_1_1 arbfp1 } The vertex shader needs the same parameter, but we also have to define a parameter that is passed from Ogre 3D to our shader. This contains the matrix that we will use for transforming our quad into camera space: vertex_program MyVertexShader1 cg { source Ogre3DBeginnerGuideShaders.cg entry_point MyVertexShader1 profiles vs_1_1 arbvp1 default_params { param_named_auto worldViewMatrix worldviewproj_matrix } } The material itself just uses the vertex and fragment shader names to reference them: material MyMaterial13 { technique { pass { vertex_program_ref MyVertexShader1 { } fragment_program_ref MyFragmentShader1 { } } } } Now we need to write the shader itself. Create a file named Ogre3DBeginnersGuideShaders.cg in the mediamaterialsprograms folder of your Ogre 3D SDK. Each shader looks like a function. One difference is that we can use the out keyword to mark a parameter as an outgoing parameter instead of the default incoming parameter. The out parameters are used by the rendering pipeline for the next rendering step. The out parameters of a vertex shader are processed and then passed into the pixel shader as an in parameter. The out parameter from a pixel shader is used to create the final render result. Remember to use the correct name for the function; otherwise, Ogre 3D won't find it. Let's begin with the fragment shader because it's easier: void MyFragmentShader1(out float4 color: COLOR) The fragment shader will return the color blue for every pixel we render: { color = float4(0,0,1,0); } That's all for the fragment shader; now we come to the vertex shader. The vertex shader has three parameters—the position for the vertex, the translated position of the vertex as an out variable, and as a uniform variable for the matrix we are using for the translation: void MyVertexShader1( float4 position : POSITION, out float4 oPosition : POSITION, uniform float4x4 worldViewMatrix) Inside the shader, we use the matrix and the incoming position to calculate the outgoing position: { oPosition = mul(worldViewMatrix, position); } Compile and run the application. You should see our quad, this time rendered in blue. What just happened? Quite a lot happened here; we will start with step 2. Here we defined the fragment shader we are going to use. Ogre 3D needs five pieces of information for a shader. We define a fragment shader with the keyword fragment_program, followed by the name we want the fragment program to have, then a space, and at the end, the language in which the shader will be written. As for programs, shader code was written in assembly and in the early days, programmers had to write shader code in assembly because there wasn't another language to be used. But also, as with general programming language, soon there came high-level programming to ease the pain of writing shader code. At the moment, there are three different languages that shaders can be written in: HLSL, GLSL, and CG. The shader language HLSL is used by DirectX and GLSL is the language used by OpenGL. CG was developed by NVidia in cooperation with Microsoft and is the language we are going to use. This language is compiled during the start up of our application to their respective assembly code. So shaders written in HLSL can only be used with DirectX and GLSL shaders with OpenGL. But CG can compile to DirectX and OpenGL shader assembly code; that's the reason why we are using it to be truly cross platform. That's two of the five pieces of information that Ogre 3D needs. The other three are given in the curly brackets. The syntax is like a property file—first the key and then the value. One key we use is source followed by the file where the shader is stored. We don't need to give the full path, just the filename will do, because Ogre 3D scans our directories and only needs the filename to find the file. Another key we are using is entry_point followed by the name of the function we are going to use for the shader. In the code file, we created a function called MyFragmentShader1 and we are giving Ogre 3D this name as the entry point for our fragment shader. This means, each time we need the fragment shader, this function is called. The function has only one parameter out float4 color : COLOR. The prefix out signals that this parameter is an out parameter, meaning we will write a value into it, which will be used by the render pipeline later on. The type of this parameter is called float4, which simply is an array of four float values. For colors, we can think of it as a tuple (r,g,b,a) where r stands for red, g for green, b for blue, and a for alpha: the typical tuple to description colors. After the name of the parameter, we got a : COLOR. In CG, this is called a semantic describing for what the parameter is used in the context of the render pipeline. The parameter :COLOR tells the render pipeline that this is a color. In combination with the out keyword and the fact that this is a fragment shader, the render pipeline can deduce that this is the color we want our fragment to have. The last piece of information we supply uses the keyword profiles with the values ps_1_1 and arbfp1. To understand this, we need to talk a bit about the history of shaders. With each generation of graphics cards, a new generation of shaders have been introduced. What started as a fairly simple C-like programming language without even IF conditions are now really complex and powerful programming languages. Right now, there are several different versions for shaders and each with a unique function set. Ogre 3D needs to know which of these versions we want to use. ps_1_1 means pixel shader version 1.1 and arbfp1 means fragment program version 1. We need both profiles because ps_1_1 is a DirectX specific function set and arbfp1 is a function subset for OpenGL. We say we are cross platform, but sometimes we need to define values for both platforms. All subsets can be found at http://www.ogre3d.org/docs/manual/manual_18.html. That's all needed to define the fragment shader in our material file. In step 3, we defined our vertex shader. This part is very similar to the fragment shader definition code; the main difference is the default_params block. This block defines parameters that are given to the shader during runtime. param_named_auto defines a parameter that is automatically passed to the shader by Ogre 3D. After this key, we need to give the parameter a name and after this, the value keyword we want it to have. We name the parameter worldViewMatrix; any other name would also work, and the value we want it to have has the key worldviewproj_matrix. This key tells Ogre 3D we want our parameter to have the value of the WorldViewProjection matrix. This matrix is used for transforming vertices from local into camera space. A list of all keyword values can be found at http://www.ogre3d.org/docs/manual/manual_23.html#SEC128. How we use these values will be seen shortly. Step 4 used the work we did before. As always, we defined our material with one technique and one pass; we didn't define a texture unit but used the keyword vertex_program_ref. After this keyword, we need to put the name of a vertex program we defined, in our case, this is MyVertexShader1. If we wanted, we could have put some more parameters into the definition, but we didn't need to, so we just opened and closed the block with curly brackets. The same is true for fragment_program_ref. Writing a shader Now that we have defined all necessary things in our material file, let's write the shader code itself. Step 6 defines the function head with the parameter we discussed before, so we won't go deeper here. Step 7 defines the function body; for this fragment shader, the body is extremely simple. We created a new float4 tuple (0,0,1,0), describes the color blue and assigns this color to our out parameter color. The effect is that everything that is rendered with this material will be blue. There isn't more to the fragment shader, so let's move on to the vertex shader. Step 8 defines the function header. The vertex shader has 3 parameters— two are marked as positions using CG semantics and the other parameter is a 4x4 matrix using float4 as values named worldViewMatrix. Before the parameter type definition, there is the keyword uniform. Each time our vertex shader is called, it gets a new vertex as the position parameter input, calculates the position of this new vertex, and saves it in the oPosition parameter. This means with each call, the parameter changes. This isn't true for the worldViewMatrix. The keyword uniform denotes parameters that are constant over one draw call. When we render our quad, the worldViewMatrix doesn't change while the rest of the parameters are different for each vertex processed by our vertex shader. Of course, in the next frame, the worldViewMatrix will probably have changed. Step 9 creates the body of the vertex shader. In the body, we multiply the vertex that we got with the world matrix to get the vertex translated into camera space. This translated vertex is saved in the out parameter to be processed by the rendering pipeline. We will look more closely into the render pipeline after we have experimented with shaders a bit more. Texturing with shaders We have painted our quad in blue, but we would like to use the previous texture. Time for action – using textures in shaders Create a new material named MyMaterial14. Also create two new shaders named MyFragmentShader2 and MyVertexShader2. Remember to copy the fragment and vertex program definitions in the material file. Add to the material file a texture unit with the rock texture: texture_unit { texture terr_rock6.jpg } We need to add two new parameters to our fragment shader. The first is a two tuple of floats for the texture coordinates. Therefore, we also use the semantic to mark the parameter as the first texture coordinates we are using. The other new parameter is of type sampler2D, which is another name for texture. Because the texture doesn't change on a per fragment basis, we mark it as uniform. This keyword indicates that the parameter value comes from outside the CG program and is set by the rendering environment, in our case, by Ogre 3D: void MyFragmentShader2(float2 uv : TEXCOORD0, out float4 color : COLOR, uniform sampler2D texture) In the fragment shader, replace the color assignment with the following line: color = tex2D(texture, uv); The vertex shader also needs some new parameters—one float2 for the incoming texture coordinates and one float2 as the outgoing texture coordinates. Both are our TEXCOORD0 because one is the incoming and the other is the outgoing TEXCOORD0: void MyVertexShader2( float4 position : POSITION, out float4 oPosition : POSITION, float2 uv : TEXCOORD0, out float2 oUv : TEXCOORD0, uniform float4x4 worldViewMatrix) In the body, we calculate the outgoing position of the vertex: oPosition = mul(worldViewMatrix, position); For the texture coordinates, we assign the incoming value to the outgoing value: oUv = uv; Remember to change the used material in the application code, and then compile and run it. You should see the quad with the rock texture.
Read more
  • 0
  • 0
  • 5590
article-image-opencart-faqs
Packt
25 Nov 2010
4 min read
Save for later

OpenCart FAQs

Packt
25 Nov 2010
4 min read
OpenCart 1.4 Beginner's Guide Build and manage professional online shopping stores easily using OpenCart. Develop a professional, easy-to-use, attractive online store and shopping cart solution using OpenCart that meets today's modern e-commerce standards Easily integrate your online store with one of the more popular payment gateways like PayPal and shipping methods such as UPS and USPS Provide coupon codes, discounts, and wholesale options for your customers to increase demand on your online store With hands-on examples, step-by-step explanations, and illustrations Q: What are the system requirements for OpenCart? A: The following screenshot shows the minimum system requirements for OpenCart for installation and running without problems. You should contact your hosting provider if you are not sure whether these settings are set or not. Q: What are the methods to upload files to a web host? A: There are two common methods for uploading files to a web host: Using cPanel File Manager Utility Using an FTP Client Q: Can we run more than one store on a single OpenCart installation? A: Yes. We can run more than one store on a single OpenCart installation. Q: What are GeoZones? A: Geo Zones represent the groups of countries or smaller geo sections under these countries. A Geo Zone can include countries, states, cities, and regions depending on the type of country. OpenCart uses Geo Zones to identify shipping and tax rate price regulations for a customer's order. Here is an example: Q: What if we want to edit anything in Geo Zones? A: If we want to edit any Country and / or Zone definition in Geo Zones, we should visit System | Localisation | Zones menu in the administration pane. Q: What is SEO? A: SEO (Search Engine Optimization) is a group of processes which is applied for websites to increase their visibility in search engine results to get more qualified traffic. For an online store, it is very important to apply at least the basic SEO techniques. Q: Where can we find the new modules of OpenCart? A: www.OpenCart.com contributions and forum pages are the essential sources to find new modules and/or ask for new ones from developers. Q: What do you mean by Payment Gateway? A: A payment gateway is an online analogue of a physical credit card processing terminal that we can locate in retail shops. Its function is to process credit card information and return the results back to the store system. You can imagine the payment gateway as an element in the middle of an online store and credit card network. The software part of this service is included in OpenCart but we will have to use one of the payment gateway services. Q: What are the payment methods in OpenCart? A: The current OpenCart version supports many established payment systems, including PayPal services, Authorize.net, Moneybookers, 2Checkout, and so on, as well as basic payment options such as Cash on Delivery, Bank Transfer, Check/money order, etc. Q: In which currency is the total amount calculated? A: PayPal automatically localizes the total amount according to the PayPal owner's account currency. Q: Whats the difference between PayPal Website Payment Standard and PayPal Website Payment Pro? A: PayPal Website Payment Standard is the easiest method to implement accepting credit card payments on an online store. There are no monthly fees or setup costs charged by PayPal. PayPal Website Payment Pro is the paid PayPal solution for an online store as a payment gateway and merchant account. The biggest difference from PayPal Website Payment Standard is that customers do not leave the website for credit card processing. The credit card information is completely processed in the online store as it is the popular method of all established e-commerce websites. Q: Which of the two PayPal products is recommended? A: For a beginner OpenCart administrator who wants to use PayPal for the online store, it is recommended to get experience with the free Standard payment option and then upgrade to the Pro option.
Read more
  • 0
  • 0
  • 2644

article-image-starting-ogre-3d
Packt
25 Nov 2010
7 min read
Save for later

Starting Ogre 3D

Packt
25 Nov 2010
7 min read
  OGRE 3D 1.7 Beginner's Guide Create real time 3D applications using OGRE 3D from scratch Easy-to-follow introduction to OGRE 3D Create exciting 3D applications using OGRE 3D Create your own scenes and monsters, play with the lights and shadows, and learn to use plugins Get challenged to be creative and make fun and addictive games on your own A hands-on do-it-yourself approach with over 100 examples Images         Read more about this book       (For more resources on this subject, see here.) Introduction Up until now, the ExampleApplication class has started and initialized Ogre 3D for us; now we are going to do it ourselves. Time for action – starting Ogre 3D This time we are working on a blank sheet. Start with an empty code file, include Ogre3d.h, and create an empty main function: #include "OgreOgre.h"int main (void){ return 0;} Create an instance of the Ogre 3D Root class; this class needs the name of the "plugin.cfg": "plugin.cfg":Ogre::Root* root = new Ogre::Root("plugins_d.cfg"); If the config dialog can't be shown or the user cancels it, close the application: if(!root->showConfigDialog()){ return -1;} Create a render window: Ogre::RenderWindow* window = root->initialise(true,"Ogre3DBeginners Guide"); Next create a new scene manager: Ogre::SceneManager* sceneManager = root->createSceneManager(Ogre::ST_GENERIC); Create a camera and name it camera: Ogre::Camera* camera = sceneManager->createCamera("Camera");camera->setPosition(Ogre::Vector3(0,0,50));camera->lookAt(Ogre::Vector3(0,0,0));camera->setNearClipDistance(5); With this camera, create a viewport and set the background color to black: Ogre::Viewport* viewport = window->addViewport(camera);viewport->setBackgroundColour(Ogre::ColourValue(0.0,0.0,0.0)); Now, use this viewport to set the aspect ratio of the camera: camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/Ogre::Real(viewport->getActualHeight())); Finally, tell the root to start rendering: root->startRendering(); Compile and run the application; you should see the normal config dialog and then a black window. This window can't be closed by pressing Escape because we haven't added key handling yet. You can close the application by pressing CTRL+C in the console the application has been started from. What just happened? We created our first Ogre 3D application without the help of the ExampleApplication. Because we aren't using the ExampleApplication any longer, we had to include Ogre3D.h, which was previously included by ExampleApplication.h. Before we can do anything with Ogre 3D, we need a root instance. The root class is a class that manages the higher levels of Ogre 3D, creates and saves the factories used for creating other objects, loads and unloads the needed plugins, and a lot more. We gave the root instance one parameter: the name of the file that defines which plugins to load. The following is the complete signature of the constructor: Root(const String & pluginFileName = "plugins.cfg",const String &configFileName = "ogre.cfg",const String & logFileName = "Ogre.log") Besides the name for the plugin configuration file, the function also needs the name of the Ogre configuration and the log file. We needed to change the first file name because we are using the debug version of our application and therefore want to load the debug plugins. The default value is plugins.cfg, which is true for the release folder of the Ogre 3D SDK, but our application is running in the debug folder where the filename is plugins_d.cfg. ogre.cfg contains the settings for starting the Ogre application that we selected in the config dialog. This saves the user from making the same changes every time he/she start our application. With this file Ogre 3D can remember his choices and use them as defaults for the next start. This file is created if it didn't exist, so we don't append an _d to the filename and can use the default; the same is true for the log file. Using the root instance, we let Ogre 3D show the config dialog to the user in step 3. When the user cancels the dialog or anything goes wrong, we return -1 and with this the application closes. Otherwise, we created a new render window and a new scene manager in step 4. Using the scene manager, we created a camera, and with the camera we created the viewport; then, using the viewport, we calculated the aspect ratio for the camera. After creating all requirements, we tell the root instance to start rendering, so our result would be visible. Following is a diagram showing which object was needed to create the other: Adding resources We have now created our first Ogre 3D application, which doesn't need the ExampleApplication. But one important thing is missing: we haven't loaded and rendered a model yet. Time for action – loading the Sinbad mesh We have our application, now let's add a model. After setting the aspect ratio and before starting the rendering, add the zip archive containing the Sinbad model to our resources: Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../Media/packs/Sinbad.zip","Zip"); We don't want to index more resources at the moment, so index all added resources now: Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); Now create an instance of the Sinbad mesh and add it to the scene: Ogre::Entity* ent = sceneManager->createEntity("Sinbad.mesh");sceneManager->getRootSceneNode()->attachObject(ent); Compile and run the application; you should see Sinbad in the middle of the screen: What just happened? We used the ResourceGroupManager to index the zip archive containing the Sinbad mesh and texture files, and after this was done, we told it to load the data with the createEntity() call in step 3. Using resources.cfg Adding a new line of code for each zip archive or folder we want to load is a tedious task and we should try to avoid it. The ExampleApplication used a configuration file called resources.cfg in which each folder or zip archive was listed, and all the content was loaded using this file. Let's replicate this behavior. Time for action – using resources.cfg to load our models Using our previous application, we are now going to parse the resources.cfg. Replace the loading of the zip archive with an instance of a config file pointing at the resources_d.cfg: the resources_d.cfg:Ogre::ConfigFile cf;cf.load(«resources_d.cfg»); First get the iterator, which goes over each section of the config file: Ogre::ConfigFile::SectionIterator sectionIter =cf.getSectionIterator(); Define three strings to save the data we are going to extract from the config file and iterate over each section: Ogre::String sectionName, typeName, dataname;while (sectionIter.hasMoreElements()){ Get the name of the section: sectionName = sectionIter.peekNextKey(); Get the settings contained in the section and, at the same time, advance the section iterator; also create an iterator for the settings itself: Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext();Ogre::ConfigFile::SettingsMultiMap::iterator i; Iterate over each setting in the section: for (i = settings->begin(); i != settings->end(); ++i){ Use the iterator to get the name and the type of the resources: typeName = i->first;dataname = i->second; Use the resource name, type, and section name to add it to the resource index: Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname, typeName, sectionName); Compile and run the application, and you should see the same scene as before.
Read more
  • 0
  • 0
  • 7033
Modal Close icon
Modal Close icon