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

7019 Articles
Packt
18 Jun 2013
21 min read
Save for later

Atmosfall – Managing Game Progress with Coroutines

Packt
18 Jun 2013
21 min read
(For more resources related to this topic, see here.) What do we build? We'll explore this idea of managing progress through a game schedule by completing a scrolling shooter in the tradition of games such as Xevious or River Run, where the player maneuvers a ship around the screen, avoiding enemy fire and destroying enemy ships until he/she reaches a boss target. Enemies will include ships that fly various patterns across the screen, turrets that follow the scrolling background and turn to face the player's ship, and a boss at the end that takes many hits to destroy and moves in various directions, firing multiple weapons. The player's ship will be able to fire at points on the screen that the player touches. What does it do? The player maneuvers their ship around the screen as the ground scrolls under them from the top of the screen downward. As the scrolling background reaches certain points, enemies appear and fly or scroll around the screen, firing bullets as they go; the player must avoid the bullets as well as the ship itself while shooting back. Like the Deep Black game, this project will be based on Corona's Box2D-based physics library. In this version, most objects will be "sensors", meaning they only detect collisions, and do not bounce off of each other or transfer momentum. We'll also use Box2D's collision filters so that we don't need to process enemy ships colliding with each other, or bullets hitting each other. In the TranslationBuddy project, we got a taste of coroutines and how they can be used to bookmark a task that you're in the middle of and come back to it later. In this project, we'll take that concept much further, using coroutines to create scripted behavior that's carried out over time, which is the simplest part of what game players and developers usually refer to as AI. We'll create computer-controlled fighters that follow flight assignments which are predictable at run time, but easily customized by the designer. Why is it great? In addition to coroutines, we'll also use a Lua feature called environments to create a minimal language of very simple functions controlling intervals and enemy actions. Features like this can become useful in larger projects, where programmers and designers must collaborate on a project. In such projects, programmers are responsible for the code that carries out the actions which the enemies will take, but the decisions of what the enemies should do, when, and in what order, are made by game designers, and frequently have to be adjusted for best balance and fun. For this reason, it's good to let the designers edit these schedules and scripts themselves. Designers are usually not experienced programmers, although they often have a little knowledge of programming and scripting, so this simple language will make it much easier for the designers. How are we going to do it? For this project, we'll review the design, rather than creating it. While an indie programmer will often be designing their own games and then coding from their designs, any programmer at a studio is likely to be coding from a document given to them by a designer or design team. We will be managing game progress with the help of the following game coroutines: Founding the framework Moving the player Scheduling enemies Scripting behavior Controlling the boss Cleaning up and making the game playable What do I need to get started? First, open the file design.txt from the project pack and read through it, noting the [NYI] tags that indicate features still pending. In full development projects, this sort of status tracking will usually be carried out by a more complex database or dedicated tracking program, but even in small projects, a simple record of what has yet to be accomplished can be very useful. At this point, the game has files describing various ships (a broad category which also includes the ground-based, immobile turrets) as well as the various weapons with which the ships are equipped, the bullets they fire, and the explosions when they land. It also includes code that handles things taking damage—including events that can be tracked by user interface elements or gameplay progress tracking, processing user input into commands, and a long background made up of large tiles. A splash screen is already completed and appears when the game is launched. What the game still needs is actual level design. Enemies need to appear as time advances in the level, and carry out various plans of attack against the player. This means that there are two kinds of schedules required; the schedule of which enemies appear when, and the individual schedules of the enemies that dictate how each one flies and attacks after it is created. To make this happen, we'll not only create scheduling behaviors, but also modules that attach these behaviors and other suitable characteristics, such as orientation, to our predefined ships to make them into bosses and enemies. This distinction between units in a game that have statistics and behaviors, and the actors that represent them in the game world, is very powerful for scaling projects up in complexity. Once that's done, create a new project folder, Atmosfall, and copy the contents of the version 0 folder in the project pack directory. You should be able to load this project into the simulator and advance the game past the splash screen, seeing a ship in the middle of a swamp background. In the simulator, you can click anywhere on the game screen and watch the ship fire double bullets at the point at which you click. You can also build the game for a device and watch the ship slide around the screen as you tilt the device. The prototype responds to user input and is ready to start adding the scheduling and AI enemy control. Tracking progress through the level Games like this typically trigger enemy appearances and events based on how far the background has scrolled past the screen. To focus on the challenges of the project, we'll import the background itself and just add the scrolling logic to issue events that track this progress. Getting ready You should have already copied the partly completed project from the version 0 folder into your new project directory; if you haven't, do that now. Getting on with it We'll start by loading the new marsh background into the Ground layer of the game's view, instead of the blank rectangle that the project uses by default. Open the game.lua file and change the createScene function to load this module as the new background, as shown in the following code snippet: local group = self.viewself.Ground = require "level.marsh"(group)self.Mobs = display.newGroup() Then we adjust the scale of the background to make it fit into the width of the screen: self.Ground = require "level.marsh"(group)local scale = display.contentWidth / self.Ground.widthself.Ground.xScale, self.Ground.yScale = scale, scaleself.Mobs = display.newGroup() If you test the code at this point, you should see a static background filling the screen behind the player ship. Sliding the background Pinning a moving rectangle to another moving rectangle so that it doesn't slide too far and show the back side of the world requires a little bit of math, but we can offload this math onto Corona with a little ingenuity. First, when the scene starts, we'll make sure that in the willEnterScene responder, the background is lined up, with its bottom edge along the bottom edge of the screen. physics.setGravity(0, 0)self.Ground:setReferencePoint(display.BottomCenterReferencePoint)self.Ground.xOrigin, self.Ground.y = display.contentCenterX,display.contentHeightfor _, coordinates in ipairs(walls) do Before we can start the background moving, we need to know how long it's supposed to take. This could vary from level to level in a real game, so we will let the schedule we load provide this value (the file in question doesn't exist yet; creating it will be part of our next task, so make a note that it will need to return its total length) as shown in the following code: physics.setGravity(0, 0)self.Duration = require "level.marsh-enemies" (self)self.Ground:setReferencePoint(display.BottomCenterReferencePoint) Now that we know the desired length of the background scroll, we can start the transition in response to the enterScene event, once the scene has finished loading as shown in the following code snippet. This is where the magic happens and the explanation will follow once you've had a chance to scan it. self.Exit = nillocal bounds = self.Ground.contentBoundsself.Ground.Pan = transition.to(self.Ground,{time = self.Duration * 1000;y = 0, yReference = bounds.yMin - bounds.yMax;onComplete = function(object)object.enterFrame, object.Pan = nil, nilend})self.Lives = 2 The key here is that transition.to (and transition.from) can tween any value on any object that can be indexed, even though it usually gets applied to the visible properties of display objects. The yReference value has no visible effect on an object by itself; changing an object's yReference value changes what value its y position ends up being in its parent coordinates, but doesn't cause anything to move on the screen. However, when you combine this with continually adjusting the y position, it has the effect of changing the scale of the motion; setting the y position moves the object so that the point designated internally as its yReference value sits at the specified coordinate in its parent system. Image We also needed to know the distance to move the reference point in the group; the marsh module builds a group with its zero point, or origin, at its bottom. So eventually, we need to move the yReference value to a negative value equal to the functional height of the background. We figure this out from the height of its bounding rectangle. If you want to test this out, you'll have to temporarily replace self.Duration = require "marsh-enemies" (group) with self.Duration = 60. To temporarily sub out values like this, I often create an end-of-line comment, making the line look like the following: self.Duration = 60 -- require "level.marsh-enemies" (self) Then, to replace the old code, I can just delete the part that says 60 ––. Once you've inserted this place-holder, you can test the code and you'll see the background crawl past. However, if you're using a tall profile device, such as an iPhone 5, you may see that the bottom edge of the background first creeps down across the empty bar at the bottom of the screen, before filling it completely, and at the end, it will expose a bar of black at the top as it creeps into place. This is because when Corona uses letterbox alignment, it only positions the reference frame for drawing to leave space at the edges; it doesn't actually crop out anything that was hanging over the edges of the screen. But we can do this fairly easily by adding a mask to the display stage, the way we did on scenes in Project 3 to hide bits of overhanging text during transitions. To enforce this letterboxing globally throughout the program, we can add the mask in main.lua. require "input"display.currentStage:setMask(graphics.newMask("effect/masking-frame.png"))display.currentStage.maskX, display.currentStage.maskY = display.contentCenterX, display.contentCenterYlocal storyboard = require "storyboard" Tracking the background progress We need to track how far the schedule for the level will have advanced. We want this to be as fine-grained as we can manage, so we'll check the value as frequently as Corona will do, which is every frame. This means that an enterFrame listener is the logical vector which is shown in the following code snippet: Runtime:addEventListener('enterFrame', self.Ground)function self.Ground:enterFrame(event)endself.Lives = 2 For the schedule, we need to track time elapsed since the schedule starts. We'll make a note of the time when the scene begins, and post the Progress events that indicate what time the schedule has reached at, as shown in the following code: self.Ground.Start = system.getTimer()Runtime:addEventListener('enterFrame', self.Ground)function self.Ground:enterFrame(event) The other thing we want to track is the actual motion of the background. The first enemy we'll create is a turret, so if it doesn't appear to move in sync with the ground, the user will find that very distracting. This is a little trickier, since the ground's position and reference are both moving on the same sliding scale. Fortunately, there is another point that moves more predictably—the origin. The origin of an object is whichever point is considered (0, 0) for placing that object's reference point. For most objects, it's fixed at the object's center; for groups, it's (0, 0) in the group's coordinates, wherever the group's children happen to be placed in relation to it. In our case, what we're really concerned with is that the object's origin is fixed with respect to its visible contents in a way that the reference point isn't. So if the group moves down by three pixels on the screen, you can say confidently that its yOrigin value also increased by three (assuming that it's not parented to a group with a different yScale value). We can track the position of the ground's yOrigin value from frame to frame in order to determine how much it has visibly moved. We can include that information in the events we dispatch to supply the progress information as shown in the following code: self.Ground.Start = system.getTimer()self.Ground.oldY = self.Ground.yOriginRuntime:addEventListener('enterFrame', self.Ground)function self.Ground:enterFrame(event)scene:dispatchEvent{name = 'Progress'; time = (event.time - self.Start) / 1000; delta = self.yOrigin - self.oldY}self.oldY = self.yOriginend Our schedule module will feed off these events to update its progress and trigger actions. First, however, we need something for the schedule module to do; schedules for levels will consist of spawning enemies at different intervals. Constructing the enemy behavior For the schedule to spawn new enemies, we need one to exist. We'll start with a simple one, that just moves in sync with the ground to start with. Once that works, we'll add tracking and weapon fire.. Getting on with it Add a new file, turret.lua, and open it. This file will add turret behavior to a ship sprite and physics description specified in the starting project. Creating an enemy Add the basic description of the turret object's appearance and physics as shown in the following code: local ship = require "ship.ship"local category = require "category"local groundFilter = {groupIndex = category.enemy;}return function(game, x, y)local self = ship.turret(game, game.Mobs.Ground, groundFilter)self.x, self.y = x, yself.bodyType = 'static'return selfend This creates a turret that just sits perfectly still and does nothing, which isn't very interesting. The next thing we'll do is make it move in sync with the ground by following the Progress events that we added to the game in the last section as shown in the following code: self.bodyType = 'static'game:addEventListener('Progress', self)function self:Progress(event)if self.y thenself.y = self.y + event.deltaelsegame:removeEventListener('Progress', self)endendreturn self Since each Progress event contains the amount the screen moved, we can move the turret by the same amount. Now that this object has some basic behavior, it's time to start linking it into the game and at aching the scheduling mechanism. Save and switch to game.lua, and add a simple table before the event definitions using the following code: local scene = storyboard.newScene()scene.Spawn = {turret = require "turret";}function scene:createScene( event ) This means that we can call game.Spawn.turret(game, x, y) to create a new turret at x, y in the world for game. However, we're not going to call it directly. We'll create a schedule that contains functions to spawn enemies in a common, shared context (the game) to save the code having to contain the same values repeated an awful lot. Creating a schedule In order to have our turret appear at the right point, we'll create a schedule that spawns new enemies as the level progresses. Getting on with it Save game.lua for the moment and create a new file in the level folder called marsh-enemies.lua. This file will define a schedule module that's 60 seconds long, so that's the first thing we'll define using the following code: return function(game)local duration = 60return durationend At this point, if you previously put a placeholder duration in game.lua to test the background scroll, you can revert that to the code that uses this file. Next we'll use the schedule function (from a module that isn't created yet) to start our custom schedule function against the current game. This will take a few steps to make it fully clear, but showing you how it will be used in the following code should help you see why this setup is worth engineering: local duration = 60schedule(game,function()at (0.3) spawn.turret(50, -20)end)return duration Now here's the catch—the at and spawn.turret functions haven't been defined anywhere yet, and they won't be made local in this file or defined as globals, even though this function uses them as global. Our schedule function will create them in a custom environment. So for each schedule function, we'll create an environment that contains simplified actions on the game the schedule is for, and use it for the function that defines the schedule. We'll combine this with making the schedule function part of a coroutine, so that it can suspend itself, such as when it is waiting for a particular time to come up in the schedule. So, before moving on, load the module you're about to create into marsh-enemies.lua using the following code: local schedule = require "schedule"return function(game)local duration = 60 Building a schedule framework Save marsh-enemies.lua and create the file schedule.lua at the top of your project. This le won't actually be very long. The core is a function that starts each newly created coroutine, at aching the environment supplied to the schedule, running that schedule until it's complete, and finally disconnecting the schedule from the game so that it won't throw errors or take up processing time as shown in the following code: local function bind(game, listener, actions, schedule)setfenv(schedule, actions)schedule()game:removeEventListener('Progress', listener)end The rest of the module will be a function that does the work of setting it up. It'll create an environment that contains bridge actions to the main game, start a coroutine using our glue function, and start that coroutine with the schedule function and environment. This coroutine will wake up every time the game object receives a Progress event to see if there are any enemies it needs to spawn, create those required, and go back to waiting. We'll start by creating a blank environment and our coroutine: game:removeEventListener('Progress', listener)endreturn function(game, schedule)local actions = {}local self = coroutine.wrap(bind)end Unlike coroutine.create, coroutine.wrap returns a function that resumes the new coroutine each time it's called. It's usually a little more convenient, but be a little careful with coroutine.wrap because if any error is thrown inside the coroutine, it will bubble right up and affect the code calling the resume function. We'll then connect the new coroutine to be resumed for each Progress event sent to the game using the following code: local self = coroutine.wrap(bind)game:addEventListener('Progress', self)end We'll create a listener that stops feeding new Progress events into the schedule module when the game ends, such as when the player loses all of his or her lives as shown in the following code. This efiectively terminates the schedule; there's no way anymore to resume it and it will get garage-collected. game:addEventListener('Progress', self)local function close(event)if event.action == 'ended' thengame:removeEventListener('Progress', self)game:removeEventListener('Game', close)endendgame:addEventListener('Game', close)end Then, we'll start the coroutine with its schedule and environment, as well as the information it needs to clean itself up, and return the new coroutine in case the calling code has some use for it: game:addEventListener('Game', close)self(game, self, actions, schedule)return selfend Building the scheduled actions Of the two functions we've described, the at action is the simpler one. It checks the elapsed time in the schedule module; if it's not enough, it yields to keep waiting, but if its designated time has arrived, it returns from its loop and lets the schedule advance. This means the code is very straightforward as follows: local actions = {}function actions.at(time)repeatlocal progress = coroutine.yield()until progress.time >= timeendlocal self = coroutine.wrap(bind) Calling the function at may seem a little strange, but it allows the schedule calls to read much more like normal language. We could have called the function waitUntil and written the function waiting for it on another line, but Lua's loose syntax allows us to use this very compact format. The spawn functions are a little more complex. We could simply build them all like the following: function actions.spawn.turret(x, y)return game.Spawn.turret(game, x, y)end However, since each one would follow the same pattern, we can use another pattern based on metatables and the __index lookup, the self-populaing table. __index on a table's metatable is only used when the requested key isn't in the original table; this means that the function that creates the requested value can store it in the table, and next time, it will simply be retrieved from the table instead of being looked up in the __index table again. This makes the spawn action family easy to summarize in one block. actions.spawn = setmetatable({},{__index = function(t, name)local function cue(...)return game.Spawn[name](game, ...)endt[name] = cuereturn cueend})local self = coroutine.wrap(bind) That's actually all there is to the schedule system! You can test it out and watch the turret appear in the upper-left hand slide-down corner across the screen, mindlessly facing right and doing nothing. Bringing an enemy to life Making the turret work requires only two main steps. The first is to have it track the player. Since the game object keeps a reference to the Player object, this boils down to basic trigonometry. Open turret.lua and add a line to the Progress handler as shown in the following code: if self.y thenself.y = self.y + event.deltaself.rotation = math.deg(math.atan2(game.Player.y - self.y,game.Player.x - self.x))else The arctangent of the y and x distances gives the facing direction from the turret to the player, which we can use as the rotation angle to make the turret point at the player. If you try the code again you should see the turret stay pointed at the player as it scrolls down and the player moves. The last step is to give the turret a weapon. While we have the turret file open, have it start firing as soon as it is created: endself.Weapons.AntiAir:start(self, 100, 0)return self This depends on the turret having a weapon called AntiAir, which in this case was already created in the existing partial code. The turret is complete for the time being. If you test the code, it should shoot at the player, and bullets fired at it should vanish when they hit it. Currently, however, nothing gets destroyed no matter how many bullets hit it. What did we do? A lot of stuff happened in this section! Using coroutines to track a continuously advancing schedule of new enemies, using Lua environments to wrap up some complicated actions in some simple wrappers, and adding an advancing series of progression data to drive everything else. What else do I need to know? Environments are a powerful feature of Lua; each function has an associated environment which is just a table linked to that function. Whenever a function needs to use a global, it looks up the global name as a string key in that table. By changing a function's environment, we can give it access to a totally different set of global functions. The real power here will come from the fact that the environment that we link to our schedule will be stocked with functions that use the normal environment, and can therefore take actions whose particulars are hidden from the code using them. Lua creates a default environment to link to its code when it's started, containing all the standard global functions, and stores a link to that environment in that environment under the name _G, which you've probably used already.
Read more
  • 0
  • 0
  • 2223

article-image-apache-cloudstack-architecture
Packt
17 Jun 2013
17 min read
Save for later

Apache CloudStack Architecture

Packt
17 Jun 2013
17 min read
(For more resources related to this topic, see here.) Introducing cloud Before embarking on a journey to understand and appreciate CloudStack, let's revisit the basic concepts of cloud computing and how CloudStack can help us in achieving our private, public, or hybrid cloud objectives. Let's start this article with a plain and simple definition of cloud. Cloud is a shared multi-tenant environment built on a highly efficient, highly automated, and preferably virtualized IT infrastructure where IT resources can be provisioned on demand from anywhere over a broad network, and can be metered. Virtualization is the technology that has made the enablement of these features simpler and convenient. A cloud can be deployed in various models; including private, public, community or hybrid clouds. These deployment models can be explained as follows: Private cloud: In this deployment model, the cloud infrastructure is operated solely for an organization and may exist on premise or off premise. It can be managed by the organization or a third-party cloud provider. Public cloud: In this deployment model, the cloud service is provided to the general public or a large industry group, and is owned and managed by the organization providing cloud services. Community cloud: In this deployment model, the cloud is shared by multiple organizations and is supported by a specific community that has shared concerns. It can be managed by the organization or a third party provider, and can exist on premise or off premise. Hybrid cloud: This deployment model comprises two or more types of cloud (public, private, or community) and enables data and application portability between the clouds. A cloud—be it private, public, or hybrid—has the following essential characteristics: On-demand self service Broad network access Resource pooling Rapid elasticity or expansion Measured service Shared by multiple tenants Cloud has three possible service models, which means there are three types of cloud services that can be provided. They are: Infrastructure as a service (IaaS): This type of cloud service model provides IT infrastructure resources as a service to the end users. This model provides the end users with the capability to provision processing, storage, networks, and other fundamental computing resources that the customer can use to run arbitrary software including operating systems and applications. The provider manages and controls the underlying cloud infrastructure and the user has control over the operating systems, storage and deployed applications. The user may also have some control over the networking services. Platform as a service (PaaS): In this service model, the end user is provided with a platform that is provisioned over the cloud infrastructure. The provider manages the network, operating system, or storage and the end user has control over the applications and may have control over the hosting environment of the applications. Software as a service (SaaS): This layer provides software as a service to the end users, such as providing an online calculation engine for their end users. The end users can access these software using a thin client interface such as a web browser. The end users do not manage the underlying cloud infrastructure such as network, servers, OS, storage, or even individual application capabilities but may have some control over the application configurations settings. As depicted in the preceding diagram, the top layers of cloud computing are built upon the layer below it. In this book, we will be mainly dealing with the bottom layer—Infrastructure as a service. Thus providing Infrastructure as a Service essentially means that the cloud provider assembles the building blocks for providing these services, including the computing resources hardware, networking hardware and storage hardware. These resources are exposed to the consumers through a request management system which in turn is integrated with an automated provisioning layer. The cloud system also needs to meter and bill the customer on various chargeback models. The concept of virtualization enables the provider to leverage and pool resources in a multi-tenant model. Thus, the features provided by virtualization resource pooling, combined with modern clustering infrastructure, enable efficient use IT resources to provide high availability and scalability, increase agility, optimize utilization, and provide a multi-tenancy model. One can easily get confused about the differences between the cloud and a virtualized Datacenter; well, there are many differences, such as: The cloud is the next stage after the virtualization of datacenters. It is characterized by a service layer over the virtualization layer. Instead of bare computing resources, services are built over the virtualization platforms and provided to the users. Cloud computing provides the request management layer, provisioning layer, metering and billing layers along with security controls and multi-tenancy. Cloud resources are available to consumers on an on demand model wherein the resources can be provisioned and de-provisioned on an as needed basis. Cloud providers typically have huge capacities to serve variable workloads and manage variable demand from customers. Customers can leverage the scaling capabilities provided by cloud providers to scale up or scale down the IT infrastructure needed by the application and the workload. This rapid scaling helps the customer save money by using the capacity only when it is needed. The resource provisioning in the cloud is governed by policies and rules, and the process of provisioning is automated. Metering, Chargeback, and Billing are essential governance characteristics of any cloud environment as they govern and control the usage of precious IT resources. Thus setting up a cloud is basically building capabilities to provide IT resources as a service in a well-defined manner. Services can be provided to end users in various offerings, depending upon the amount of resources each service offering provides. The amount of resources can be broken down to multiple resources such as the computing capacity, memory, storage, network bandwidth, storage IOPS, and so on. A cloud provider can provide and meter multiple service offerings for the end users to choose from. Though the cloud provider makes upfront investments in creating the cloud capacity, however from a consumer's point of view the resources are available on demand on a pay per use model. Thus the customer gets billed for consumption just like in case of electricity or telecom services that individuals use. The billing may be based on hours of compute usage, the amount of storage used, bandwidth consumed, and so on. Having understood the cloud computing model, let's look at the architecture of a typical Infrastructure as a Service cloud environment. Infrastructure layer The Infrastructure layer is the base layer and comprises of all the hardware resources upon which IT is built upon. These include computing resources, storage resources, network resources, and so on. Computing resources Virtualization is provided using a hypervisor that has various functions such as enabling the virtual machines of the hosts to interact with the hardware. The physical servers host the hypervisor layer. The physical server resources are accessed through the hypervisor. The hypervisor layer also enables access to the network and storage. There are various hypervisors on the market such as VMware, Hyper-V, XenServer, and so on. These hypervisors are responsible for making it possible for one physical server to host multiple machines, and for enabling resource pooling and multi tenancy. Storage Like the Compute capacity, we need storage which is accessible to the Compute layer. The Storage in cloud environments is pooled just like the Compute and accessed through the virtualization layer. Certain types of services just offer storage as a service where the storage can be programmatically accessed to store and retrieve objects. Pooled, virtualized storage is enabled through technologies such as Network Attached Storage (NAS) and Storage Area Network (SAN) which helps in allowing the infrastructure to allocate storage on demand that can be based on policy, that is, automated. The storage provisioning using such technologies helps in providing storage capacity on demand to users and also enables the addition or removal of capacity as per the demand. The cost of storage can be differentiated according to the different levels of performance and classes of storage. Typically, SAN is used for storage capacity in the cloud where statefulness is required. Direct-attached Storage (DAS) can be used for stateless workloads that can drive down the cost of service. The storage involved in cloud architecture can be redundant and prevent the single point of failure. There can be multiple paths for the access of disk arrays to provide redundancy in case connectivity failures. The storage arrays can also be configured in a way that there is incremental backup of the allocated storage. The storage should be configured such that health information of the storage units is updated in the system monitoring service, which ensures that the outage and its impact are quickly identified and appropriate action can be taken in order to restore it to its normal state. Networks and security Network configuration includes defining the subnets, on-demand allocation of IP addresses, and defining the network routing tables to enable the flow of data in the network. It also includes enabling high availability services such as load balancing. Whereas the security configuration aims to secure the data flowing in the network that includes isolation of data of different tenants among each other and with the management data of cloud using techniques such as network isolation and security groups. Networking in the cloud is supposed to deal with the isolation of resources between multiple tenants as well as provide tenants with the ability to create isolated components. Network isolation in the cloud can be done using various techniques of network isolation such as VLAN, VXLAN, VCDNI, STT, or other such techniques. Applications are deployed in a multi-tenant environment and consist of components that are to be kept private, such as a database server which is to be accessed only from selected web servers and any other traffic from any other source is not permitted to access it. This is enabled using network isolation, port filtering, and security groups. These services help with segmenting and protecting various layers of application deployment architecture and also allow isolation of tenants from each other. The provider can use security domains, layer 3 isolation techniques to group various virtual machines. The access to these domains can be controlled using providers' port filtering capabilities or by the usage of more stateful packet filtering by implementing context switches or firewall appliances. Using network isolation techniques such as VLAN tagging and security groups allows such configuration. Various levels of virtual switches can be configured in the cloud for providing isolation to the different networks in the cloud environment. Networking services such as NAT, gateway, VPN, Port forwarding, IPAM systems, and access control management are used in the cloud to provide various networking services and accessibility. Some of these services are explained as follows: NAT: Network address translation can be configured in the environment to allow communication of a virtual machine in private network with some other machine on some other network or on the public Internet. A NAT device allows the modification of IP address information in the headers of IP packets while they are transformed from a routing device. A machine in a private network cannot have direct access to the public network so in order for it to communicate to the Internet, the packets are sent to a routing device or a virtual machine with NAT configured which has direct access to the Internet. NAT modifies the IP packet header so that the private IP address of the machine is not visible to the external networks. IPAM System/DHCP: An IP address management system or DHCP server helps with the automatic configuration of IP addresses to the virtual machines according to the configuration of the network and the IP range allocated to it. A virtual machine provisioned in a network can be assigned an IP address as per the user or is assigned an IP address from the IPAM. IPAM stores all the available IP addresses in the network and when a new IP address is to be allocated to a device, it is taken from the available IP pool, and when a device is terminated or releases the IP address, the address is given back to the IPAM system. Identity and access management: A access control list describes the permissions of various users on different resources in the cloud. It is important to define an access control list for users in a multi-tenant environment. It helps in restricting actions that a user can perform on any resource in the cloud. A role-based access mechanism is used to assign roles to users' profile which describes the roles and permissions of users on different resources. Use of switches in cloud A switch is a LAN device that works at the data link layer (layer 2) of the OSI model and provides multiport bridge. Switches store a table of MAC addresses and ports. Let us see the various types of switches and their usage in the cloud environment: Layer 3 switches: A layer-3 switch is a special type of switch which operates at layer 3—the Network layer of the OSI model. It is a high performance device that is used for network routing. A layer-3 switch has a IP routing table for lookups and it also forms a broadcast domain. Basically, a layer-3 switch is a switch which has a router's IP routing functionality built in. A layer-3 switch is used for routing and is used for better performance over routers. The layer-3 switches are used in large networks like corporate networks instead of routers. The performance of the layer-3 switch is better than that of a router because of some hardware-level differences. It supports the same routing protocols as network routers do. The layer-3 switch is used above the layer-2 switches and can be used to configure the routing configuration and the communication between two different VLANs or different subnets. Layer 4-7 switches: These switches use the packet information up to OSI layer 7 and are also known as content switches, web-switches, or application switches. These types of switches are typically used for load balancing among a group of servers which can be performed on HTTP, HTTPS, VPN, or any TCP/IP traffic using a specific port. These switches are used in the cloud for allowing policy-based switching—to limit the different amount of traffic on specific end-user switch ports. It can also be used for prioritizing the traffic of specific applications. These switches also provide forwarding decision making like NAT services and also manages the state of individual sessions from beginning to end thus acting like firewalls. In addition, these switches are used for balancing traffic across a cluster of servers as per the configuration of the individual session information and status. Hence these types of switches are used above layer-3 switches or above a cluster of servers in the environment. They can be used to forward packets as per the configuration such as transferring the packets to a server that is supposed to handle the requests and this packet forwarding configuration is generally based on the current server loads or sticky bits that binds the session to a particular server. Layer-3 traffic isolation provides traffic isolation across layer-3 devices. It's referred to as Virtual Routing and Forwarding (VRF). It virtualizes the routing table in a layer-3 switch and has set of virtualized tables for routing. Each table has a unique set of forwarding entries. Whenever traffic enters, it is forwarded using the routing table associated with the same VRF. It enables logical isolation of traffic as it crosses a common physical network infrastructure. VRFs provide access control, path isolation, and shared services. Security groups are also an example of layer-3 isolation capabilities which restricts the traffic to the guests based on the rules defined. The rules are defined based on the port, protocol, and source/destination of the traffic. Virtual switches: The virtual switches are software program that allows one guest VM to communicate with another and is similar to the Ethernet switch explained earlier. Virtual switches provide a bridge between the virtual NICs of the guest VMs and the physical NIC of the host. Virtual switches have port groups on one side which may or may not be connected to the different subnets. There are various types of virtual switches used with various virtualization technologies such as VMware Vswitch, Xen, or Open Vswitch. VMware also provides a distributed virtual switch which spans multiple hosts. The virtual switches consists of port groups at one end and an uplink at the other. The port groups are connected to the virtual machines and the uplink is mapped to the physical NIC of the host. The virtual switches function as a virtual switch over the hypervisor layer on the host. Management layer The Management layer in a cloud computing space provides management capabilities to manage the cloud setup. It provides features and functions such as reporting, configuration for the automation of tasks, configuration of parameters for the cloud setup, patching, and monitoring of the cloud components. Automation The cloud is a highly automated environment and all tasks such as provisioning the virtual machine, allocation of resources, networking, and security are done in a self-service mode through automated systems. The automation layer in cloud management software is typically exposed through APIs. The APIs allow the creation of SDKs, scripts, and user interfaces. Orchestration The Orchestration layer is the most critical interface between the IT organization and its infrastructure, and helps in the integration of the various pieces of software in the cloud computing platform. Orchestration is used to join together various individual tasks which are executed in a specified sequence with exception handling features. Thus a provisioning task for a virtual machine may involve various commands or scripts to be executed. The orchestration engine binds these individual tasks together and creates a provisioning workflow which may involve provisioning a virtual machine, adding it to your DNS, assigning IP Addresses, adding entries in your firewall and load balancer, and so on. The orchestration engine acts as an integration engine and also provides the capabilities to run an automated workflow through various subsystems. As an example, the service request to provision cloud resources may be sent to an orchestration engine which then talks to the cloud capacity layer to determine the best host or cluster where the workload can be provisioned. As a next step, the orchestration engine chooses the component to call to provision the resources. The orchestration platform helps in easy creation of complex workflows and also provides ease of management since all integrations are handled by a specialized orchestration engine and provide loose coupling. The orchestration engine is executed in the cloud system as an asynchronous job scheduler which orchestrates the service APIs to fulfill and execute a process. Task Execution The Task execution layer is at the lower level of the management operations that are performed using the command line or any other interface. The implementation of this layer can vary as per the platform on which the execution takes place. The activity of this layer is activated by the layers above in the management layer. Service Management The Service Management layer helps in compliance and provides means to implement automation and adapts IT service management best practices as per the policies of the organization, such as the IT Infrastructure Library (ITIL). This is used to build processes to implement different types of incident resolutions and also provide change management. The self service capability in cloud environment helps in providing users with a self-service catalog which consists of various service options that the user can request and provision resources from the cloud. The service layer can be comprised of various levels of services such as basic provisioning of virtual machines with some predefined templates/configuration, or can be of an advanced level with various options for provisioning servers with configuration options as well.
Read more
  • 0
  • 0
  • 8772

article-image-python-libraries-geospatial-development
Packt
17 Jun 2013
14 min read
Save for later

Python Libraries for Geospatial Development

Packt
17 Jun 2013
14 min read
(For more resources related to this topic, see here.) Reading and writing geospatial data While you could in theory write your own parser to read a particular geospatial data format, it is much easier to use an existing Python library to do this. We will look at two popular libraries for reading and writing geospatial data: GDAL and OGR. GDAL/OGR Unfortunately, the naming of these two libraries is rather confusing. Geospatial Data Abstraction Library ( GDAL), was originally just a library for working with raster geospatial data, while the separate OGR library was intended to work with vector data. However, the two libraries are now partially merged, and are generally downloaded and installed together under the combined name of "GDAL". To avoid confusion, we will call this combined library GDAL/OGR and use "GDAL" to refer to just the raster translation library. A default installation of GDAL supports reading 116 different raster file formats, and writing to 58 different formats. OGR by default supports reading 56 different vector file formats, and writing to 30 formats. This makes GDAL/OGR one of the most powerful geospatial data translators available, and certainly the most useful freely-available library for reading and writing geospatial data. GDAL design GDAL uses the following data model for describing raster geospatial data: Let's take a look at the various parts of this model: A dataset holds all the raster data, in the form of a collection of raster "bands", along with information that is common to all these bands. A dataset normally represents the contents of a single file. A raster band represents a band, channel, or layer within the image. For example, RGB image data would normally have separate bands for the red, green, and blue components of the image. The raster size specifies the overall width and height of the image, in pixels. The georeferencing transform converts from (x, y) raster coordinates into georeferenced coordinates—that is, coordinates on the surface of the earth. There are two types of georeferencing transforms supported by GDAL: affine transformations and ground control points. An affine transformation is a mathematical formula allowing the following operations to be applied to the raster data: More than one of these operations can be applied at once; this allows you to perform sophisticated transforms such as rotations. Affine transformations are sometimes referred to as linear transformations. Ground Control Points ( GCPs) relate one or more positions within the raster to their equivalent georeferenced coordinates, as shown in the following figure: Note that GDAL does not translate coordinates using GCPs— that is left up to the application, and generally involves complex mathematical functions to perform the transformation. The coordinate system describes the georeferenced coordinates produced the georeferencing transform. The coordinate system includes the projection and datum, as well as the units and scale used by the raster data. The metadata contains additional information about the dataset as a whole. Each raster band contains the following (among other things): The band raster size: This is the size (number of pixels across and number of lines high) for the data within the band. This may be the same as the raster size for the overall dataset, in which case the dataset is at full resolution, or the band's data may need to be scaled to match the dataset. Some band metadata providing extra information specific to this band. A color table describing how pixel values are translated into colors. The raster data itself. GDAL provides a number of drivers which allow you to read (and sometimes write) various types of raster geospatial data. When reading a file, GDAL selects a suitable driver automatically based on the type of data; when writing, you first select the driver and then tell the driver to create the new dataset you want to write to. GDAL example code A Digital Elevation Model ( DEM) file contains height values. In the following example program, we use GDAL to calculate the average of the height values contained in a sample DEM file. In this case, we use a DEM file downloaded from the GLOBE elevation dataset: from osgeo import gdal,gdalconst import struct dataset = gdal.Open("data/e10g") band = dataset.GetRasterBand(1) fmt = "<" + ("h" * band.XSize) totHeight = 0 for y in range(band.YSize): scanline = band.ReadRaster(0, y, band.XSize, 1, band.XSize, 1, band.DataType) values = struct.unpack(fmt, scanline) for value in values: if value == -500: # Special height value for the sea -> ignore. continue totHeight = totHeight + value average = totHeight / (band.XSize * band.YSize) print "Average height =", average As you can see, this program obtains the single raster band from the DEM file, and then reads through it one scanline at a time. We then use the struct standard Python library module to read the individual height values out of the scanline. Because the GLOBE dataset uses a special height value of -500 to represent the ocean, we exclude these values from our calculations. Finally, we use the remaining height values to calculate the average height, in meters, over the entire DEM data file. OGR design OGR uses the following model for working with vector-based geospatial data: Let's take a look at this design in more detail: The data source represents the file you are working with—though it doesn't have to be a file. It could just as easily be a URL or some other source of data. The data source has one or more layers , representing sets of related data. For example, a single data source representing a country may contain a "terrain" layer, a "contour lines" layer, a "roads" later, and a "city boundaries" layer. Other data sources may consist of just one layer. Each layer has a spatial reference and a list of features. The spatial reference specifies the projection and datum used by the layer's data. A feature corresponds to some significant element within the layer. For example, a feature might represent a state, a city, a road, an island, and so on. Each feature has a list of attributes and a geometry. The attributes provide additional meta-information about the feature. For example, an attribute might provide the name for a city's feature, its population, or the feature's unique ID used to retrieve additional information about the feature from an external database. Finally, the geometry describes the physical shape or location of the feature. Geometries are recursive data structures that can themselves contain sub-geometries—for example, a "country" feature might consist of a geometry that encompasses several islands, each represented by a subgeometry within the main "country" geometry. The geometry design within OGR is based on the Open Geospatial Consortium's "Simple Features" model for representing geospatial geometries. For more information, see http://www.opengeospatial.org/standards/sfa . Like GDAL, OGR also provides a number of drivers which allow you to read (and sometimes write) various types of vector-based geospatial data. When reading a file, OGR selects a suitable driver automatically; when writing, you first select the driver and then tell the driver to create the new data source to write to. OGR example code The following example program uses OGR to read through the contents of a shapefile, printing out the value of the NAME attribute for each feature along with the geometry type: from osgeo import ogr shapefile = ogr.Open("TM_WORLD_BORDERS-0.3.shp") layer = shapefile.GetLayer(0) for i in range(layer.GetFeatureCount()): feature = layer.GetFeature(i) name = feature.GetField("NAME") geometry = feature.GetGeometryRef() print i, name, geometry.GetGeometryName() Documentation GDAL and OGR are well documented, but with a catch for Python programmers. The GDAL/OGR library and associated command-line tools are all written in C and C++. Bindings are available which allow access from a variety of other languages, including Python, but the documentation is all written for the C++ version of the libraries. This can make reading the documentation rather challenging—not only are all the method signatures written in C++, but the Python bindings have changed many of the method and class names to make them more "pythonic". Fortunately, the Python libraries are largely self-documenting, thanks to all the docstrings embedded in the Python bindings themselves. This means you can explore the documentation using tools such as Python's built-in pydoc utility, which can be run from the command line like this: % pydoc -g osgeo This will open up a GUI window allowing you to read the documentation using a web browser. Alternatively, if you want to find out about a single method or class, you can use Python's built-in help() command from the Python command line, like this: >>> import osgeo.ogr >>> help(osgeo.ogr.DataSource.CopyLayer) Not all the methods are documented, so you may need to refer to the C++ docs on the GDAL website for more information, and some of the docstrings are copied directly from the C++ documentation—but in general the documentation for GDAL/OGR is excellent, and should allow you to quickly come up to speed using this library. Availability GDAL/OGR runs on modern Unix machines, including Linux and Mac OS X, as well as most versions of Microsoft Windows. The main website for GDAL can be found at: http://gdal.org The main website for OGR is at: http://gdal.org/ogr To download GDAL/OGR, follow the Downloads link on the main GDAL website. Windows users may find the FWTools package useful, as it provides a wide range of geospatial software for win32 machines, including GDAL/OGR and its Python bindings. FWTools can be found at: http://fwtools.maptools.org For those running Mac OS X, prebuilt binaries can be obtained from: http://www.kyngchaos.com/software/frameworks Make sure that you install GDAL Version 1.9 or later, as you will need this version to work through the examples in this book. Being an open source package, the complete source code for GDAL/OGR is available from the website, so you can compile it yourself. Most people, however, will simply want to use a prebuilt binary version. Dealing with projections One of the challenges of working with geospatial data is that geodetic locations (points on the Earth's surface) are mapped into a two-dimensional Cartesian plane using a cartographic projection. Whenever you have some geospatial data, you need to know which projection that data uses. You also need to know the datum (model of the Earth's shape) assumed by the data. A common challenge when dealing with geospatial data is that you have to convert data from one projection/datum to another. Fortunately, there is a Python library pyproj which makes this task easy. pyproj pyproj is a Python "wrapper" around another library called PROJ.4. "PROJ.4" is an abbreviation for Version 4 of the PROJ library. PROJ was originally written by the US Geological Survey for dealing with map projections, and has been widely used in geospatial software for many years. The pyproj library makes it possible to access the functionality of PROJ.4 from within your Python programs. Design The pyproj library consists of the following pieces: pyproj consists of just two classes: Proj and Geod. Proj converts from longitude and latitude values to native map (x, y) coordinates, and vice versa. Geod performs various Great Circle distance and angle calculations. Both are built on top of the PROJ.4 library. Let's take a closer look at these two classes. Proj Proj is a cartographic transformation class, allowing you to convert geographic coordinates (that is, latitude and longitude values) into cartographic coordinates (x, y values, by default in meters) and vice versa. When you create a new Proj instance, you specify the projection, datum, and other values used to describe how the projection is to be done. For example, to use the Transverse Mercator projection and the WGS84 ellipsoid, you would do the following: projection = pyproj.Proj(proj='tmerc', ellps='WGS84') Once you have created a Proj instance, you can use it to convert a latitude and longitude to an (x, y) coordinate using the given projection. You can also use it to do an inverse projection—that is, converting from an (x, y) coordinate back into a latitude and longitude value again. The helpful transform() function can be used to directly convert coordinates from one projection to another. You simply provide the starting coordinates, the Proj object that describes the starting coordinates' projection, and the desired ending projection. This can be very useful when converting coordinates, either singly or en masse. Geod Geod is a geodetic computation class, which allows you to perform various Great Circle calculations. We looked at Great Circle calculations earlier, when considering how to accurately calculate the distance between two points on the Earth's surface. The Geod class, however, can do more than this: The fwd() method takes a starting point, an azimuth (angular direction) and a distance, and returns the ending point and the back azimuth (the angle from the end point back to the start point again):   The inv() method takes two coordinates and returns the forward and back azimuth as well as the distance between them:   The npts() method calculates the coordinates of a number of points spaced equidistantly along a geodesic line running from the start to the end point:   When you create a new Geod object, you specify the ellipsoid to use when performing the geodetic calculations. The ellipsoid can be selected from a number of predefined ellipsoids, or you can enter the parameters for the ellipsoid (equatorial radius, polar radius, and so on) directly. Example code The following example starts with a location specified using UTM zone 17 coordinates. Using two Proj objects to define the UTM Zone 17 and lat/long projections, it translates this location's coordinates into latitude and longitude values: import pyproj UTM_X = 565718.5235 UTM_Y = 3980998.9244 srcProj = pyproj.Proj(proj="utm", zone="11", ellps="clrk66", units="m") dstProj = pyproj.Proj(proj="longlat", ellps="WGS84", datum="WGS84") long,lat = pyproj.transform(srcProj, dstProj, UTM_X, UTM_Y) print "UTM zone 11 coordinate (%0.4f, %0.4f) = %0.4f, %0.4f" % (UTM_X, UTM_Y, lat, long) Continuing on with this example, let's take the calculated lat/long values and, using a Geod object, calculate another point 10 kilometers northeast of that location: angle = 315 # 315 degrees = northeast. distance = 10000 geod = pyproj.Geod(ellps="WGS84") long2,lat2,invAngle = geod.fwd(long, lat, angle, distance) print "%0.4f, %0.4f is 10km northeast of %0.4f, %0.4f" % (lat2, long2, lat, long) Documentation The documentation available on the pyproj website, and in the docs directory provided with the source code, is excellent as far as it goes. It describes how to use the various classes and methods, what they do and what parameters are required. However, the documentation is rather sparse when it comes to the parameters used when creating a new Proj object. As the documentation says: A Proj class instance is initialized with proj map projection control parameter key/value pairs. The key/value pairs can either be passed in a dictionary, or as keyword arguments, or as a proj4 string (compatible with the proj command). The documentation does provide a link to a website listing a number of standard map projections and their associated parameters, but understanding what these parameters mean generally requires you to delve into the PROJ documentation itself. The documentation for PROJ is dense and confusing, even more so because the main manual is written for PROJ Version 3, with addendums for later versions. Attempting to make sense of all this can be quite challenging. Fortunately, in most cases you won't need to refer to the PROJ documentation at all. When working with geospatial data using GDAL or OGR, you can easily extract the projection as a "proj4 string" which can be passed directly to the Proj initializer. If you want to hardwire the projection, you can generally choose a projection and ellipsoid using the proj="..." and ellps="..." parameters, respectively. If you want to do more than this, though, you will need to refer to the PROJ documentation for more details. To find out more about PROJ, and to read the original documentation, you can find everything you need at: http://trac.osgeo.org/proj
Read more
  • 0
  • 0
  • 8088

article-image-ibm-cognos-workspace-advanced
Packt
14 Jun 2013
5 min read
Save for later

IBM Cognos Workspace Advanced

Packt
14 Jun 2013
5 min read
(For more resources related to this topic, see here.) Who should use Cognos Workspace Advanced? With Cognos Workspace Advanced, business users have one tool for creating advanced analyses and reports. The tool, like Query Studio and Analysis Studio, is designed for ease of use and is built on the same platform as the other report development tools in Cognos. Business Insight Advanced/Cognos Workspace Advanced is actually so powerful that it is being positioned more as a light Cognos Report Studio than as a powerful Cognos Query Studio and Cognos Analysis Studio. Comparing to Cognos Query Studio and Cognos Analysis Studio With so many options for business users, how do we know which tool to use? The best approach for making this decision is to consider the similarities and differences between the options available. In order to help us do so, we can use the following table: Feature Query Studio Analysis Studio Cognos Workspace Advanced Ad hoc reporting X   X Ad hoc analysis   X X Basic charting X X X Advanced charting     X Basic filtering X X X Advanced filtering     X Basic calculations X X X Advanced calculations     X Properties pane     X External data     X Freeform design     X As you can see from the table, all three products have basic charting, basic filtering, and basic calculation features. Also, we can see that Cognos Query Studio and Cognos Workspace Advanced both have ad hoc reporting capabilities, while Cognos Analysis Studio and Cognos Workspace Advanced both have ad hoc analysis capabilities. In addition to those shared capabilities, Cognos Workspace Advanced also has advanced charting, filtering, and calculation features. Cognos Workspace Advanced also has a limited properties pane (similar to what you would see in Cognos Report Studio). Furthermore, Cognos Workspace Advanced allows end users to bring in external data from a flat file and merge it with the data from Cognos Connection. Finally, Cognos Workspace Advanced has free-form design capabilities. In other words, you are not limited in where you can add charts or crosstabs in the way that Cognos Query Studio and Cognos Analysis Studio limit you to the standard templates. The simple conclusion after performing this comparison is that you should always use Cognos Workspace Advanced. While that will be true for some users, it is not true for all. With the additional capabilities come additional complexities. For your most basic business users, you may want to keep them using Cognos Query Studio or Cognos Analysis Studio for their ad hoc reporting and ad hoc analysis simply because they are easier tools to understand and use. However, for those business users with basic technical acumen, Cognos Workspace Advanced is clearly the superior option. Accessing Cognos Workspace Advanced I would assume now that, after reviewing the capabilities Cognos Workspace Advanced brings to the table, you are anxious to start using it. We will start off by looking at how to access the product. The first way to access Cognos Workspace Advanced is through the welcome page. On the welcome page, you can get to Cognos Workspace Advanced by clicking on the option Author business reports: This will bring you to a screen where you can select your package. In Cognos Query Studio or Cognos Analysis Studio, you will only be able to select non-dimensional and dimensional packages based on the tool you are using. With Cognos Workspace Advanced, because the tool can use both dimensional and non-dimensional packages, you will be prompted with packages for both. The next way to access Cognos Workspace Advanced is through the Launch menu in Cognos Connection. Within the menu, you can simply choose Cognos Workspace Advanced to be taken to the same options for choosing a package. Note, however, that if you have already navigated into a package, it will automatically launch Cognos Workspace Advanced using the very same package. The third way to access Cognos Workspace Advanced is by far the most functional way. You can actually access Cognos Workspace Advanced from within Cognos Workspace by clicking on the Do More... option on a component of the dashboard: When you select this option, the object will expand out and open for editing inside Cognos Workspace Advanced. Then, once you are done editing, you can simply choose the Done button in the upper right-hand corner to return to Cognos Workspace with your newly updated object. For the sake of showing as many features as possible in this chapter, we will launch Cognos Workspace Advanced from the welcome page or from the Launch menu and select a package that has an OLAP data source. For the purpose of following along, we will be using the Cognos BI sample package great_outdoors_8 (or Great Outdoors). When we first access it, we are prompted to choose a package. For these examples, we will choose great_outdoors_8: We are then brought to a splash screen where we can choose Create new or Open existing. We will choose Create new. We are then prompted to pick the type of chart we want to create. As we will see from the following screenshot, our options are: Blank: It starts us off with a completely blank slate List: It starts us off with a list report Crosstab: It starts us off with a crosstab Chart: It starts us off with a chart and loads the chart wizard Financial: It starts us off with a crosstab formatted like a financial report Existing...: It allows us to open an existing report We will choose Blank because we can still add as many of the other objects as we want to later on.
Read more
  • 0
  • 0
  • 3242

article-image-architecture-freeswitch
Packt
14 Jun 2013
13 min read
Save for later

Architecture of FreeSWITCH

Packt
14 Jun 2013
13 min read
(For more resources related to this topic, see here.) A revolution has begun and secrets have been revealed How and why the telephone works is a mystery to most people. It has been kept secret for years. We just plugged our phones into the wall and they worked, and most people do just that and expect it to work. The telephony revolution has begun, and we have begun to pry its secrets from the clutches of the legacy of the telephony industry. Now, everyday individuals like you and me are able to build phone systems that outperform traditional phone services and offer advanced features for relatively low cost. Some people even use FreeSWITCH to provide telephone services for making a profit. FreeSWITCH has been designed to make all of this easier, so we will go over the architecture to get a better understanding of how it works. Do not be concerned if some of the concepts we introduce seem unnaturally abstract. Learning telephony takes time, especially VoIP. In fact, we recommend that you read this article more than once. Absorb as much as you can on the first pass. You will be surprised at how much your understanding of VoIP and FreeSWITCH has improved.Give yourself plenty of time to digest all of these strange new concepts, and soon you will find that you are a skilled FreeSWITCH administrator. If you keep at it, you will be rewarded with a meaningful understanding of this strange and wonderful world we call telephony. Telephones and telephony systems (such as telephone switches and PBXs) are very complicated and have evolved over the years into several varieties. The most popular type of phone in the U.K. and the U.S. is the traditional analog phone, which we affectionately refer to as POTS lines or Plain Old Telephone Service. From the traditional Ma Bell phone up to the long-range cordless phones that most of us have today, one thing has remained the same—the underlying technology. In the last 10-15 years, there has been a convergence of technology between computers and telephones that has produced a pair of affordable alternatives to POTS lines—Mobile phones and VoIP phones (also called Internet Phones). FreeSWITCH fits into this big tangled mess of various telephone technologies by bridging them together, so that they can communicate despite being otherwise completely incompatible. FreeSWITCH also bridges telephone calls with computer programs that you can write yourself, and controls what happens in ways like never before. FreeSWITCH is software that runs on Windows and several UNIX varieties such as Mac OS X, Linux, Solaris, and BSD. This means you can install FreeSWITCH on your home PC or even a high-end server and use it to process phone calls. The FreeSWITCH design – modular, scalable, and stable The design goal of FreeSWITCH is to provide a modular, scalable system around a stable switching core, and to provide a robust interface for developers to add to and control the system. Various elements in FreeSWITCH are independent of each other and do not have much knowledge about how the other parts are working, other than what is provided in what are called exposed functions. The functionality of FreeSWITCH can also be extended with loadable modules, which tie a particular external technology into the core. FreeSWITCH has many different module types that revolve around the central core, much like satellites orbiting a planet. The list includes: Module type: Purpose: Endpoint Telephone protocols like SIP/H.323 and POTS lines Application Performs a task such as playing audio or setting data Application Programming Interface (API) Exports a function that takes text input and returns text output, which could be used across modules or from an external connection Automated Speech Recognition (ASR) Interfaces with speech recognition systems Chat Bridges and exchanges various chat protocols Codec Translates between audio formats Dialplan Parses the call details and decides where to route the call Directory Connects directory information services, such as LDAP, to a common core lookup API Event handlers Allows external programs to control FreeSWITCH File Provides an interface to extract and play sound from various audio file formats Formats Plays audio files in various formats Languages Programming language interfaces used for call control Loggers Controls logging to the console, system log, or log files Say Strings together audio files in various languages to provide feedback to say things like phone numbers, time of day, spell words, and so on Text-To-Speech (TTS) Interfaces with text-to-speech engines Timers POSIX or Linux kernel timing in applications XML Interfaces Uses XML for Call Detail Records (CDRs), RADIUS, CURL, LDAP, RPC, and/or SCGI The following image shows what the FreeSWITCH architecture looks like and how the modules orbit the core of FreeSWITCH: By combining the functionality of the various module interfaces, FreeSWITCH can be configured to connect IP phones, POTS lines, and IP-based telephone services. It can also translate audio formats and interfaces with a custom menu system, which you can create by yourself. You can even control a running FreeSWITCH server from another machine. Let's start by taking a closer look at a pair of important module types. Important modules – Endpoint and Dialplan Endpoint modules are critically important and add some of the key features that make FreeSWITCH the powerful platform it is today. The primary role of these modules is to take certain common communication technologies and normalize them into a common abstract entity which we refer to as a session. A session represents a connection between FreeSWITCH and a particular protocol. There are several Endpoint modules that come with FreeSWITCH, which implement several protocols such as SIP, H.323, Jingle (Google Talk), and some others. We will spend some time examining one of the more popular modules named mod_sofia. Sofia-SIP (http://sofia-sip.sourceforge.net) is an open source project sponsored by Nokia, which provides a programming interface for the Session Initiation Protocol (SIP). We use this library in FreeSWITCH in a module we call mod_sofia. This module registers to all the hooks in FreeSWITCH necessary to make an Endpoint module, and translates the native FreeSWITCH constructs into SIP constructs and back again. Configuration information is taken from the central FreeSWITCH configuration files, which allows mod_sofia to load user-defined preferences and connection details. This allows FreeSWITCH to accept registration from SIP phones and devices, register to other SIP Endpoints such as service providers, send notifications, and provide services to the phones such as voicemail. The SIP protocol is defined by a number of RFC (request for comment) documents. The primary RFC can be found at http://www.ietf.org/rfc/rfc3261.txt When a SIP call is established between FreeSWITCH and another SIP device, it will show up in FreeSWITCH as an active session. If the call is inbound, it can be transferred or bridged to interactive voice response (IVR) menus, hold music, or one or more extensions, though numerous other options are available. Let's examine a typical scenario where an SIP phone registered as extension 2000 dials extension 2001 with the hope of establishing a call. First, the SIP phone sends a call setup message to mod_sofia over the network (mod_sofia is listening for such messages). After receiving the message, mod_sofia in turn parses the relevant details and passes the call into the core state machine in FreeSWITCH. The state machine (in the FreeSWITCH core) then sends the call into the ROUTING state. The next step is to locate the Dialplan module based on the configuration data for the calling Endpoint. The default and most widely used Dialplan module is the XML Dialplan module. This module is designed to look up a list of instructions from the central XML registry within FreeSWITCH. The XML Dialplan module will parse a series of XML extension objects using regular expression pattern-matching. As we are trying to call 2001, we hope to find an XML extension testing the destination_number field for something that matches 2001 and routes accordingly. The Dialplan is not limited to matching only a single extension. The XML Dialplan module builds a sort of task list for the call. Each extension that matches it will have its actions added to the call's task list. Assuming FreeSWITCH finds at least one extension, the XML Dialplan will insert instructions into the session object with the information it needs to try and connect the call to 2001. Once these instructions are in place, the state of the calling session changes from ROUTING to EXECUTE, where the next handler drills down the list and executes the instructions obtained during the ROUTING state. This is where the application interface comes into the picture. Each instruction is added to the session in the form of an application name and a data argument that will be passed to that application. The one we will use in this example is the bridge application. The purpose of this application is to create another session with an outbound connection, then connect the two sessions for direct audio exchange. The argument we will supply to bridge will be user/2001, which is the easiest way to generate a call to extension 2001. A Dialplan entry for 2001 might look like this: <extension name="example"><condition field="destination_number"expression="^2001$"><action application="bridge" data="user/2001"/></condition></extension> The extension is named example, and it has a single condition to match. If the condition is matched, it has a single application to execute. In plain language, the mentioned extension could be expressed like this: If the caller dialed 2001, this establishes a connection between the calling party and the endpoint (that is, telephone) at 2001. Consider how this happens. Once we have inserted the instructions into the session, the session's state will change to EXECUTE, and the FreeSWITCH core will use the data collected to perform the desired action. First, the default execute state handler will parse the command to execute bridge on user/2001, then it will look up the bridge application and pass the user/2001 data in. This will cause the FreeSWITCH core to create a new outbound session of the desired type. User 2001 is also a SIP phone, so user/2001 will resolve into a SIP dial string, which will be passed to mod_sofia to ask it to create a new outbound session. If the setup for that new session is successful, there will now be two sessions in the FreeSWITCH core. The bridge application will take the new session and the original session (the caller's phone) and call the bridge function on it. This allows the audio to flow in both directions once the person at extension 2001 actually answers the phone. If that user was unable to answer or was busy, a timeout (that is, a failure) would occur and send the corresponding message back to the caller's phone. If a call is unanswered or an extension is busy, many routing options are possible, including call forwarding or voicemail. All of this happens from the simple action of picking up the phone handset and dialing 2 0 0 1. FreeSWITCH takes all of the complexity of SIP and reduces it to a common denominator. From there, it reduces the complexity further by allowing us to configure a single instruction in the Dialplan to connect the phone at 2000 to the phone at 2001. If we want to allow the phone at 2001 to be able to call the phone at 2000, we can add another entry in the Dialplan going the other way: <extension name="example 2"><condition field="destination_number" expression="^2000$"><action application="bridge" data="user/2000"/></condition></extension> In this scenario, the Endpoint module turned SIP into a FreeSWITCH session and the Dialplan module turned XML into an extension. The bridge application turned the complex code of creating an outbound call and connecting the audio into a simple application/data pair. Both the Dialplan module and the application module interface are designed around regular FreeSWITCH sessions. Therefore, not only does the abstraction make life easier for us at the user level, it also simplifies the design of the application and the Dialplan because they can be made agnostic of the actual endpoint technology involved in the call. It is because of this abstraction, when we make up a new Endpoint module tomorrow for something like Skype (there is actually such a thing present, by the way), that we can reuse all the same application and Dialplan modules. The same principle applies to the Say, Automatic Speech Recognition (ASR), Text-to-Speech (TTS), and other such modules. It is possible that you may want to work with some specific data provided by the Endpoint's native protocol. In SIP, for instance, there are several arbitrary headers as well as several other bits of interesting data from the SIP packets. We solve this problem by adding variables to the channel. Using channel variables, mod_sofia can set these arbitrary values as they are encountered in the SIP data where you can retrieve them by name from the channel in your Dialplan or application. This way, we share our knowledge of these special variables with the SIP Endpoint. However, the FreeSWITCH core just sees them as arbitrary channel variables that the core can ignore. There are also several special reserved channel variables that can influence the behavior of FreeSWITCH in many interesting ways. If you have ever used a scripting language or configuration engine that uses variables (sometimes called attribute-value pairs or AVPs), you are at an advantage because channel variables are pretty much the same concept. There is simply a variable name and a value that is passed to the channel and the data is set. There is even an application interface for this, the set application, which lets you set your own variables from the Dialplan: <extension name="example 3"><condition field="destination_number" expression="^2000$"><action application="set" data="foo=bar"/><action application="bridge" data="user/2000"/></condition></extension> This example is almost identical to the previous example, but instead of just placing the call, we first set the variable foo equal to the value bar. This variable will remain set throughout the call and can even be referenced at the end of the call in the detail logs. The more we build things in small pieces, the more the same underlying resources can be reused, making the system simpler to use. For example, the codec interface knows nothing else about the core, other than its own isolated world of encoding and decoding audio packets. Once a proper codec module has been written, it becomes usable by any Endpoint interface capable of carrying that codec in its audio stream. This means that if we get a Text-To-Speech module working, we can generate synthesized speech on any and all Endpoints that FreeSWITCH supports. It does not matter which one comes first as they have nothing to do with each other. However, the addition of either one instantly adds functionality to the other. The TTS module becomes more useful because it can use more codecs; the codecs have become more useful because we added a new function that can take advantage of them. The same idea applies to applications. If we write a new application module, the existing endpoints will immediately be able to run and use that application.
Read more
  • 0
  • 0
  • 18983

article-image-so-what-play
Packt
14 Jun 2013
11 min read
Save for later

So, what is Play?

Packt
14 Jun 2013
11 min read
(For more resources related to this topic, see here.) Quick start – Creating your first Play application Now that we have a working Play installation in place, we will see how easy it is to create and run a new application with just a few keystrokes. Besides walking through the structure of our Play application, we will also look at what we can do with the command-line interface of Play and how fast modifications of our application are made visible. Finally, we will take a look at the setup of integrated development environments ( IDEs ). Step 1 – Creating a new Play application So, let's create our first Play application. In fact, we create two applications, because Play comes with the APIs for Java and Scala, the sample accompanying us in this book is implemented twice, each in one separate language. Please note that it is generally possible to use both languages in one project. Following the DRY principle, we will show code only once if it is the same for the Java and the Scala application. In such cases we will use the play-starter-scala project. First, we create the Java application. Open a command line and change to a directory where you want to place the project contents. Run the play script with the new command followed by the application name (which is used as the directory name for our project): $ play new play-starter-java We are asked to provide two additional information: The application name, for display purposes. Just press the Enter key here to use the same name we passed to the play script. You can change the name later by editing the appName variable in play-starter-java/project/Build.scala. The template we want to use for the application. Here we choose 2 for Java. Repeat these steps for our Scala application, but now choose 1 for the Scala template. Please note the difference in the application name: $ play new play-starter-scala The following screenshot shows the output of the play new command: On our way through the next sections, we will build an ongoing example step-by-step. We will see Java and Scala code side-by-side, so create both projects if you want to find out more about the difference between Java and Scala based Play applications. Structure of a Play application Physically, a Play application consists of a series of folders containing source code, configuration files, and web page resources. The play new command creates the standardized directory structure for these files: /path/to/play-starter-scala└app source code| └controllers http request processors| └views templates for html files└conf configuration files└project sbt project definition└public folder containing static assets| └images images| └javascripts javascript files| └stylesheets css style sheets└test source code of test cases During development, Play generates several other directories, which can be ignored, especially when using a version control system: /path/to/play-starter-scala└dist releases in .zip format└logs log files└project THIS FOLDER IS NEEDED| └project but this...| └target ...and this can be ignored└target generated sources and binaries There are more folders that can be found in a Play application depending on the IDE we use. In particular, a Play project has optional folders on more involved topics we do not discuss in this book. Please refer to the Play documentation for more details. The app/ folder The app/ folder contains the source code of our application. According to the MVC architectural pattern, we have three separate components in the form of the following directories: app/models/: This directory is not generated by default, but it is very likely present in a Play application. It contains the business logic of the application, for example, querying or calculating data. app/views/: In this directory we find the view templates. Play's view templates are basically HTML files with dynamic parts. app/controllers/: This controllers contain the application specific logic, for example, processing HTTP requests and error handling. The default directory (or package) names, models, views, and controllers, can be changed if needed. The conf/ directory The conf/ directory is the place where the application's configuration files are placed. There are two main configuration files: application.conf: This file contains standard configuration parameters routes – This file defines the HTTP interface of the application The application.conf file is the best place to add more configuration options if needed for our application. Configuration files for third-party libraries should also be put in the conf/ directory or an appropriate sub-directory of conf/. The project/ folder Play builds applications with the Simple Build Tool ( SBT ). The project/ folder contains the SBT build definitions: Build.scala: This is the application's build script executed by SBT build.properties: This definition contains properties such as the SBT version plugins.sbt: This definition contains the SBT plugins used by the project The public/ folder Static web resources are placed in the public/ folder. Play offers standard sub-directories for images, CSS stylesheets, and JavaScript files. Use these directories to keep your Play applications consistent. Create additional sub-directories of public/ for third-party libraries for a clear resource management and to avoid file name clashes. The test/ folder Finally, the test/ folder contains unit tests or functional tests. This code is not distributed with a release of our application. Step 2 – Using the Play console Play provides a command-line interface (CLI), the so-called Play console. It is based on the SBT and provides several commands to manage our application's development cycle. Starting our application To enter the Play console, open a shell, change to the root directory of one of our Play projects, and run the play script. $ cd /path/to/play-starter-scala$ play On the Play console, type run to run our application in development (DEV) mode. [play-starter-scala] $ run Use ~run instead of run to enable automatic compilation of file changes. This gives us an additional performance boost when accessing our application during development and it is recommended by the author. All console commands can be called directly on the command line by running play <command>. Multiple arguments have to be denoted in quotation marks, for example, play "~run 9001" A web server is started by Play, which will listen for HTTP requests on localhost:9000 by default. Now open a web browser and go to this location. The page displayed by the web browser is the default implementation of a new Play application. To return to our shell, type the keys Ctrl + D to stop the web server and get back to the Play console. Play console commands Besides run , we typically use the following console commands during development: clean: This command deletes cached files, generated sources, and compiled classes compile: This command compiles the current application test: This command executes unit tests and functional tests We get a list of available commands by typing help play in the Play development console. A release of an application is started with the start command in production (PROD) mode. In contrast to the DEV mode no internal state is displayed in the case of an error. There are also commands of the play script, available only on the command line: clean-all: This command deletes all generated directories, including the logs. debug: This command runs the Play console in debug mode, listening on the JPDA port 9999. Setting the environment variable JDPA_PORT changes the port. stop: This command stops an application that is running in production mode. Closing the console We exit the Play console and get back to the command line with the exit command or by simply typing the key Ctrl + D . Step 3 – Modifying our application We now come to the part that we love the most as impatient developers: the rapid development turnaround cycles. In the following sections, we will make some changes to the given code of our new application visible. Fast turnaround – change your code and hit reload! First we have to ensure that our applications are running. In the root of each of our Java and Scala projects, we start the Play console. We start our Play applications in parallel on two different ports to compare them side-by-side with the commands ~run and ~run 9001. We go to the browser and load both locations, localhost:9000 and I Then we open the default controller app/controllers/Application.java and app/controllers/Application.scala respectively, which we created at application creation, in a text editor of our choice, and change the message to be displayed in the Java code: public class Application extends Controller {public static Result index() {return ok(index.render("Look ma! No restart!"));}} and then in the Scala code: object Application extends Controller {def index = Action {Ok(views.html.index("Look ma! No restart!"))}} Finally, we reload our web pages and immediately see the changes: That's it. We don't have to restart our server or re-deploy our application. The code changes take effect by simply reloading the page. Step 4 – Setting up your preferred IDE Play takes care of automatically compiling modifications we make to our source code. That is why we don't need a full-blown IDE to develop Play applications. We can use a simple text editor instead. However, using an IDE has many advantages, such as code completion, refactoring assistance, and debugging capabilities. Also it is very easy to navigate through the code. Therefore, Play has built-in project generation support for two of the most popular IDEs: IntelliJ IDEA and Eclipse . IntelliJ IDEA The free edition, IntelliJ IDEA Community , can be used to develop Play projects. However, the commercial release, IntelliJ IDEA Ultimate , includes Play 2.0 support for Java and Scala. Currently, it offers the most sophisticated features compared to other IDEs.More information can be found here: http://www.jetbrains.com/idea and also here: http://confluence.jetbrains.com/display/IntelliJIDEA/Play+Framework+2.0 We generate the required IntelliJ IDEA project files by typing the idea command on the Play console or by running it on the command line: $ play idea We can also download the available source JAR files by running idea with-source=true on the console or on the command line: $ play "idea with-source=true" After that, the project can be imported into IntelliJ IDEA. Make sure you have the IDE plugins Scala, SBT , and Play 2 (if available) installed. The project files have to be regenerated by running play idea every time the classpath changes, for example, when adding or changing project dependencies. IntelliJ IDEA will recognize the changes and reloads the project automatically. The generated files should not be checked into a version control system, as they are specific to the current environment. Eclipse Eclipse is also supported by Play. The Eclipse Classic edition is fine, which can be downloaded here: http://www.eclipse.org/downloads. It is recommended to install the Scala IDE plugin, which comes up with great features for Scala developers and can be downloaded here: http://scala-ide.org. You need to download Version 2.1.0 (milestone) or higher to get Scala 2.10 support for Play 2.1. A Play 2 plugin exists also for Eclipse, but it is in a very early stage. It will be available in a future release of the Scala IDE. More information can be found here: https://github.com/scala-ide/scala-ide-play2/wiki The best way to edit Play templates with Eclipse currently is by associating HTML files with the Scala Script Editor. You get this editor by installing the Scala Worksheet plugin, which is bundled with the Scala IDE. We generate the required Eclipse project files by typing the eclipse command on the Play console or by running it on the command line: $ play eclipse Analogous to the previous code, we can also download available source JAR files by running eclipse with-source=true on the console or on the command line: $ play "eclipse with-source=true" Also, don't check in generated project files for a version control system or regenerate project files if dependencies change. Eclipse (Juno) is recognizing the changed project files automatically. Other IDEs Other IDEs are not supported by Play out of the box. There are a couple of plugins, which can be configured manually. For more information on this topic, please consult the Play documentation. Summary We saw how easy it is to create and run a new application with just a few keystrokes. Besides walking through the structure of our Play application, we also looked at what we can do with the command-line interface of Play and how fast modifications of our application are made visible. Finally, we looked at the setup of integrated development environments ( IDEs ). Resources for Article : Further resources on this subject: Play! Framework 2 – Dealing with Content [Article] Play Framework: Data Validation Using Controllers [Article] Play Framework: Binding and Validating Objects and Rendering JSON Output [Article]
Read more
  • 0
  • 0
  • 2304
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 $19.99/month. Cancel anytime
article-image-creating-pop-menu
Packt
14 Jun 2013
7 min read
Save for later

Creating a pop-up menu

Packt
14 Jun 2013
7 min read
(For more resources related to this topic, see here.) How to do it... Open the application model (Application.e4xmi) and go to Application | Windows | Trimmed Window | Controls | Perspective Stack | Perspective | Controls | PartSashContainer | Part ( Code Snippets). Expand the Code Snippet part and right-click on the Menus node. Select Add child | Popup Menu. Set the ID of the pop-up menu to codesnippetapp.snippetlist.popupmenu. Right-click on the newly added pop-up menu and select Add Child | DirectMenuItem. Set Label of the menu item as New Snippet. Click on Class URI link. This opens the New Handler wizard. Click on the Browse button next to the Package textbox and select codesnippetapp.handlers from the list of packages displayed. Set Name as NewSnippetMenuHandler and click on the Finish button. The new class file is opened in the editor. Go back to the application model. Refer to the following screenshot: Right-click on the Popup Menu node and add another pop-up menu item with the Delete label and the DeleteSnippetMenuHandler class. Now we need to register this pop-up menu with the TableViewer class in the Code Snippets part. Open the class SnippetListView (you can find this class in the codesnippetapp.views package). We will have to register the pop-up menu using Menu Service. Add the EMenuService argument to the postConstruct method: @PostConstruct public void postConstruct(Composite parent, IEclipseContext ctx, EMenuService menuService) Append the following code to the postConstruct method: menuService.registerContextMenu(snippetsList.getTable(), "codesnippetapp.snippetlist.popupmenu"); Run the application. Right-click in the TableViewer class on the left-hand side. You should see a pop-up menu with two options: New Snippet and Delete. How it works... To add a pop-up menu, you first need to create a menu in the application model for a part in which you want to display the menu. In this recipe, we added a menu to the Code Snippets part. Then, you add menu items. In this recipe, we added two DirectMenuItem. For the main menu bar in the task of adding menu and toolbar buttons, we added HandledMenuItem, because we wanted to share the handler for the menu between toolbar button and menu item. However, in this case, we need only one implementation of options in the pop-up menu, so we created DirectMenuItem. But, if you want to add keyboard shortcuts for the menu options, then you may want to create HandledMenuItem instead of DirectMenuItem. For each menu item, you set a class URI that is a handler class for the menu item. The next step is to register this pop-up menu with a UI control. In our application, we want to associate this menu with the TableViewer class that displays a list of snippets. To register a menu with any UI control, you need to get an instance of EMenuService. We obtained this instance in the postConstruct method of SnippetListView using DI—we added the EMenuService argument to the postConstruct method. Then, we used registerContextMenu of EMenuService to associate the pop-up menu with the TableViewer class. registerContextMenu takes instances of the UI control and menu ID as arguments. There's more... The Delete option in our pop-up menu makes sense only when you click on any snippet. So, when you right-click on an area of TreeViewer that does not have any snippet at that location, the Delete option should not be displayed, only the New Snippet option. This can be done using core expressions. You can find more information about core expressions at http://wiki.eclipse.org/Platform_Expression_Framework, and http://wiki.eclipse.org/Command_Core_Expressions. We will use a core expression to decide if the Delete menu option should be displayed. We will add a mouse listener to the TableViewer class. If the mouse was clicked on a Snippet, then we will add SnippetData to IEclipseContext with the snippet_at_mouse_click key. If there is no snippet at the location, then we will remove this key from IEclipseContext. Then, we will add a core expression to check if the snippet_at_mouse_click variable is of type codesnippetapp.data.SnippetData. We will then associate this core expression with the Delete menu item in the application model. Adding mouse listener to the TableViewer class Create a static field in the SnippetListView class. private static String SNIPPET_AT_MOUSE_CLICK = "snippet_at_mouse_ click"; Make the ctx argument of the postConstruct method, final. Append the following code in the postConstruct method: //Add mouse listener to check if there is a snippet at mouse click snippetsList.getTable().addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { if (e.button == 1) //Ignore if left mouse button return; //Get snippet at the location of mouse click TableItem itemAtClick = snippetsList.getTable(). getItem(new Point(e.x, e.y)); if (itemAtClick != null) { //Add selected snippet to the context ctx.set(SNIPPET_AT_MOUSE_CLICK, itemAtClick.getData()); } else { //No snippet at the mouse click. Remove the variable ctx.remove(SNIPPET_AT_MOUSE_CLICK); } } }); Creating core expression Carry out to the following steps: Open plugin.xml and go to the Dependencies tab. Add org.eclipse.core.expression as a required plugin. Go to the Extensions tab. Add the org.eclipse.core.expressions. definitions extension. This will add a new definition. Change the ID of the definition to CodeSnippetApp.delete.snippet.expression. Right-click on the definition and select New |With. Change the name of the variable to snippet_at_mouse_click. This is the same variable name we set in the SnippetListView class. Right-click on the With node, and select New | instanceof option. Set the value to codesnippetapp.data.SnippetData. This core expression will be true when the type of (instanceof) the snippet_at_mouse_click variable is codesnippetapp.data.SnippetData. Click on plugin.xml and verify that the core expression definition is as follows: <extension point="org.eclipse.core.expressions.definitions"> <definition id="CodeSnippetApp.delete.snippet.expression"> <with variable="snippet_at_mouse_click"> <instanceof value="codesnippetapp.data.SnippetData"> </instanceof> </with> </definition> </extension> Setting the core expression for Menu Item Open the application model (Application.e4xmi) and go to DirectMenuItem for the Delete pop-up menu. Right-click on the menu item and select Add child | VisibleWhen Core Expression. This will add a Core Expression child node. Click on the Core Expression node and then on the Find button next to the Expression Id textbox and select CodeSnippetApp.delete.snippet. expression from the list. This is the ID of the core expression definition we added in plugin.xml. Run the application. When you right-click on the Snippets List view, which does not have any snippet at this point, you should see only the New Snippet menu option. Summary In this task, we created a pop-up menu that is displayed when you right-click in the snippets list. If no snippet is selected at a location where you right-click, then it displays a pop-up menu with a single option to add a snippet. If there is a snippet at the location, then we display a menu that has options to delete the snippet and add a snippet. Resources for Article : Further resources on this subject: Installing Alfresco Software Development Kit (SDK) [Article] JBoss AS plug-in and the Eclipse Web Tools Platform [Article] Deployment of Reports with BIRT [Article]
Read more
  • 0
  • 0
  • 3680

article-image-getting-started-leaflet
Packt
14 Jun 2013
9 min read
Save for later

Getting started with Leaflet

Packt
14 Jun 2013
9 min read
(For more resources related to this topic, see here.) Getting ready First, we need to get an Internet browser, if we don't have one already installed. Leaflet is tested with modern desktop browsers: Chrome, Firefox, Safari 5+, Opera 11.11+, and Internet Explorer 7-10. Internet Explorer 6 support is stated as not perfect but accessible. We can pick one of them, or all of them if we want to be thorough. Then, we need an editor. Editors come in many shapes and flavors: free or not free, with or without syntax highlighting, or remote file editing. A quick search on the Internet will provide thousands of capable editors. Notepad++ (http://notepad-plus-plus.org/) for Windows, Komodo Edit (http://www.activestate.com/komodo-edit) for Mac OS, or Vim (http://www.vim.org/) for Linux are among them. We can download Leaflet's latest stable release (v0.5.1 at the time of writing) and extract the content of the ZIP file somewhere appropriate. The ZIP file contains the sources as well as a prebuilt version of the library that can be found in the dist directory. Optionally, we can build from the sources included in the ZIP file; see this article's Building Leaflet from source section. Finally, let's create a new project directory on our hard drive and copy the dist folder from the extracted Leaflet package to it, ensuring we rename it to leaflet. How to do it... Note that the following code will constitute our code base throughout the rest of the article. Create a blank HTML file called index.html in the root of our project directory. Add the code given here and use the browser installed previously to execute it: <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="leaflet/ leaflet.css" /> <!--[if lte IE 8]> <link rel="stylesheet" type="text/css" href=" leaflet/ leaflet.ie.css" /> <![endif]--> <script src = "leaflet/leaflet.js"></script> <style> html, body, #map { height: 100%; } body { padding: 0; margin: 0; } </style> <title>Getting Started with Leaflet</title> </head> <body> <div id="map"></div> <script type="text/javascript"> var map = L.map('map', { center: [52.48626, -1.89042], zoom: 14 }); L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/ {x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); </script> </body> </html> The following screenshot is of the first map we have created: How it works... The index.html file we created is a standardized file that all Internet browsers can read and display the contents. Our file is based on the HTML doctype standard produced by the World Wide Web Consortium (W3C), which is only one of many that can be used as seen at http://www.w3.org/QA/2002/04/valid-dtd-list.html. Our index file specifies the doctype on the first line of code as required by the W3C, using the <!DOCTYPE HTML> markup. We added a link to Leaflet's main CSS file in the head section of our code: <link rel="stylesheet" type="text/css" href="leaflet/leaflet.css" /> We also added a conditional statement to link an Internet Explorer 8 or lower only stylesheet when these browsers interpret the HTML code: <!--[if lte IE 8]> <link rel="stylesheet" type="text/css" href="leaflet/leaflet.ie.css" /> <![endif]--> This stylesheet mainly addresses Internet Explorer specific issues with borders and margins. Leaflet's JavaScript file is then referred to using a script tag: <script src = "leaflet/leaflet.js"></script> We are using the compressed JavaScript file that is appropriate for production but very inefficient for debugging. In the compressed version, every white space character has been removed, as shown in the following bullet list, which is a straight copy-paste from the source of both files for the function onMouseClick: compressed: _onMouseClick:function(t){!this._loaded||this.dragging&& this.dragging.moved()||(this.fire("preclick"),this._ fireMouseEvent(t))}, uncompressed: _onMouseClick: function (e) { if (!this._loaded || (this.dragging && this.dragging.moved())) { return; } this.fire('preclick'); this._fireMouseEvent(e); }, To make things easier, we can replace leaflet.js with leaflet-src.js—an uncompressed version of the library. We also added styles to our document to make the map fit nicely in our browser window: html, body, #map { height: 100%; } body { padding: 0; margin: 0; } The <div> tag with the id attribute map in the document's body is the container of our map. It must be given a height otherwise the map won't be displayed: <div id="map" style="height: 100%;" ></div> Finally, we added a script section enclosing the map's initialization code, instantiating a Map object using the L.map(…) constructor and a TileLayer object using the L.tileLayer(…) constructor. The script section must be placed after the map container declaration otherwise Leaflet will be referencing an element that does not yet exist when the page loads. When instantiating a Map object, we pass the id of the container of our map and an array of Map options: var map = L.map('map', { center: [52.48626, -1.89042], zoom: 14 }); There are a number of Map options affecting the state, the interactions, the navigation, and the controls of the map. See the documentation to explore those in detail at http://leafletjs.com/reference.html#map-options. Next, we instantiated a TileLayer object using the L.tileLayer(…) constructor and added to the map using the TileLayer.addTo(…) method: L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); Here, the first parameter is the URL template of our tile provider—that is OpenStreetMap— and the second a noncompulsory array of TileLayer options including the recommended attribution text for our map tile's source. The TileLayer options are also numerous. Refer to the documentation for the exhaustive list at http://leafletjs.com/reference.html#tilelayer-options. There's more... Let's have a look at some of the Map options, as well as how to build Leaflet from source or use different tile providers. More on Map options We have encountered a few Map options in the code for this recipe, namely center and zoom. We could have instantiated our OpenStreetMap TileLayer object before our Map object and passed it as a Map option using the layers option. We also could have specified a minimum and maximum zoom or bounds to our map, using minZoom and maxZoom (integers) and maxBounds, respectively. The latter must be an instance of LatLngBounds: var bounds = L.latLngBounds([ L.latLng([52.312, -2.186]), L.latLng([52.663, -1.594]) ]); We also came across the TileLayer URL template that will be used to fetch the tile images, replacing { s} by a subdomain and { x}, {y}, and {z} by the tiles coordinate and zoom. The subdomains can be configured by setting the subdomains property of a TileLayer object instance. Finally, the attribution property was set to display the owner of the copyright of the data and/or a description. Building Leaflet from source A Leaflet release comes with the source code that we can build using Node.js. This will be a necessity if we want to fix annoying bugs or add awesome new features. The source code itself can be found in the src directory of the extracted release ZIP file. Feel free to explore and look at how things get done within a Leaflet. First things first, go to http://nodejs.org and get the install file for your platform. It will install Node.js along with npm, a command line utility that will download and install Node Packaged Modules and resolve their dependencies for us. Following is the list of modules we are going to install: Jake: A JavaScript build program similar to make JSHint: It will detect potential problems and errors in JavaScript code UglifyJS: A mangler and compressor library for JavaScript Hopefully, we won't need to delve into the specifics of these tools to build Leaflet from source. So let's open a command line interpreter— cmd.exe on Windows, or a terminal on Mac OSX or Linux—and navigate to the Leaflet's src directory using the cd command, then use npm to install Jake, JSHint and UglifyJS: cd leaflet/src npm install –g jake npm install jshint npm install uglify-js We can now run Jake in Leaflet's directory: jake What about tile providers? We could have chosen a different tile provider as OpenStreetMap is free of charge but has its limitations in regard of a production environment. A number of web services provide tiles but might come at a price depending on your usage: CloudMade, MapQuest. These three providers serve tiles use the OpenStreetMap tile scheme described at http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames. Remember the way we added the OpenStreetMap layer to the map? L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); Remember the way we added the OpenStreetMap layer to the map? Cloudmade: L.tileLayer(' http://{s}.tile.cloudmade.com/API-key/997/256/{z}/ {x}/{y}.png', { attribution: ' Map data © <a href="http://openstreetmap. org">OpenStreetMap</a> contributors, <a href="http:// creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>' }).addTo(map); MapQuest: L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}. png', { attribution: ' Tiles Courtesy of <a href="http://www.mapquest. com/" target="_blank">MapQuest</a> <img src = "http://developer.mapquest.com/content/osm/mq_logo.png">', subdomains: ['otile1', 'otile2', 'otile3', 'otile4'] }).addTo(map); You will learn more about the Layer URL template and subdomains option in the documentation at http://leafletjs.com/reference.html#tilelayer. Leaflet also supports Web Map Service (WMS) tile layers—read more about it at http://leafletjs.com/reference.html#tilelayer-wms—and GeoJSON layers in the documentation at http://leafletjs.com/reference.html#geojson. Summary In this article we have learned how to create map using Leaflet and created our first map. We learned about different map options and also how to build a leaflet from source. Resources for Article : Further resources on this subject: Using JavaScript Effects with Joomla! [Article] Getting Started with OpenStreetMap [Article] Quick start [Article]
Read more
  • 0
  • 0
  • 4041

article-image-using-storyboards
Packt
14 Jun 2013
7 min read
Save for later

Using Storyboards

Packt
14 Jun 2013
7 min read
(For more resources related to this topic, see here.) Configuring storyboards for a project Getting ready In this recipe, we will learn how to configure an application's project properties using Xcode so that it is set up correctly to use a storyboard file. How to do it... To begin, perform the following simple steps: Select your project from the project navigator window. Then, select your project target from under the TARGETS group and select the Summary tab. Select MainStoryboard from the Main Storyboard drop-down menu, as shown in the preceding screenshot. How it works... In this recipe, we gained an understanding of what storyboards are, as well as how they differ from user interfaces created in the past, whereby a new view would need to be created for each XIB file for your application. Whether you are creating applications for the iPad or iPhone, each view controller that gets created within your storyboard represents the contents of a single screen, comprised of the contents of more than one scene. Each object contained within a view controller can be linked to another view controller that implements another scene. In our final steps, we looked at how to configure our project properties so that it is set up to use the storyboard user interface file by our application. There's more… You can also choose to manually add new Storyboard template to your project. This can be achieved by performing the following simple steps: Select your project from the project navigator window. Select File New | File…| or press command + N. Select the Storyboard template from the list of available templates, located under the User Interface subsection within the iOS section. Click on the Next button to proceed to the next step in the wizard. Ensure that you have selected iPhone from under the Device Family drop-down menu. Click on the Next button to proceed to the next step in the wizard. Specify the name of the storyboard file within the Save As field as the name of the file to be created. Click on the Create button to save the file to the specified folder. Finally, when we create our project using storyboards, we will need to modify our application's delegate AppDelegate.m file, as shown in the following code snippet: - (BOOL)application:(UIApplication *)application didFinishLaunchin gWithOptions:(NSDictionary *)launchOptions { // Override point for customization after // application launch. return YES; } For more information about using storyboards in your applications, you can refer to the Apple Developer documentation, located at https://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/Xcode4UserGuide/InterfaceBuilder/InterfaceBuilder. Creating a Twitter application In this recipe, we will learn how to create a single view application to build our Twitter application. Getting ready In this recipe, we will start by creating our TwitterExample project. How to do it... To begin with creating a new Xcode project, perform the following simple steps: Launch Xcode from the /Developer/Applications folder. Select Create a new Xcode project, or click on File | New | Project…. Select Single View Application from the list of available templates. Click on the Next button to proceed to the next step in the wizard. Next, enter in TwitterExample as the name of your project. Select iPhone from under the Devices drop-down menu. Ensure that the Use Storyboards checkbox has been checked. Ensure that the Use Automatic Reference Counting checkbox has been checked. Ensure that the Include Unit Tests checkbox has not been checked. Click on the Next button to proceed to the next step in the wizard. Specify the location where you would like to save your project. Then, click on the Create button to save your project at the specified location. The Company Identifier for your app needs to be unique. Apple recommends that you use the reverse domain style (for example, com.domainName.appName). Once your project has been created, you will be presented with the Xcode development environment, along with the project files that the template created for you. How it works... In this recipe, we just created an application that contains a storyboard and consists of one view controller, which does not provide any functionality at the moment. In the following recipes, we will look at how we can add functionality to view controllers, create storyboard scenes, and transition between them. Creating storyboard scenes The process of creating scenes involves adding a new view controller to the storyboard, where each view controller is responsible for managing a single scene. A better way to describe scenes would be to think of a movie reel, where each frame that is being displayed is the actual scene that connects onto the next part. Getting ready When adding scenes to your storyboard file, you can add controls and views to the view controller's view, just as you would do for an XIB file, and have the ability to configure outlets and actions between your view controllers and its views. How to do it... To add a new scene into your storyboard file, perform the following simple steps: From the project navigator, select the file named MainStoryboard.storyboard. From Object Library, select and drag a new View Controller object on to the storyboard canvas. This is shown in the following screenshot: Next, drag a Label control on to the view and change the label's text property to read About Twitter App. Next, drag a Round Rect Button control on to the view that we will use in a later section to call the calling view. In the button's attributes, change the text to read Go Back. Next, on the first view controller, drag a Round Rect Button control on to the view. In the button's attributes, change the text to read About Twitter App. This will be used to call the new view that we added in the previous step. Next, on the first view controller, drag a Round Rect Button control on to the view, underneath the About Twitter App button that we created in the previous step. In the button's attributes, change the text to read Compose Tweet. Next, save your project by selecting File | Save from the menu bar, or alternatively by pressing command + S. Once you have added the controls to each of the view, your final interface should look something like what is shown in the following screenshot: The next step is to create the Action event for our Compose Tweet button so that it has the ability to post tweets. To create an action, perform the following steps: Open the assistant editor by selecting Navigate | Open In Assistant Editor or by pressing option + command + ,. Ensure that the ViewController.h interface file gets displayed. Select the Compose Tweet button; hold down the control key, and drag it from the Compose Tweet button to the ViewController.h interface file between the @interface and @end tags. Choose Action from the Connection drop-down menu for the connection to be created. Enter composeTweet for the name of the method to create. Choose UIButton from the Type drop-down menu for the type of method to create. The highlighted line in the following code snippet shows the completed ViewController.h interface file, with our method that will be responsible for calling and displaying our tweet sheet. // ViewController.h // TwitterExample // // Created by Steven F Daniel on 21/09/12. // Copyright (c) 2012 GenieSoft Studios. All rights reserved. #import @interface ViewController : UIViewController // Create the action methods - (IBAction)composeTweet:(UIButton *)sender; @end Now that we have created our scene, buttons, and actions, our next step is to configure the scene, which is shown in the next recipe. How it works... In this recipe, we looked at how we can add a new view controller to our storyboard and then started to add controls to each of our view controllers and customize their properties. Next, we looked at how we can create an Action event for our Compose Tweet button that will be responsible for responding and executing the associated code behind it to display our tweet sheet. Instead of us hooking up an event handler to the TouchUpInside event of the button, we decided to simply add an action to it and handle the output of this ourselves. These types of actions are called "instance methods". Here we are basically creating the Action method that will be responsible for allowing the user to compose and send a Twitter message.
Read more
  • 0
  • 0
  • 10518

article-image-so-what-kineticjs
Packt
14 Jun 2013
3 min read
Save for later

So, what is KineticJS?

Packt
14 Jun 2013
3 min read
(For more resources related to this topic, see here.) With KineticJS you can draw shapes on the stage and manipulate them using the following elements: Move Rotate Animate Even if your application has thousands of figures, the animation will run smoothly and with a high enough FPS. The items are organized into layers, of which you can have as many as you want. Shapes can also be organized into groups. KineticJS allows unlimited nesting of shapes and groups. Scenes, layers, groups, and figures are virtual nodes, similar to DOM nodes in HTML. Any node can be styled or transformed. There are several predefined shapes, such as rectangles, circles, images, text, lines, polygons, stars, and so on. You can also create custom drawing functions in order to create custom shapes. For each object you can assign different event handlers (touch or mouse). You can also apply filter or animation to the shapes. Of course, you can implement all the necessary HTML5 Canvas functionality without KineticJS, but you have to spend a lot more time, and not necessarily get the same level of performance. The creators of KineticJS put all their love and faith into a brighter future of HTML5 interactivity. The main advantage of the library is high performance, which is achieved by creating two canvas renderers – a scene renderer and a hit graph renderer. One renderer is what you see, and the second is a special hidden canvas that's used for high-performance event detection. A huge advantage of KineticJS is that it is an extension to HTML5 Canvas, and thus is perfectly suited for developing applications for mobile platforms. High performance can hide all the flaws of the canvas in iOS, Android, and other platforms. It is a known fact that the iOS platform does not support Adobe Flash. In this case, KineticJS is a good Flash alternative for iOS devices. You can wrap up your KineticJS application with Cordova/PhoneGap and use it as an offline application, or publish to the App store. In short, the following are the main advantages of KineticJS: Speed Scalability Extensibility Flexibility Familiarity with API (for developers with the knowledge of HTML, CSS, JS, and jQuery) If you are an active innovator and indomitable web developer, this library is for you. Summary In this article, we walked through the basics and main advantages KineticJS. Resources for Article : Further resources on this subject: HTML5 Presentations - creating our initial presentation [Article] Removing Unnecessary jQuery Loads [Article] Using JavaScript Effects with Joomla! [Article]
Read more
  • 0
  • 0
  • 3915
article-image-customize-your-linkedin-profile-headline
Packt
13 Jun 2013
2 min read
Save for later

Customize your LinkedIn profile headline

Packt
13 Jun 2013
2 min read
(For more resources related to this topic, see here.) Every LinkedIn user can customize his/her profile headline. Your headline is the first thing that is read about you by other LinkedIn users, even before they get a chance to have a look at your detailed profile. Hence, this tool should be used wisely so that it can attract the right audience. The following screenshot shows what a profile headline looks like: How to do it... To set up your LinkedIn profile headline, perform the following steps: Click on the Edit Profile button from the LinkedIn toolbar located at the top of the page that appears after you log in. Click on the button located next to your current headline, and you will see a screen, as shown in the following screenshot: Input the professional headline for the target audience. How it works... You've now learned how to update your LinkedIn profile headline. The key point is to be as specific as you can and put the right keywords that are search engine friendly and eye catching. Let me state a few examples: Job seeker headline: 5 years of exp in Java and .NET; looking for opportunities in Hong Kong Service marketing headline: Helping fortune 500 companies increase revenues by designing better HR strategies Examples of a few other interesting headlines: Chief Operating Officer; building high performing sales teams that align with corporate vision Experienced sales professional looking to positively impact a new organization Retail technology solutions; developing high performing retail outlets Summary It is a good idea to refine and update your profile headline regularly, so that your profile is viewed by the right audience. Thus, we have learnt how to customize the LinkedIn profile headline. Resources for Article : Further resources on this subject: Managing the Discussion Forums Using PHP-Nuke [Article] Safely Manage Different Versions of Content with Plone [Article] Customizing Headers and Footers with MS Office Live Small Business [Article]
Read more
  • 0
  • 0
  • 13805

article-image-creating-your-own-theme
Packt
13 Jun 2013
5 min read
Save for later

Creating Your Own Theme

Packt
13 Jun 2013
5 min read
(For more resources related to this topic, see here.) Starting with a new layout Before we start creating a concrete5 theme we need a layout. In this article, we're going to use a simple layout without any pictures to keep the code as short as possible—it's about concrete5, not about HTML and CSS. If you don't have the time for an exercise, you can use your own layout. With good knowledge about the basic technologies of concrete5, you should be able to amend the instructions in this article to match your own layout. If you don't feel very comfortable working with PHP you should probably use the printed HTML code in this article. Here's a screenshot of what our site is going to look like once we've finished our theme: While this layout isn't very pretty, it has an easy structure; navigation on top and a big content area where we can insert any kind of block we want. In case you're using your own layout, try to use one with a simple structure; navigation on top or on the left with one big place for the content, and try to avoid Flash. The HTML code Let's have a look at the HTML code: <!DOCTYPE html><html lang="en"><head><title>concrete5 Theme</title><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><style type="text/css" media="screen">@import "main.css";</style></head><body><div id="wrapper"><div id="page"><div id="header_line_top"></div><div id="header"><ul class="nav-dropdown"><li><a href="#">Home</a></li><li><a href="#">Test</a></li><li><a href="#">About</a></li></ul></div><div id="header_line_bottom"></div><div id="content"><p>Paragraph 1</p><p>Paragraph 2</p><p>Paragraph 3</p></div><div id="footer_line_top"></div><div id="footer"></div><div id="footer_line_bottom"></div></div></div></body></html> There are three highlighted lines in the preceding code: The CSS import: This is to keep the layout instructions separated from the HTML elements; we've got all the CSS rules in a different file named main.css. This is also how almost all concrete5 themes are built. The header block contains the navigation. As we're going to apply some styles to it, make sure it has its own ID. Using an ID also improves the performance when using CSS and JavaScript to access an element, as an ID is unique. The same applies to the content block. Make sure it has a unique ID. Most web technologies we use nowadays are standardized in one way or another. Currently, the most important organization is W3C. They also offer tools to validate your code. Checking your code is never a bad idea. Navigate to http://validator.w3.org/ and enter the address of the website you want to check or in this case, as your website isn't accessible by the public, click on Validate by Direct Input and paste the HTML code to see if there are any mistakes. While it should be fairly easy to produce valid HTML code, things are a bit tricky with CSS. Due to some old browser bugs, you're often forced to use invalid CSS rules. There's often a way to rebuild the layout to avoid some invalid rules but often this isn't the case—you won't be doomed if something isn't 100 percent valid but you're on the safer side if it is. CSS rules As mentioned earlier, all CSS rules are placed in a file named main.css. Let's have a look at all CSS rules you have to put in our CSS file: /* global HTML tag rules */html, body, div, pre, form, fieldset, input, h1, h2, h3, h4, h5, h6,p, textarea, ul, ol, li, dl, dt, dd, blockquote, th, td {margin: 0;padding: 0;}p {margin: 5px 0px 15px 0px;}html {height: 100%;}body {background-color: #989898;height: 100%;}/* layout rules */#wrapper {margin: 0 auto;width: 980px;text-align: left;padding-top: 35px;}#page {background: #FFFFFF;float: left;width: 960px;padding: 5px;-moz-box-shadow: 0 0 15px black;-webkit-box-shadow: 0 0 15px black;box-shadow: 0 0 15pxblack;border-radius: 10px;}/* header */#header {background: #262626;border-radius: 10px 10px 0px 0px;height: 75px;}#header_line_top {background: #262626;height: 0px;}#header_line_bottom {background: #e64116;height: 3px;}/* content */#content {min-height: 300px;padding: 30px;color: #1E1E1E;font-family: verdana, helvetica, arial;font-size: 13px;line-height: 22px;}/* footer */#footer {background: #262626;height: 75px;border-radius: 0px 0px 10px 10px;}#footer_line_top {background: #e64116;height: 3px;}#footer_line_bottom {background: #262626;height: 0px;}/* header navigation */#header ul{margin: 0px;padding: 20px;}#header ul li {float: left;list-style-type: none;}#header ul li a {margin-right: 20px;display: block;padding: 6px 15px 6px 15px;color: #ccc;text-decoration: none;font-family: verdana, helvetica, arial;}#header ul li a:hover {color: white;}
Read more
  • 0
  • 0
  • 2015

article-image-top-features-youll-want-know-about
Packt
12 Jun 2013
10 min read
Save for later

Top features you'll want to know about

Packt
12 Jun 2013
10 min read
(For more resources related to this topic, see here.) 1 – Track changes and production revisions (for Adobe Story Plus only) It is important to keep track of any changes you or someone else may make to a document. It's easy to save over the previous version with the new one, but what if you want to compare the previous and current versions to one another? You are able to track any and all revisions through this feature. Called revision styles, all revisions become associated with a unique style for easier identification. Track changes Before moving to revisions, we need to be able to know how to insert and track changes made to a document. This is how it is done: When in the AUTHORING view, in the document, go to the Review tab in the top tool bar. Check Start Tracking Changes to enable it, and uncheck it to disable: When it is checked, any new content you add will be in red text and highlighted: There is a speech bubble on the right-hand side of the addition, which allows for the person making the change to add a comment. Click on the icon to open the comment window: When you place the cursor over the inserted change, a new bubble will appear telling you who made the change and when. On the far right-hand side, you can either accept or reject the change: Production revisions You have to be in the Authoring view in order to make a revision. Production revisions highlight certain pages where changes have been made. The script becomes locked and all changes are highlighted in the revision style you choose. On the title page, a note is inserted on the bottomright corner giving the date of the last revision. This is also done on the footer of every page where there is a change. The color changes and borders will not be exported in a PDF. Before starting a revision, make sure that you have done the following: Act on all tracked changes in your document by accepting or rejecting them. Disable track changes after completing accepting/rejecting tracked changes. Now, after completing the preceding steps, follow these steps: Select Production | Start Revision. In the Active Revision drop-down, choose a revision style: This style will be used for the markups in the revision. Make sure that you haven't already used the chosen style for a previous revision document. Click Start Revision. Creating a revision style Follow these steps to create your revision style: Select Production | Manage Revisions. Click on the + icon. Enter a name for the style The following options can be tailored according to your needs: Revision Color: Used to choose a color from the color menu. This color will then be applied to all the revised text and the border of the individual pages that contain the revisions. The border color will not be displayed in a printed or exported document. Mark: The default mark is displayed on the right of the revised content. You can change this mark by choosing any symbol of your liking. Date: The revision date. Revision Text Style: The chosen formatting option is used to display revised text. Click Done and your new style will be available from now on. Deleting or modifying existing revisions Let's take a look at how we can delete or modify already existing revisions: Select the style that you want to delete or modify. You can do either of the following: Click on the - sign to delete the style To modify, simply edit its values and click Done Display options for revisions Adobe Story also provides some display options for revisions, here's how we can set them up: Select Production | Manage Revisions. In Viewing Options, the following display options can be personalized according to your needs: Show Markup For: The options are Select All or Active. This will let you choose whether you want to have all the markups shown for all revisions or just the active ones. Mark Position: The mark you set in Revision Style is set to the right-hand side by default; you can also change its position. Show Date In Script Header and Footer: If you do not want to display the date, disable this option. Locking or unlocking scene numbers When you lock scene numbers, you prevent the renumbering of existing scenes whenever a new scene is added during production revisions. When you do insert a new scene, Adobe Story will apply a number to the scene preceding it. For example, if you add a new scene in between scene 4 and 5, it will be numbered 4A. Here's how we can lock and unlock scene numbers: Select Production | Manage Scene Numbers. Select the Keep Existing Scene Number option to lock all current scenes. To unlock, deselect Keep Existing Scene Number. Omitting or unomitting scenes Adobe Story allows you to remove a scene without affecting the scene numbers remaining in the script. The word OMITTED will appear at the location of the scene you've chosen to omit. You can, at a later date, unomit the scene if you chose and recover the content. To omit a scene, simply place your cursor on the scene and then select Production | Omit Scene. To unomit a scene, place your cursor on the omitted scene and then select Production | Unomit Scene. Printing production revisions If you want to print your revisions, it is easy to do so; just follow these steps: Select File | Print. Choose any one of the following option: Entire Script All ChangedPages Revision To print in color, select the Print Revised Text In Color option. Identifying the total number of revised pages Here's how we can identify the total number of revised pages: Select Production | Manage Revisions. In Viewing Options, select All and click Done. 2 – Tagging Along with the advent of the "cloud" concept, tagging individual words to content has become something of a norm in today's online society. Adobe Story has incorporated a similar system. With tagging, you can tag words and phrases in your scripts automatically, or manually by using the Tagging Panel option. For example, "boom" can be tagged as "sound effect". Tagging panel To open the panel, you must be first in the AUTHORING view. Select View | Tagging Panel. The panel will open on the right-hand side of the document. To add tags to the panel, enter the name of the tag in the field next to the Create button: To delete a tag from the tagging panel, select the tag and then click on the Delete this Tag link: Tagging automatically You must be in the online mode for the Autotagging feature to work. It will not work in the offline mode. The Autotagging feature is only available for English scripts. This is how it's done: Select File | Tagging | Start Autotagging. Or select it from the drop-down menu option in the Tagging panel: Once you enable Autotagging, the script will be locked. You will have to wait until the process has completed before being able to edit the document; the following screenshot shows the message being displayed: Tagging manually Select View | Tagging Panel. Choose the word or phrase you would like to tag. If what you're choosing has already been tagged, it will be appended to the tag list for the word or phrase. Select a tag from Taglist in the Tagging panel. Do either of the following: Select the Show In Bold option if you want the tagged words or phrases to be displayed in bold. Select the Show Color option if you would prefer Story to display the selected color (you can choose a color for each tag with a color palette on the righthand of the tag in the Taglist panel) to the tag: Finding words or phrases by their specific tag Follow these steps to search for words or phrases with a specific tag: Disable visibility for all tags. Enable visibility for the tag that you want to search. To do this, simply click on the eye icon on the left-hand side of the tagged word: Use the arrow icons in the Tagging panel in order to navigate through the tags in the script. Only the visible tags will be shown. Viewing tags associated with a word or phrase To view tags associated with a word or a phrase, you can do either of the following: Select the word/phrase. The tags associated with the word/phrase will be highlighted in the Tagging panel. Scroll through the panel in order to view the tags associated with it: Move your mouse over the word/phrase. The information will be displayed in the tool tip: Hold Ctrl (Cmd on Mac) and double-click to view the associated tags: Removing tags Over the word you wish to edit, hold Ctrl (Cmd on Mac) and double-click to bring up the Applied Tags panel. Click on the Remove This Tag icon for the chosen tag. Click Close. To remove all the tags, select File | Tagging | Remove All Tags. To remove all the manual tags, select File | Tagging | Remove All Manual Tags. To remove all the auto tags, select File | Tagging | Remove Auto Tags. 3 – Application for iOS-based devices Adobe Story has an application for iOS-based devices. This application is available currently only in English. It allows you to read and review Adobe Story scripts and documents. It does not support AV (Audio Visual) scripts, Multicolumn scripts, and TV scripts as of yet. Logging in Before you start, make sure you have registered yourself with Adobe Story using the web or desktop application. Use the same combination of e-mail address and password used on the full application with the iOS version. Accept the TOU before attempting to log in. If you want to log out, select Account and then select Log Out. Viewing documents, scene outline, and scenes The ten most recently read files will be displayed upon logging in to the Adobe Story application. To view all the documents, click Categories. To view the scene outline, select the script in the Recent Files or Categories view. To view the contents of a scene, select the scene in the scene outline. Use the arrow icons to move among the scenes. To view Notifications, in the Recent Files view, select Notifications. A list of notifications is displayed. Highlighted notifications are for new ones. Reviewing scripts As long as you have author, co-author, or reviewer permissions, you will be able to review a script. Open the script and navigate to the scene. Do one of the following: Double-click to select the content that you want to comment on. Click on Comment, or on the Add Comment button. To comment on the content that has already been commented on, enter your comment in the Write New Comment textbox. To navigate comments, use the arrow icons. Click Post. Viewing or deleting comments In the scene containing the comments, select Comments. The comment list is displayed. The paragraph containing the comment is highlighted when you select on a comment in the list. Select Delete after clicking on the desired comment. Summary In this article we learned about three of Adobe Story's key features. We learned about track changes and production revisions. we learned about tagging, and learned about more about Adobe Story in iOS devices. There is a whole lot more to learn as far as the features in Adobe Story is concerned. Resources for Article : Further resources on this subject: Integrating Scala, Groovy, and Flex Development with Apache Maven [Article] Exporting SAP BusinessObjects Dashboards into Different Environments [Article] An Introduction to Flash Builder 4-Network Monitor [Article]
Read more
  • 0
  • 0
  • 2245
Packt
12 Jun 2013
8 min read
Save for later

A quick start – OpenCV fundamentals

Packt
12 Jun 2013
8 min read
(For more resources related to this topic, see here.) The OpenCV library has a modular structure, and the following diagram depicts the different modules available in it: A brief description of all the modules is as follows: Module Feature Core A compact module defining basic data structures, including the dense multidimensional array Mat and basic functions used by all other modules. Imgproc An image processing module that includes linear and non-linear image filtering, geometrical image transformations (resize, affine and perspective warping, generic table-based remapping), color space conversion, histograms, and so on. Video A video analysis module that includes motion estimation, background subtraction, and object tracking algorithms. Calib3d Basic multiple-view geometry algorithms, single and stereo camera calibration, object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction. Features2d Salient feature detectors, descriptors, and descriptor matchers. Objdetect Detection of objects and instances of the predefined classes; for example, faces, eyes, mugs, people, cars, and so on. Highgui An easy-to-use interface to video capturing, image and video codecs, as well as simple UI capabilities. Gpu GPU-accelerated algorithms from different OpenCV modules. Task 1 – image basics When trying to recreate the physical world around us in digital format via a camera, for example, the computer just sees the image in the form of a code that just contains the numbers 1 and 0. A digital image is nothing but a collection of pixels (picture elements) which are then stored in matrices in OpenCV for further manipulation. In the matrices, each element contains information about a particular pixel in the image. The pixel value decides how bright or what color that pixel should be. Based on this, we can classify images as: Greyscale Color/RGB Greyscale Here the pixel value can range from 0 to 255 and hence we can see the various shades of gray as shown in the following diagram. Here, 0 represents black and 255 represents white: A special case of grayscale is the binary image or black and white image. Here every pixel is either black or white, as shown in the following diagram: Color/RGB Red, Blue, and Green are the primary colors and upon mixing them in various different proportions, we can get new colors. A pixel in a color image has three separate channels— one each for Red, Blue, and Green. The value ranges from 0 to 255 for each channel, as shown in the following diagram: Task 2 – reading and displaying an image We are now going to write a very simple and basic program using the OpenCV library to read and display an image. This will help you understand the basics. Code A simple program to read and display an image is as follows: // opencv header files #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" // namespaces declaration using namespace cv; using namespace std; // create a variable to store the image Mat image; int main( int argc, char** argv ) { // open the image and store it in the 'image' variable // Replace the path with where you have downloaded the image image=imread("<path to image">/lena.jpg"); // create a window to display the image namedWindow( "Display window", CV_WINDOW_AUTOSIZE ); // display the image in the window created imshow( "Display window", image ); // wait for a keystroke waitKey(0); return 0; } Code explanation Now let us understand how the code works. Short comments have also been included in the code itself to increase the readability. #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" The preceding two header files will be a part of almost every program we write using the OpenCV library. As explained earlier, the highgui header is used for window creation, management, and so on, while the core header is used to access the Mat data structure in OpenCV. using namespace cv; using namespace std; The preceding two lines declare the required namespaces for this code so that we don't have to use the :: (scope resolution) operator every time for accessing the functions. Mat image; With the above command, we have just created a variable image of the datatype Mat that is frequently used in OpenCV to store images. image=imread("<path to image">/lena.jpg"); In the previous command, we opened the image lena.jpg and stored it in the image variable. Replace <path to image> in the preceding command with the location of that picture on your PC. namedWindow( "Display window", CV_WINDOW_AUTOSIZE ); We now need a window to display our image. So, we use the above function to do the same. This function takes two parameters, out of which the first one is the name of the window. In our case, we would like to name our window Display Window. The second parameter is optional, but it resizes the window based on the size of the image so that the image is not cropped. imshow( "Display window", image ); Finally, we are ready to display our image in the window we just created by using the preceding function. This function takes two parameters out of which the first one is the window name in which the image has to be displayed. In our case, obviously, that will be Display Window . The second parameter is the image variable containing the image that we want to display. In our case, it's the image variable. waitKey(0); Last but not least, it is advised that you use the preceding function in most of the codes that you write using the OpenCV library. If we don't write this code, the image will be displayed for a fraction of a second and the program will be immediately terminated. It happens so fast that you will not be able to see the image. What this function does essentially is that it waits for a keystroke from the user and hence it delays the termination of the program. The delay here is in milliseconds. Output The image can be displayed as follows: Task 3 – resizing and saving an image We are now going to write a very simple and basic program using the OpenCV library to resize and save an image. Code The following code helps you to resize a given image: // opencv header files #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/core.hpp" // namespaces declaration using namespace std; using namespace cv; int main(int argc, char** argv) { // create variables to store the images Mat org, resized,saved; // open the image and store it in the 'org' variable // Replace the path with where you have downloaded the image org=imread("<path to image>/lena.png"); //Create a window to display the image namedWindow("Original Image",CV_WINDOW_AUTOSIZE); //display the image imshow("Original Image",org); //resize the image resize(org,resized,Size(),0.5,0.5,INTER_LINEAR); namedWindow("Resized Image",CV_WINDOW_AUTOSIZE); imshow("Resized Image",resized); //save the image //Replace <path> with your desired location imwrite("<path>/saved.png",resized; namedWindow("Image saved",CV_WINDOW_AUTOSIZE); saved=imread("<path to image>/saved.png"); imshow("Image saved",saved); //wait for a keystroke waitKey(0); return 0; } Code explanation Only the new functions/concepts will be explained in this case. #include "opencv2/imgproc/imgproc.hpp" Imgproc is another useful header that gives us access to the various transformations, color conversions, filters, histograms, and so on. Mat org, resized; We have now created two variables, org and resized, to store the original and resized images respectively. resize(org,resized,Size(),0.5,0.5,INTER_LINEAR); We have used the preceding function to resize the image. The preceding function takes six parameters, out of which the first one is the variable containing the source image to be modified. The second one is the variable to store the resized image. The third parameter is the output image size. In this case we have not specified this, but we have instead used the Size() function, which will automatically calculate it based on the values of the fourth and fifth parameters. The fourth and fifth parameters are the scale factors along the horizontal and vertical axes respectively. The sixth parameter is for choosing the type of interpolation method. We have used the bilinear interpolation, which is the default method. imwrite("<path>/saved.png",final); Finally, using the preceding function, you can save an image to a particular location on our PC. The function takes two parameters, out of which the first one is the location where you want to store the image and the second is the variable in which the image is stored. This function is very useful when you want to perform multiple operations on an image and save the image on your PC for future reference. Replace <path> in the preceding function with your desired location. Output Resizing can be demonstrated through the following output: Summary This section showed you how to perform a few of the basic tasks in OpenCV as well as how to write your first OpenCV program. Resources for Article : Further resources on this subject: OpenCV: Segmenting Images [Article] Tracking Faces with Haar Cascades [Article] OpenCV: Image Processing using Morphological Filters [Article]
Read more
  • 0
  • 0
  • 8544

article-image-building-multipage-forms-intermediate
Packt
11 Jun 2013
5 min read
Save for later

Building multipage forms (Intermediate)

Packt
11 Jun 2013
5 min read
(For more resources related to this topic, see here.) Getting ready We'll separate our existing user registration form already created to multipage forms. The sections will be for personal information, address details, and contact information. How to do it... All code related to the form is written in a file named _form under protected/views/user. We are dividing the input fields into three sections, so create three separate files in the same folder with the names _page1, _page2, and _page3. Separate the code's respective files. Some sample lines are as follows: <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'user-form', 'enableAjaxValidation'=>false, 'stateful'=>true, )); ?> <div class="row"> <?php echo $form->labelEx($model,'first_name'); ?> <?php echo $form->textField($model,'first_name', array( 'size'=>50, 'maxlength'=>50 )); ?> <?php echo $form->error($model,'first_name'); ?> </div> ..... ..... <div class="row buttons"> <?php echo CHtml::submitButton('Next', array( 'name'=>'page2' )); ?> </div> <?php $this->endWidget(); ?> .... <div class="row buttons"> <?php echo CHtml::submitButton('back', array( 'name'=>'page1' )); ?> <?php echo CHtml::submitButton('Next', array( 'name'=>'page3' )); ?> </div> <div class="row buttons"> <?php echo CHtml::submitButton('Back', array( 'name'=>'page2' )); ?> <?php echo CHtml::submitButton('submit', array( 'name'=>'submit' )); ?> </div> Now, in the User controller, change the code for actionCreate as follows: public function actionCreate() { if(isset($_POST['page1'])) { $model = new User('page1'); $this->checkPageState($model, $_POST['User']); $view = '_page1'; } elseif(isset($_POST['page2'])) { $model = new User('page1'); $this->checkPageState($model, $_POST['User']); if($model->validate()) { $view = '_page2'; $model->scenario = 'page2'; } else { $view = '_page1'; } } .... $this->render($view, array('model'=>$model)); } And add a function, checkPageState(), as follows: private function checkPageState(&$model, $data) { $model->attributes = $this->getPageState('page', array()); $model->attributes = $data; $this->setPageState('page', $model->attributes); } Lastly, create scenarios in the model User to validate each page of the form separately. Add three arrays specifying all the required fields per page, as follows: return array( array('first_name, last_name, gender, dob', 'required', 'on'=>'page1' ), array('address_1, city, state, country', 'required', 'on'=>'page2' ), array('phone_number_1, email_1', 'required', 'on'=>'page3' ), How it works... We have separated all our input fields into three forms. Each page contains an entire standalone form that accepts the input from the user, validates it from the server, and stores the data till we finally submit this form. The parameter stateful passed to the CactiveForm widget specifies the form needed to maintain the state across the pages. To do this, Yii creates a hidden field in each form with the name YII_PAGE_STATE, as shown in the following screenshot: All the data submitted on the first page is stored in this hidden field and passed to the server with the second page. To read the data from this field we have used the method getPageState(), and to write we have used setPageState(). We have added a private method checkPageState() to the User controller, which reads the page state, if any, and assigns it to $model->attributes, then assigns data from the current form using $model->attributes = $_POST['User'], and finally overwrites the page state with freshly combined data. When we click on Next on _page1, we set the POST variable page2, which in turn executes the second block in the if-else ladder in actionCreate. In this article, we create an instance of the model User with scenario set to _page1 (as we need to validate the data received from _page1). With a call to checkPageState(), we check the current page state and add any new data from _page1 to the page state. Then we check if the data filled is valid using $model->validate() . If the model passes the validation we set, apply view to _page2 and set $model->scenario to _page2, to mark the required fields on _page2. If the validation fails, we set the view to _page1 with the validation errors set in the model. At the end of the action, we render the selected view with the current state of the model. If any validation errors are set, they are listed on the same page; else, the next page will be rendered. The same steps are repeated for _page2 as well. When the submit button is clicked on on _page3, we retrieve the previous data from the page state using getPageState(). Here we are not using checkPageState() as now we do not need to store any data to the page state. We simply assign the data from _page3 to the model, and if the model validates we save all the data to the database with $model->save(). After saving, we are redirected to actionView(), where data from all three forms is listed as shown in the following screenshot: Summary In this article, we saw the importance of dividing big single forms into mulitpage forms. The article provided an insight into the making of multipage forms. Resources for Article : Further resources on this subject: Play! Framework 2 – Dealing with Content [Article] Play Framework: Introduction to Writing Modules [Article] Generating Content in WordPress Top Plugins—A Sequel [Article]
Read more
  • 0
  • 0
  • 11467
Modal Close icon
Modal Close icon