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

How-To Tutorials

7018 Articles
article-image-advanced-effects-using-blender-particle-system-sequel
Packt
18 Aug 2010
6 min read
Save for later

Advanced Effects using Blender Particle System: A Sequel

Packt
18 Aug 2010
6 min read
(For more resources on Blender, see here.) Multiple Particle Systems Sometimes, singular particle systems are not enough to create the effects we want. This is when multiple particles come in, enabling us to create things like welding sparks, fireworks, rain splash, object shatters, etc. Thankfully, we have Reactor Particles which does just that. In most cases, reactor particles are born when other particle systems' events happen. You'll see more of that later in this part. I guess the best way to explain these things is through valid examples. Let's begin by simulating the fireworks effect we see during New Year or when there are festivities. First thing we need to do is to setup our scene. We'll be creating a very simple setup for now and it's up to you to take it further when needed. Fire up Blender 2.49 (sadly, Blender 2.5 doesn't support reactor particles yet) and orient the camera such that it is facing towards the positive y axis, as shown in the screenshot below: (Move the mouse over the image to enlarge it.) (Positioning the Camera) Next, delete the default Cube and add a Plane object then position it just below the camera's view. You can scale it according to your liking but we can also adjust it later on if need be. Let's name this plane “emitter”. (Plane Added in the Scene) With the “emitter” object still selected, go to Object (F7) then click on Particle buttons and add a new particle system. (Adding a New Particle System) This particle system will be the single burst that will eventually give birth to hundreds of particles later on. Let's name it “single” for easier reference later on. Keep the amount at a minimum, probably something like lower than 20, so it won't get too chaotic later on once the bursting of particles begin. Also change the Life of the particle system such that you see them die on your camera's view, otherwise we won't be able to see the bursting effect happening at all. And lastly, increase the Normal value under Physics, this will tell how the particles are shot and how fast. You might also have to edit the Life later on once you have decided on the Normal settings. (“single” Particle Settings) (Single Frame from the Particle System Animation) Now if we play back our animation, it should look something like this: (fireworks_1.avi) Next is the main particles for this system – the burst. With the plane emitter still selected, head over to the same window where the Particle System was created. On the upper right hand corner of the Particle System tab, you'll notice a portion there with “1 Part 1” on it with arrows left and right. These are indications of how many sub-particle systems there are in our main system. Our reaction particles would not act if it was a different system, so this is one crucial part. Where you see the 1 Part 1 area, click on the right arrow to register another sub-particle system, making it a “2 Part 2”. Then click on Add New again, just like how we did in the previous part. (Adding a Sub-Particle System) The important options that we have to take note here are the particle system type, emit from values, and target. With the Physics option, I'll leave it to you to tweak around. As you might have already guessed, we must first and foremost, choose Reactor as the particle system type, otherwise it would be useless doing so. Next is to change from which will the particles be emitted from (emit from), choose Particle since we wanted it to be emitted from the first particle system that we created. Then in the Target portion, you can choose from which system will it be emitted from, the default which is Psys:1, you can change this setting accordingly depending on which order you want it to be emitted. (Reactor Particle System Settings) Then here's the hardware rendered version of the system: (fireworks_2.avi) And that's about it! This is also applicable to things like welding sparks or rain splashes. If you want your particle reactor to happen on object collision, instead of setting the particle reactor to begin on Death, change it to Collision then set your objects as collision objects. You can check Part 1 of this article to see more on the material settings. And just a bonus, I've added some tiny details to particle system. You can check out the video below and also download the .blend file. (fireworks_3.avi) Boids Particle boids, are by far, one of the most underestimated and overlooked strengths of Blender's particle system. Not only is it very daunting at first, but the complexity it can offer you is mind blowing. Simply put, Particle Boid or Boids Particle System is a type of Particle Physics whereby it follows rules and protocols that a user has set. These rules may range from prey and predator relationships to advanced crowd simulation. They can be related to artificial intelligence in ways that each particle point can behave differently and act on its own regardless of the other particle points present in space. I don't, however, claim to have really surmounted boids particle systems, even before in earlier versions of Blender. It is so exciting and exhilirating yet frustrating at times. To fully comprehend it, you need lots and lots of patience, probably more time to tweak around, and a note near you to have the settings listed down. For the sake of this article, I'll keep this introduction to boids particle system as simple and as quick as possible, giving you more freedom to experiment and just give you a basic understanding on what this particle system is all about. Let's get going, shall we? Fire up Blender 2.53 and delete the default Cube in your scene. (Deleting the Default Cube) Next, we need to add the basic elements for our basic boids particle system. It includes 1) an emitter, 2) the visualization object, and 3) the goal object. With the cube deleted in our 3d viewport, add a plane object (or anything you wish) and leave the default levels of division as it is, this would act as our particle emitter. Name it “emitter”. (Plane Object Added) Next, add a simple UV Sphere above the plane, this would then act as our goal object. Smooth the shading and scale to something like 0.200. Name this uv sphere as “goal”.
Read more
  • 0
  • 0
  • 9666

article-image-sessions-and-users-php-5-cms
Packt
17 Aug 2010
14 min read
Save for later

Sessions and Users in PHP 5 CMS

Packt
17 Aug 2010
14 min read
(For more resources on PHP, see here.) The problem Dealing with sessions can be confusing, and is also a source of security loopholes. So we want our CMS framework to provide basic mechanisms that are robust. We want them to be easy to use by more application-oriented software. To achieve these aims, we need to consider: The need for sessions and their working The pitfalls that can introduce vulnerabilities Efficiency and scalability considerations Discussion and considerations To see what is required for our session handling, we shall first review the need for them and consider how they work in a PHP environment. Then the vulnerabilities that can arise through session handling will be considered. Web crawlers for search engines and more nefarious activities can place a heavy and unnecessary load on session handling, so we shall look at ways to avoid this load. Finally, the question of how best to store session data is studied. Why sessions? The need for continuity was mentioned when we first discussed users. But it is worth reviewing the requirement in a little more detail. If Tim Berners-Lee and his colleagues had known all the developments that would eventually occur in the internet world, maybe the Web would have been designed differently. In particular, the basic web transport protocol HTTP might not have treated each request in isolation. But that is hindsight, and the Web was originally designed to present information in a computer-independent way. Simple password schemes were sufficient to control access to specific pages. Nowadays, we need to cater for complex user management, or to handle things like shopping carts, and for these we need continuity. Many people have recognized this, and introduced the idea of sessions. The basic idea is that a session is a series of requests from an individual website visitor, and the session provides access to enduring information that is available throughout the session. The shopping cart is an obvious example of information being retained across the requests that make up a session. PHP has its own implementation of sessions, and there is no point reinventing the wheel, so PHP sessions are the obvious tool for us to use to provide continuity. How sessions work There are three main choices which have been available for handling continuity: Adding extra information to the URI Using cookies Using hidden fields in the form sent to the browser All of them can be used at times. Which of them is most suitable for handling sessions? PHP uses either of the first two alternatives. Web software often makes use of hidden variables, but they do not offer a neat way to provide an unobtrusive general mechanism for maintaining continuity. In fact, whenever hidden variables are used, it is worth considering whether session data would be a better alternative. For reasons discussed in detail later, we shall consider only the use of cookies, and reject the URI alternative. There was a time when there were lots of scary stories about cookies, and people were inclined to block them. While there will always be security issues associated with web browsing, the situation has changed, and the majority of sites now rely on cookies. It is generally considered acceptable for a site to demand the use of cookies for operations such as user login or for shopping carts and purchase checkout. The PHP cookie-based session mechanism can seem obscure, so it is worth explaining how it works. First we need to review the working of cookies. A cookie is simply a named piece of data, usually limited to around 4,000 bytes, which is stored by the browser in order to help the web server to retain information about a user. More strictly, the connection is with the browser, not the user. Any cookie is tied to a specific website, and optionally to a particular part of the website, indicated by a path. It also has a life time that can be specified explicitly as a duration; a zero duration means that the cookie will be kept for as long as the browser is kept open, and then discarded. The browser does nothing with cookies, except to save and then return them to the server along with requests. Every cookie that relates to the particular website will be sent if either the cookie is for the site as a whole, or the optional path matches the path to which the request is being sent. So cookies are entirely the responsibility of the server, but the browser helps by storing and returning them. Note that, since the cookies are only ever sent back to the site that originated them, there are constraints on access to information about other sites that were visited using the same browser. In a PHP program, cookies can be written by calling the set_cookie function, or implicitly through session handling. The name of the cookie is a string, and the value to be stored is also a string, although the serialize function can be used to make more structured data into a string for storage as a cookie. Take care to keep the cookies within the size limit. PHP makes available the cookies that have been sent back by the browser in the $_COOKIES super-global, keyed by their names. Apart from any cookies explicitly written by code, PHP may also write a session cookie. It will do so either as a result of calls to session handling functions, or because the system has been configured to automatically start or resume a session for each request. By default, session cookies do not use the option of setting an expiry time, but can be deleted when the browser is closed down. Commonly, browsers keep this type of cookie in memory so that they are automatically lost on shutdown. Before looking at what PHP is doing with the session cookie, let's note that there is an important general consideration for writing cookies. In the construction of messages between the server and the browser, cookies are part of the header. That means rules about headers must be obeyed. Headers must be sent before anything else, and once anything else has been sent, it is not permitted to send more headers. So, in the case of server to browser communication, the moment any part of the XHTML has been written by the PHP program, it is too late to send a header, and therefore too late to write a cookie. For this reason, a PHP session is best started early in the processing. The only purpose PHP has in writing a session cookie is to allocate a unique key to the session, and retrieve it again on the next request. So the session cookie is given an identifying name, and its value is the session's unique key. The session key is usually called the session ID, and is used by PHP to pick out the correct set of persistent values that belong to the session. By default, the session name is PHPSESSID but it can, in most circumstances, be changed by calling the PHP function session_name prior to starting the session. Starting, or more often restarting, a session is done by calling session_start, which returns the session ID. In a simple situation, you do not need the session ID, as PHP places any existing session data in another superglobal, $_SESSION. In fact, we will have a use for the session ID as you will soon see. The $_SESSION super-global is available once session_start has been called, and the PHP program can store whatever data it chooses in it. It is an array, initially empty, and naturally the subscripts need to be chosen carefully in a complex system to avoid any clashes. The neat part of the PHP session is that provided it is restarted each time with session_start, the $_SESSION superglobal will retain any values assigned during the handling of previous requests. The data is thus preserved until the program decides to remove it. The only exception to this would be if the session expired, but in a default configuration, sessions do not expire automatically. Later in this article, we will look at ways to deliberately kill sessions after a determinate period of inactivity. As it is only the session ID that is stored in the cookie, rules about the timing of output do not apply to $_SESSION, which can be read or written at any time after session_start has been called. PHP stores the contents of $_SESSION at the end of processing or on request using the PHP function session_write_close. By default, PHP puts the data in a temporary file whose name includes the session ID. Whenever the session data is stored, PHP retrieves it again at the next session_start. Session data does not have to be stored in temporary files, and PHP permits the program to provide its own handling routines. We will look at a scheme for storing the session data in a database later in the article. Avoiding session vulnerabilities So far, the option to pass the session ID as part of the URI instead of as a cookie has not been considered. Looking at security will show why. The main security issue with sessions is that a cracker may find out the session ID for a user, and then hijack that user's session. Session handling should do its best to guard against that happening. PHP can pass the session ID as part of the URI. This makes it especially vulnerable to disclosure, since URIs can be stored in all kinds of places that may not be as inaccessible as we would like. As a result, secure systems avoid the URI option. It is also undesirable to find links appearing in search engines that include a session ID as part of the URI. These two points are enough to rule out the URI option for passing session ID. It can be prevented by the following PHP calls: ini_set('session.use_cookies', 1);ini_set('session.use_only_cookies', 1); These calls force PHP to use cookies for session handling, an option that is now considered acceptable. The extent to which the site will function without cookies depends on what a visitor can do with no continuity of data—user login will not stick, and anything like a shopping cart will not be remembered. It is best to avoid the default name of PHPSESSID for the session cookie, since that is something that a cracker could look for in the network traffic. One step that can be taken is to create a session name that is the MD5 hash of various items of internal information. This makes it harder but not impossible to sniff messages to find out a session ID, since it is no longer obvious what to seek—the well known name of PHPSESSID is not used. It is important for the session ID to be unpredictable, but we rely on PHP to achieve that. It is also desirable that the ID be long, since otherwise it might be possible for an attacker to try out all possible values within the life of a session. PHP uses 32 hexadecimal digits, which is a reasonable defense for most purposes. The other main vulnerability apart from session hijacking is called session fixation. This is typically implemented by a cracker setting up a link that takes the user to your site with a session already established, and known to the cracker. An important security step that is employed by robust systems is to change the session ID at significant points. So, although a session may be created as soon as a visitor arrives at the site, the session ID is changed at login. This technique is used by Amazon among others so that people can browse for items and build up a shopping cart, but on purchase a fresh login is required. Doing this reduces the available window for a cracker to obtain, and use, the session ID. It also blocks session fixation, since the original session is abandoned at critical points. It is also advisable to change the ID on logout, so although the session is continued, its data is lost and the ID is not the same. It is highly desirable to provide logout as an option, but this needs to be supplemented by time limits on inactive sessions. A significant part of session handling is devoted to keeping enough information to be able to expire sessions that have not been used for some time. It also makes sense to revoke a session that seems to have been used for any suspicious activity. Ideally, the session ID is never transmitted unencrypted, but achieving this requires the use of SSL, and is not always practical. It should certainly be considered for high security applications. Search engine bots One aspect of website building is, perhaps unexpectedly, the importance of handling the bots that crawl the web. They are often gathering data for search engines, although some have more dubious goals, such as trawling for e-mail addresses to add to spam lists. The load they place on a site can be substantial. Sometimes, search engines account for half or more of the bandwidth being used by a site, which certainly seems excessive. If no action is taken, these bots can consume significant resources, often for very little advantage to the site owner. They can also distort information about the site, such as when the number of current visitors is displayed but includes bots in the counts. Matters are made worse by the fact that bots will normally fail to handle cookies. After all, they are not browsers and have no need to implement support for cookies. This means that every request by a bot is separate from every other, as our standard mechanism for linking requests together will not work. If the system starts a new session, it will have to do this for every new request from a bot. There will never be a logout from the bot to terminate the session, so each bot-related session will last for the time set for automatic expiry. Clearly it is inadvisable to bar bots, since most sites are anxious to gain search engine exposure. But it is possible to build session handling so as to limit the workload created by visitors who do not permit cookies, which will mostly be bots. When we move into implementation techniques, the mechanisms will be demonstrated. Session data and scalability We could simply let PHP take care of session data. It does that by writing a serialized version of any data placed into $_SESSION into a file in a temporary directory. Each session has its own file. But PHP also allows us to implement our own session data handling mechanism. There are a couple of good reasons for using that facility, and storing the information in the database. One is that we can analyze and manage the data better, and especially limit the overhead of dealing with search engine bots. The other is that by storing session data in the database, we make it feasible for the site to be run across multiple servers. There may well be other issues before that can be achieved, but providing session continuity is an essential requirement if load sharing is to be fully effective. Storing session data in a database is a reliable solution to this issue. Arguments against storing session data in a database include questions about the overhead involved, constraints on database performance, or the possibility of a single point of failure. While these are real issues, they can certainly be mitigated. Most database engines, including MySQL, have many options for building scalable and robust systems. If necessary, the database can be spread across multiple computers linked by a high speed network, although this should never be done unless it is really needed. Design of such a system is outside the scope of this article, but the key point is that the arguments against storing session data in a database are not particularly strong.
Read more
  • 0
  • 0
  • 3437

article-image-implementing-microsoft-net-application-using-alfresco-web-services
Packt
17 Aug 2010
6 min read
Save for later

Implementing a Microsoft .NET Application using the Alfresco Web Services

Packt
17 Aug 2010
6 min read
(For more resources on Alfresco, see here.) For the first step, you will see how to set up the .NET project in the development environment. Then when we take a look at the sample code, we will learn how to perform the following operations from your .NET application: How to authenticate users How to search contents How to manipulate contents How to manage child associations Setting up the project In order to execute samples included with this article, you need to download and install the following software components in your Windows operating system: Microsoft .NET Framework 3.5 Web Services Enhancements (WSE) 3.0 for Microsoft .NET SharpDevelop 3.2 IDE The Microsoft .NET Framework 3.5 is the main framework used to compile the application, and you can download it using the following URL: http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en. Before importing the code in the development environment, you need to download and install the Web Services Enhancements (WSE) 3.0, which you can find at this address: http://www.microsoft.com/downloads/details.aspx?FamilyID=018a09fd-3a74-43c5-8ec1-8d789091255d. You can find more information about the Microsoft .NET framework on the official site at the following URL: http://www.microsoft.com/net/. From this page, you can access the latest news and the Developer Center where you can find the official forum and the developer community. SharpDevelop 3.2 IDE is an open source IDE for C# and VB.NET, and you can download it using the following URL: http://www.icsharpcode.net/OpenSource/SD/Download/#SharpDevelop3x. Once you have installed all the mentioned software components, you can import the sample project into SharpDevelop IDE in the following way: Click on File | Open | Project/Solution Browse and select this file in the root folder of the samples: AwsSamples.sln Now you should see a similar project tree in your development environment: More information about SharpDevelop IDE can be found on the official site at the following address: http://www.icsharpcode.net/opensource/sd/. From this page, you can download different versions of the product; which SharpDevelop IDE version you choose depends on the .NET version which you would like to use. You can also visit the official forum to interact with the community of developers. Also, notice that all the source code included with this article was implemented extending an existent open source project named dotnet. The dotnet project is available in the Alfresco Forge community, and it is downloadable from the following address:http://forge.alfresco.com/projects/dotnet/. Testing the .NET sample client Once you have set up the .NET solution in SharpDevelop, as explained in the previous section, you can execute all the tests to verify that the client is working correctly. We have provided a batch file named build.bat to allow you to build and run all the integration tests. You can find this batch file in the root folder of the sample code. Notice that you need to use a different version of msbuild for each different version of the .NET framework. If you want to compile using the .NET Framework 3.5, you need to set the following path in your environment: set PATH=%PATH%;%WinDir%Microsoft.NETFrameworkv3.5 Otherwise, you have to set .NET Framework 2.0 using the following path: set PATH=%PATH%;%WinDir%Microsoft.NETFrameworkv2.0.50727 We are going to assume that Alfresco is running correctly and it is listening on host localhost and on port 8080. Once executed, the build.bat program should start compiling and executing all the integration tests included in this article. After a few seconds have elapsed, you should see the following output in the command line: .........****************** Running tests ******************NUnit version 2.5.5.10112Copyright (C) 2002-2009 Charlie Poole.Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A.Vorontsov.Copyright (C) 2000-2002 Philip Craig.All Rights Reserved.Runtime Environment - OS Version: Microsoft Windows NT 5.1.2600 Service Pack 2 CLR Version: 2.0.50727.3053 ( Net 2.0 )ProcessModel: Default DomainUsage: SingleExecution Runtime: net-2.0............Tests run: 12, Errors: 0, Failures: 0, Inconclusive: 0, Time: 14.170376seconds Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0********* Done ********* As you can see from the project tree, you have some of the following packages: Search Crud Association The Search package shows you how to perform queries against the repository. The Crud package contains samples related to all the CRUD operations that show you how to perform basic operations; namely, how to create/get/update/remove nodes in the repository. The Association package shows you how to create and remove association instances among nodes. Searching the repository Once you have authenticated a user, you can start to execute queries against the repository. In the following sample code, we will see how to perform a query using the RepositoryService of Alfresco: RepositoryService repositoryService = WebServiceFactory.getRepositoryService(); Then we need to create a store where we would like to search contents: Store spacesStore = new Store(StoreEnum.workspace, "SpacesStore"); Now we need to create a Lucene query. In this sample, we want to search the Company Home space, and this means that we have to execute the following query: String luceneQuery = "PATH:"/app:company_home""; In the next step, we need to use the query method available from the RepositoryService. In this way, we can execute the Lucene query and we can get all the results from the repository: Query query =new Query(Constants.QUERY_LANG_LUCENE, luceneQuery);QueryResult queryResult =repositoryService.query(spacesStore, query, false); You can retrieve all the results from the queryResult object, iterating the ResultSetRow object in the following way: ResultSet resultSet = queryResult.resultSet;ResultSetRow[] results = resultSet.rows;//your custom listIList<CustomResultVO> customResultList =new List<CustomResultVO>();//retrieve results from the resultSetforeach(ResultSetRow resultRow in results){ ResultSetRowNode nodeResult = resultRow.node; //create your custom value object CustomResultVO customResultVo = new CustomResultVO(); customResultVo.Id = nodeResult.id; customResultVo.Type = nodeResult.type; //retrieve properties from the current node foreach(NamedValue namedValue in resultRow.columns) { if (Constants.PROP_NAME.Equals(namedValue.name)) { customResultVo.Name = namedValue.value; } else if (Constants.PROP_DESCRIPTION.Equals(namedValue.name)) { customResultVo.Description = namedValue.value; } } //add the current result to your custom list customResultList.Add(customResultVo);} In the last sample, we iterated all the results and we created a new custom list with our custom value object CustomResultVO. More information about how to build Lucene queries can be found at this URL: http://wiki.alfresco.com/wiki/Search. Performing operations We can perform various operations on the repository. They are documented as follows: Authentication For each operation, you need to authenticate users before performing all the required operations on nodes. The class that provides the authentication feature is named AuthenticationUtils, and it allows you to invoke the startSession and endSession methods: String username = "johndoe";String password = "secret";AuthenticationUtils.startSession(username, password);try{}finally{ AuthenticationUtils.endSession();} Remember that the startSession method requires the user credentials: the username as the first argument and the password as the second. Notice that the default endpoint address of the Alfresco instance is as follows: http://localhost:8080/alfresco If you need to change the endpoint address, you can use the WebServiceFactory class invoking the setEndpointAddress method to set the new location of the Alfresco repository.
Read more
  • 0
  • 0
  • 3577

article-image-flash-multiplayer-virtual-world-setting-smartfoxserver-third-party-http-and-database-s
Packt
17 Aug 2010
7 min read
Save for later

Flash Multiplayer Virtual World: Setting up SmartFoxServer with Third-party HTTP and Database Server

Packt
17 Aug 2010
7 min read
(For more resources on Flash, see here.) We are going to download and install Apache and MySQL server package. These kinds of server package features have easy install that auto-configures most of the server settings. It will also install some essential tool for beginners to manage the server easily, such as GUI server administration panel. Installing WAMP on Windows WampServer is an open source HTTP and database server solution on Windows. WAMP stands for Windows, Apache, MySQL, and PHP package. Go to http://www.wampserver.com/en/download.php. Click on Download WampServer to download the installer. Run the installer with all default settings. The server is configured and ready. The WampServer can run by launching from Start | Programs | WampServer | Start WampServer. It will be in the task bar and the server management operation can be found by clicking the WampServer icon. We can start the server by putting the server online in the menu. Installing MAMP on Mac OSX Similar to WampServer, MAMP is the one package web server solution that stands for Mac, Apache, MySQL, and PHP package. The MAMP package can be downloaded at http://www.mamp.info/. Download the MAMP package from the official website. Double-click on the downloaded MAMP dmg file to mount it. Drag the MAMP folder into the Applications folder. To run the MAMP server, go to Applications | MAMP and double-click on the MAMP.app. Installing LAMP on Linux As the same naming convention, the "L" stands for Linux here. Different Linux distributions use different ways to install applications. There may not be a oneclick install method on some Linux branch which requires us to install the Apache and MySQL individually. Some Linux may provide graphic user interface to install LAMP by just selecting it in the applications list. We will use Ubuntu to demonstrate the installation of LAMP. Launch terminal from Applications | Accessories | Terminal. Type following command to install LAMP. sudo tasksel install lamp-server The installer will progress and configure different modules. A dialog will prompt several times asking for a new MySQL root password. You can set your own MySQL password, while in the example we will leave the root password blank. After the completion of the installation, the MySQL server is set up as service in the system. It runs automatically and we do not need to manually launch it to use it. Connecting SmartFoxServer and MySQL server SmartFoxServer is a Java application and Java database connection driver is needed to connect from SmartFoxServer to MySQL database. Downloading JDBC Driver for MySQL JDBC is a Java database connection driver that we need to establish connections between the Java-based SmartFoxServer and the MySQL server. The JDBC driver for MySQL is called Connector/J. We are going to install it to enable MySQL connection from SmartFoxServer. Go to http://dev.mysql.com/downloads/connector/j/5.1.html in web browser. Download the Platform Independent Zip Archive. It may ask you to log in to MySQL.com account. Click on No thanks, just take me to the downloads! to bypass the login step. Choose a mirror to download by clicking on HTTP. Setting up the JDBC driver The MySQL Java connector comes with a bunch of files. We only need two among them. Extract the mysql-connector-java-5.1.10.zip file to a temporary folder. Open the folder and find the mysql-connector-java-5.1.10-bin.jar file. Copy that jar file into SmartFoxServer installation directory | jre | lib | ext. Go into the src directory of the extracted directory and copy the org directory to SmartFoxServer installation directory | jre | lib | ext. Configuring the server settings The configuration file of SmartFoxServer is an XML file that allows us to configure many server settings. It can configure the initial zone or room creation, server address, admin authorization, value tuning for performance, and a lot more. We are going to set the database connection for testing our setup in this article (core settings are out of scope of this article). The configuration file is called config.xml and is located in the SmartFoxServer installation directory under the Server directory. Configuring MySQL server connection in SmartFoxServer Open the config.xml in your favorite text editor. Go to line 203 of the config.xml. This line should be within the structure of a Zone tag with name as dbZone. Change the lines 203-218 from the config.xml: Original code: <DatabaseManager active="false"> <Driver>sun.jdbc.odbc.JdbcOdbcDriver</Driver> <ConnectionString>jdbc:odbc:sfsTest</ConnectionString> <!-- Example connecting to MySQL <Driver>org.gjt.mm.mysql.Driver</Driver> <ConnectionString>jdbc:mysql://192.168.0.1:3306/sfsTest </ConnectionString> --> <UserName>yourname</UserName> <Password>yourpassword</Password> <TestSQL><![CDATA[SELECT COUNT(*) FROM contacts]]></TestSQL> Replace the code in lines 203-218 with the following code: <DatabaseManager active="true"> <Driver>org.gjt.mm.mysql.Driver</Driver> <ConnectionString>jdbc:mysql://127.0.0.1:3306/mysql </ConnectionString> <UserName>root</UserName> <Password></Password> <TestSQL><![CDATA[SELECT NOW()]]></TestSQL> The new setting activates the DatabaseManager and configures the JDBC driver to the MySQL connector that we just downloaded. We also changed the user name and password of the connection to the database to "root" and empty password. We will use the empty password through out the development process but it is strongly recommended to set your own database user password. There is a TestSQL setting where we can write a simple database query so that the SmartFoxServer will try to run it to test if the database connection is correct. As we have not created any new databases for the virtual world, we will test the database connection by querying the current server time. Restarting the server We’ve just set up the connection between SmartFoxServer and third-party database. It is time to test the new setting by restarting the SmartFoxServer. To stop the SmartFoxServer in Windows and Linux, press Ctrl + C. To stop it in Mac OS X, click on the Cancel button in the SmartFoxServer log window. There is a log that appears as usual after we start up the server again. It is important to check the log carefully every time the config.xml is changed. The logfile can provide details of any errors that occur when it tries to load the configure file. For example, if we configure the database connection just now but forget to activate the DatabaseManager, the server will start up correctly. Then you may spend a lot of time debugging why the database connection is not working until you find that the DatabaseManager is not active at all. This happened to me several times while I was developing my first flash virtual world. If the server is running with the new database connection settings, the following lines will be appearing in the log. There can be different database manager settings for each zone. When checking the log, we should be aware which zone the log is referring to. We are configuring the database manager of dbZone zone now. DB Manager Activated ( org.gjt.mm.mysql.Driver ) Zone: dbZone If we forget to activate the DatabaseManager, we will not see the DB Manager Activated wording. Instead, the following message may appear in the log: DB Manager is not active in this Zone! Moreover, if the SmartFoxServer faces some fatal error on start up, it will terminate itself with more detailed error logs. The following lines are an example for error logs that appear when the MySQL connector file is missing: Can’t load db driver: org.gjt.mm.mysql.Driver [ Servre ] > DbManager could not retrive a connection. Java.sql.SQLException: Configuration file not found DbManagerException: The Test SQL statement failed! Please check your configuration. These lines state that the testing SQL failed to run, which we just set to test the connection. It also describes what exception has caused this error to help the debugging.
Read more
  • 0
  • 0
  • 4918

article-image-netbeans-platform-69-working-window-system
Packt
17 Aug 2010
12 min read
Save for later

NetBeans Platform 6.9: Working with Window System

Packt
17 Aug 2010
12 min read
(For more resources on NetBeans, see here.) Window System Large desktop applications need to provide many different views for visualizing data. These views have to be managed and shown and the NetBeans Platform handles these requirements for you out of the box via its docking framework. While it once might have been sufficient for a docking framework to provide static fixed window layouts, today the user expects far more flexibility. Windows should be able to be opened, movable, and, generally, customizable at runtime. The user tends to assume that the positions of views are modifiable and that they persist across restarts of the application. Not only that, but applications are assumed to be so fiexible that views should be detachable from the application's main window, enabling them to be displayed on multiple monitors at the same time. While once the simple fact of the availability of menus and toolbars was sufficient, today a far more dynamic handling is needed so that window content can be adapted dynamically. Connected to these expectations of flexibility, plugins are increasingly becoming a standard technology, with the user assuming their windows to be pluggable, too. In short, the requirements for window management have become quite complex and can only be met by means of an external docking framework, otherwise all these various concerns would need to be coded (and debugged, tested, and maintained) by hand. The NetBeans Platform provides all of these features via its docking framework, known as the NetBeans Window System. It also provides an API to let you programmatically access the window system. Together, the window system and its API fulfill all the requirements described above, letting you concentrate on your domain knowledge and business logic rather than on the work of creating a custom window management facility for each of your applications. This part of the article teaches you the following: How to define views How to position views in the main window Rest is covered in the second part of this article series. Creating a window The NetBeans Window System simplifies window management by letting you use a default component for displaying windows. The default component, that is, the superclass of all windows, is the TopComponent class, which is derived from the standard JComponent class. It defines many methods for controlling a window and handles notification of main window system events. The WindowManager is the central class controlling all the windows in the application. Though you can implement this class yourself, this is seldom done as normally the default WindowManager is sufficient. Similarly, you typically use the standard TopComponent class, rather than creating your own top-level Swing components. In contrast to the TopComponent class, the default WindowManager cannot manage your own top-level Swing components, so these cannot take advantage of the Window System API. Now let's create a TopComponent and let it be an editor for working with tasks. This is done easily by using the New Window wizard. In the Projects window, right-click the TaskEditor module project node and choose New | Window. On the first page of the wizard select Editor for Window Position and Open on Application Start. Click Next. In the next page of the wizard, type TaskEditor in Class Name Prefix. This prefix is used for all the generated files. It is possible to specify an icon that will be displayed in the tab of the new window, but let's skip that for the moment. Click Finish and all the files are generated into your module source structure. Next, open the newly created TaskEditorTopComponent and drag the TaskEditorPanel from the Palette, which is where you put it at the end of the last chapter, onto the form. The size of the component automatically adjusts to the required size of he panel. Position the panel with the preferred spacing to the left and top and activate the automatic resizing of the panel in horizontal and vertical direction. The form should now look similar to the following screenshot: Start the application. You now see a tab containing the new TaskEditor Window, which holds your form. Examining the generated files You have used a wizard to create a new TopComponent. However, the wizard did more than that. Let's take a look at all the files that have been created and at all the files that have been modified, as well as how these files work together. The only Java class that was generated is the TopComponent that will contain the TaskEditor, shown as follows: @ConvertAsProperties(dtd = "-//com.netbeansrcp.taskeditor//TaskEditor// EN", autostore = false) public final class TaskEditorTopComponent extends TopComponent { private static TaskEditorTopComponent instance; /** path to the icon used by the component and its open action */ // static final String ICON_PATH = "SET/PATH/TO/ICON/HERE"; private static final String PREFERRED_ID = "TaskEditorTopComponent"; public TaskEditorTopComponent() { initComponents(); setName(NbBundle.getMessage(TaskEditorTopComponent.class, "CTL_TaskEditorTopComponent")); setToolTipText(NbBundle.getMessage(TaskEditorTopComponent.class, "HINT_TaskEditorTopComponent")); // setIcon(ImageUtilities.loadImage(ICON_PATH, true)); } /**This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { javax.swing.GroupLayout layout = new javax.swing. GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout. Alignment.LEADING).addGap(0, 555, Short.MAX_VALUE)); layout.setVerticalGroup(layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 442, Short.MAX_VALUE) ); }// </editor-fold> // Variables declaration - do not modify // End of variables declaration /** * Gets default instance. Do not use directly: reserved for *.settings files only, * i.e. deserialization routines; otherwise you could get a non-deserialized instance. * To obtain the singleton instance, use {@link #findInstance}. */ public static synchronized TaskEditorTopComponent getDefault() { if (instance == null) { instance = new TaskEditorTopComponent(); } return instance; } /** * Obtain the TaskEditorTopComponent instance. Never call { @link #getDefault} directly! */ public static synchronized TaskEditorTopComponent findInstance() { TopComponent win = WindowManager.getDefault().findTopComponent (PREFERRED_ID); if (win == null) { Logger.getLogger(TaskEditorTopComponent.class.getName()). warning("Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system."); return getDefault(); } if (win instanceof TaskEditorTopComponent) { return (TaskEditorTopComponent) win; } Logger.getLogger(TaskEditorTopComponent.class.getName()). warning("There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior."); return getDefault(); } @Override public int getPersistenceType() { return TopComponent.PERSISTENCE_ALWAYS; } @Override public void componentOpened() { // TODO add custom code on component opening } @Override public void componentClosed() { // TODO add custom code on component closing } void writeProperties(java.util.Properties p) { // better to version settings since initial version as advocated at // http://wiki.apidesign.org/wiki/PropertyFiles p.setProperty("version", "1.0"); // TODO store your settings } Object readProperties(java.util.Properties p) { if (instance == null) { instance = this; } instance.readPropertiesImpl(p); return instance; } private void readPropertiesImpl(java.util.Properties p) { String version = p.getProperty("version"); // TODO read your settings according to their version } @Override protected String preferredID() { return PREFERRED_ID; } } As expected, the class TaskEditorTopComponent extends the TopComponent class. Let's look at it more closely: For efficient resource usage, the generated TopComponent is implemented as a singleton. A private constructor prohibits its incorrect usage from outside by disallowing direct instantiation of the class. The static attribute instance holds the only instance in existence. The static method getDefault creates and returns this instance if necessary on demand. Typically, getDefault should never be called directly. Instead of this, you should use findInstance, which delegates to getDefault if necessary. findInstance tries to retrieve the instance using the Window Manager and the ID of the TopComponent before falling back to the singleton instance. This ensures the correct usage of persistent information. The constructor creates the component tree for the TaskEditorTopComponent by calling the method init Components(). This method contains only code generated via the NetBeans "Matisse" Form Builder and is read-only in the NetBeans Java editor. You can change the code in this method using the Form Builder's Property Sheet, as will be shown later. The static property PreferredID holds the TopComponent ID used for identification of the TopComponent. As indicated by its name, the ID can be changed by the Window System, if name clashes occur. The ID is used throughout all the configuration files. The methods componentOpened() and componentClosed() are part of the lifecycle of the TopComponent. You learn about the method getPersistenceType() later, in the section about the persistence of TopComponents. What does the Java code do and not do? The Java code only defines the visual aspects of the TaskEditorTopComponent and manages the singleton instance of this component. In no way does the code describe how and where the instance is shown. That's the task of the two XML files, described below. Two small XML files are created by the wizard. The first is the TopComponent's settings file: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"> <settings version="1.0"> <module name="com.netbeansrcp.taskeditor" spec="1.0"/> <instanceof class="org.openide.windows.TopComponent"/> <instanceof class="com.netbeansrcp.taskeditor. TaskEditorTopComponent"/> <instance class="com.netbeansrcp.taskeditor.TaskEditorTopComponent" method="getDefault"/> </settings> The settings file describes the persistent instance of the TopComponent. As you can see, the preceding configuration describes that the TopComponent belongs to the module TaskEditor in the specification version "1.0" and that it is an instance of the types TopComponent and TaskEditorTopComponent. Also described is that the instance that is created is done so using the method call TaskEditorTopComponent.getDefault(). <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd"> <tc-ref version="2.0" > <module name="com.netbeansrcp.taskeditor" spec="1.0"/> <tc-id id="TaskEditorTopComponent"/> <state opened="true"/> </tc-ref> The WSTCREF (window system creation file) describes the position of the TopComponent within the main window. This becomes clearer with the following file. The other important information in the WSTCREF file is the opened state at application start. Typically, you do not have to change these two configuration files by hand. This is not true for the following file, the layer.xml, which you often need to change manually, to register new folders and files in the filesystem. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http:// www.netbeans.org/dtds/filesystem-1_2.dtd"> <filesystem> <folder name="Actions"> <folder name="Window"> <file name="com-netbeansrcp-taskeditor.TaskEditorAction.instance"> <attr name="component" methodvalue="com.netbeansrcp.taskeditor. TaskEditorTopComponent.findInstance"/> <attr name="displayName" bundlevalue="com.netbeansrcp.taskeditor. Bundle#CTL_TaskEditorAction"/> <attr name="instanceCreate" methodvalue="org.openide.windows. TopComponent.openAction"/> </file> </folder> </folder> <folder name="Menu"> <folder name="Window"> <file name="TaskEditorAction.shadow"> <attr name="originalFile" stringvalue="Actions/Window/com netbeansrcp-taskeditor-TaskEditorAction.instance"/> </file> </folder> </folder> <folder name="Windows2"> <folder name="Components"> <file name="TaskEditorTopComponent.settings" url="TaskEditorTopComponentSettings.xml"/> </folder> <folder name="Modes"> <folder name="editor"> <file name="TaskEditorTopComponent.wstcref" url="TaskEditorTopComponentWstcref.xml"/> </folder> </folder> </folder> </filesystem> The layer.xml is integrated into the central registry (also known as the SystemFileSystem) using the via a registration entry in the module's manifest file. The SystemFileSystem is a virtual filesystem for user settings. Each module can supply a layer file for merging configuration data from the module into the SystemFileSystem. The Window System API and the Actions API reserve a number of folders in the central registry for holding its configuration data. These folders enable specific subfolders and files relating to window system registration to be added to the filesystem. Let's have a look at the folder Windows2. Windows2 contains a folder named Components, which contains a virtual file with the name of the TopComponent and the extension .settings. This .settings file redirects to the real settings file. It is used to make the configuration known to the Window System. In addition, the Windows2 folder contains a folder named Modes, which contains a folder named editor. Modes represent the possible positions at which TopComponents can be shown in the application. The editor folder contains a .wstcref file for our TopComponent, which refers to the real WSTCREF file. This registers the TopComponent in the mode editor, so it shows up where typically editor windows are opened, which is the central part of the main window. Next , take a look at the folder Actions. It contains a folder named Window which contains a file declaring the action opening the TaskEditorTopComponent. The name is typically following Java class naming conventions with dots replaced by dashes and ending in .instance. The declaration of the virtual file itself consists of three critical parts. The attribute component describes how to create the component (methodvalue declares which method to call). The attribute displayName describes the default action name as shown in the example, in menu items. A possible declaration is the bundle value which describes the bundle and key to use to retrieve the display name. The attribute instanceCreate uses a static method call to create a real action to use. The folder Menu describes the application main menu. The folder Window contains a .shadow file. The attribute originalFile uses the full path in the SystemFileSytem to delegate to the original action declaration. As described above, .shadow files are used as symbolic links to real-defined virtual files. This declaration adds the action to the real menu bar of the application. As a result, important parts of the Window System API are not called programmatically, but are simply used declaratively. Declarative aspects include configuration and the positioning of windows, as well as the construction of the menu. In addition, you discovered that the wizard for creating TopComponents always creates singleton views. If you would like to change that, you need to adapt the code created by the wizard. For the time being, it is sufficient to use the singleton approach, particularly as it is more resource-friendly.
Read more
  • 0
  • 0
  • 1970

article-image-osb-deployment-automation-using-oracle-enterprise-manager
Packt
17 Aug 2010
4 min read
Save for later

OSB Deployment Automation using Oracle Enterprise Manager

Packt
17 Aug 2010
4 min read
(For more resources on Oracle, see here.) Challenges Deploying applications in production environments is a challenge. The SOA application developers build new projects, or new versions of existing projects, and throw them "over the wall" to the operations team. Administrators have to deploy multiple application files to multiple targets, in a fixed time window. This process is repeated when moving from test to stage to production. This consumes time and requires expertise on these applications. Controlling the WebLogic projects centrally is the first challenge, where administrators have to track the project versions to comply with change and release management guidelines. Next the deployment itself is a challenge, considering the administrator needs to deploy the projects with specific customizations and honor the scheduled maintenance window. All in all, the administrator has too many manual tasks to deal with, given the constraints of the operational environment. Solution With Grid Control, administrators can deploy multiple OSB projects to a domain deployment procedure framework. A five-step interview process lets the user pick the source projects, pick the target OSB server and domain, set the credentials, specify configurations and the customization file, and schedule a future deployment using the job system. Store OSB deployment artifacts in an enterprise Software Library Export OSB deployment artifacts from a live OSB server Track maturity of OSB deployment artifacts and usage Deploy OSB projects from test to stage to production Deploy in a future maintenance window Step-by-step exercise This set of step-by-step exercises will walkthrough managing the deployment of OSB projects. Viewing the Software Library The first step is to view the operational store or the Software Library in Grid Control. This is the starting point for administrators to look at the inventory, add items, or change existing items. From the Grid Control home page, click on the Deployments tab. Click the Provisioning sub-tab. The Software Library contains several objects such as operating system images, Oracle homes for database and application server, and deployment artifacts for BPEL, OSB, and so on. The Library is used to track the maturity of these components as they are used on various monitored targets. Expand Components to reveal the component types. (Move the mouse over the image to enlarge.) Uploading projects to the Software Library In this particular scenario, the administrator has been handed a copy of the OSB project, and needs to deploy it. Before deployment, the administrator needs to upload the projects to the Grid Control Software Library for tracking, operational version control, and to enable deployment: Upload OSB Projects to Software Library Select the radio button for Oracle Components. Click on the Create Component button. Enter the following values in the Describe step, as shown in the next screenshot: Select Type as Generic Component. Name as OSB projects. Leave the other fields blank. Click on Next In the Customize step, leave the defaults and click on Next. In the Upload File step: Select Upload from Agent Machine. Click on the Select Target button. Select the Host Name as gcsoa.us.oracle.com. Click on the Select File button. Select the location of the sbconfig.jar from a pre-existing project from an OSB server, which was zipped up and stored on the local machine; for instance: /u01/homes/osb_wls/projects/sbconfig.jar. Note that you can directly export projects from a live OSB server during the deployment process. This will be the most common usage of the deployment procedure. Here, for this workshop though, the export jar has already been created in advance. This export jar contains several projects extracted from another OSB server. Click on Next. On the Set Directives step, click on Next. On the Review step, note the details, and click on Finish. Note the confirmation message, and the new OSB Project generic component that has been added. Activate the OSB projects for use: Select the radio button for OSB Projects. Click on Activate, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 2003
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-netbeans-platform-69-advanced-aspects-window-system
Packt
17 Aug 2010
5 min read
Save for later

NetBeans Platform 6.9: Advanced Aspects of Window System

Packt
17 Aug 2010
5 min read
(For more resources on NetBeans, see here.) Creating custom modes You can get quite far with the standard modes provided by the NetBeans Platform. Still, sometimes you may need to provide a custom mode, to provide a new position for the TopComponents within the application. A custom mode is created declaratively in XML files, rather than programmatically in Java code. In the following example, you create two new modes that are positioned side by side in the lower part of the application using a specific location relative to each other. Create a new module named CustomModes, with Code Name Base com.netbeansrcp.custommodes, within the existing WindowSystemExamples application. Right-click the module project and choose New | Other to open the New File dialog. Then choose Other | Empty File, as shown in the following screenshot: Type mode1.wsmode as the new filename and file extension, as shown in the following screenshot. Click Finish. Define the content of the new mode1.wsmode as follows: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mode PUBLIC "-//NetBeans//DTD Mode Properties 2.3//EN" "http://www.netbeans.org/dtds/mode-properties2_3.dtd"> <mode version="2.3"> <name unique="mode1" /> <kind type="view" /> <state type="joined" /> <constraints> <path orientation="vertical" number="20" weight="0.2"/> <path orientation="horizontal" number="20" weight="0.5"/> </constraints> </mode> Create another file to define the second mode and name it mode2.wsmode. Add this content to the new file: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mode PUBLIC "-//NetBeans//DTD Mode Properties 2.3//EN" "http://www.netbeans.org/dtds/mode-properties2_3.dtd"> <mode version="2.3"> <name unique="mode2" /> <kind type="view" /> <state type="joined" /> <constraints> <path orientation="vertical" number="20" weight="0.2"/> <path orientation="horizontal" number="40" weight="0.5"/> </constraints> </mode> Via the two wsmode files described above, you have defined two custom modes. The first mode has the unique name mode1, with the second named mode2. Both are created for normal TopComponents (view instead of editor) that are integrated into the main window, rather than being undocked by default (joined instead of separated). The constraints elements in the files are comparable to GridBagLayout, with a relative horizontal and vertical position, as well as a relative horizontal and vertical weight. You place mode1 in position 20/20 with a weighting of 0,5/0,2, while mode2 is placed in position 20/40 with the same weighting. If all the other defined modes have TopComponents opened within them, the TopComponents in the two new modes should lie side by side, right above the status bar, taking up 20% of the available vertical space, with the horizontal space shared between them. Let us now create two new TopComponents and register them in the layer.xml file so that they will be displayed in your new modes. Do this by using the New Window wizard twice in the CustomModes module, first creating a window called Class Name Prefix Red and then a window with Class Name Prefix Blue. What should I set the window position to? In the wizard, in both cases, it does not matter what you set to be the window position, as you are going to change that setting manually afterwards. Let both of them open automatically when the application starts. In the Design mode of both TopComponents, add a JPanel to each of the TopComponents. Change the background property of the panel in the RedTopComponent to red and in the BlueTopComponent to blue. Edit the layer.xml of CustomModes module, registering the two .wsmode files and ensuring that the two new TopComponents open in the new modes: <folder name="Windows2"> <folder name="Components"> <file name="BlueTopComponent.settings" url="BlueTopComponentSettings.xml"/> <file name="RedTopComponent.settings" url="RedTopComponentSettings.xml"/> </folder> <folder name="Modes"> <file name="mode1.wsmode" url="mode1.wsmode"/> <file name="mode2.wsmode" url="mode2.wsmode"/> <folder name="mode1"> <file name="RedTopComponent.wstcref" url="RedTopComponentWstcref.xml"/> </folder> <folder name="mode2"> <file name="BlueTopComponent.wstcref" url="BlueTopComponentWstcref.xml"/> </folder> </folder> </folder> As before, perform a Clean and Build on the application project node and then start the application again. It should look as shown in the following screenshot: In the summary, you defined two new modes in XML files and registered them in the module's layer.xml file. To confirm that the modes work correctly, you use the layer.xml file to register two new TopComponents so that they open by default into the new modes. As a result, you now know how to extend the default layout of a NetBeans Platform application with new modes.
Read more
  • 0
  • 0
  • 1446

article-image-error-handling-php-5-cms
Packt
17 Aug 2010
10 min read
Save for later

Error Handling in PHP 5 CMS

Packt
17 Aug 2010
10 min read
(For more resources on PHP, see here.) The problem Errors will happen whether we like it or not. Ideally the framework can help in their discovery, recording, and handling by: Trapping different kinds of errors Making a record of errors with sufficient detail to aid analysis Supporting a structure that mitigates the effect of errors Discussion There are three main kinds of errors that can arise. Many possible situations can crop up within PHP code that count as errors, such as an attempt to use a method on a variable that turns out not to be an object, or is an object but does not implement the specified method. The database will sometimes report errors, such as an attempt to retrieve information from a non-existent table, or to ask for a field that has not been defined for a table. And the logic of applications can often lead to situations that can only be described as errors. What resources do we have to handle these error situations? PHP error handling If nothing else is done, PHP has its own error handler. But developers are free to build their own handlers. So that is the first item on our to do list. Consistently with our generally object oriented approach, the natural thing to do is to build an error recording class, and then to tell PHP that one of its methods is to be called whenever PHP detects an error. Once that is done, the error handler must deal with whatever PHP passes, as it has taken over full responsibility for error handling. It has been a common practice to suppress the lowest levels of PHP error such as notices and warnings, but this is not really a good idea. Even these relatively unimportant messages can reveal more serious problems. It is not difficult to write code to avoid them, so that if a warning or notice does arise, it will indicate something unexpected and therefore worth investigation. For example, the PHP foreach statement expects to work on something iterable and will generate a warning if it is given, say, a null value. But this is easily avoided, either by making sure that methods which return arrays will always return an array, even if it is an array of zero items, rather than a null value. Failing that, the foreach can be protected by a preceding test. So it is safest to assume that a low level error may be a symptom of a bigger problem, and have our error handler record every error that is passed to it. The database is the obvious place to put the error, and the handler receives enough information to make it possible to save only the latest occurrence of the same error, thus avoiding a bloated table of many more or less identical errors. The other important mechanism offered by PHP is new to version 5 and is the try, catch, and throw construct. A section of code can be put within a try and followed by one or more catch specifications that define what is to be done if a particular kind of problem arises. The problems are triggered by using throw. This is a valuable mechanism for errors that need to break the flow of program execution, and is particularly helpful for dealing with database errors. It also has the advantage that the try sections can be nested, so if a large area of code, such as an entire component, is covered by a try it is still possible to write a try of narrower scope within that code. In general, it is better to be cautious about giving information about errors to users. For one thing, ordinary users are simply irritated by technically oriented error messages that mean nothing to them. Equally important is the issue of cracking, and the need to avoid displaying any weaknesses too clearly. It is bad enough that an error has occurred, without giving away details of what is going wrong. So a design assumption for error handling should be that the detail of errors is recorded for later analysis, but that only a very simple indication of the presence of an error is given to the user with a message that it has been noted for rectification. Database errors Errors in database operations are a particular problem for developers. Within the actual database handling code, it would be negligent to ignore the error indications that are available through the PHP interfaces to database systems. Yet within applications, it is hard to know what to do with such errors. SQL is very flexible, and a developer has no reason to expect any errors, so in the nature of things, any error that does arise is unexpected, and therefore difficult to handle. Furthermore, if there have to be several lines of error handling code every time the database is accessed, then the overhead in code size and loss of clarity is considerable. The best solution therefore seems to be to utilize the PHP try, catch, and throw structure. A special database error exception can be created by writing a suitable class, and the database handling code will then deal with an error situation by "throwing" a new error with an exception of that class. The CMS framework can have a default try and catch in place around most of its operation, so that individual applications within the CMS are not obliged to take any action. But if an application developer wants to handle database errors, it is always possible to do so by coding a nested try and catch within the application. One thing that must still be remembered by developers is that SQL easily allows some kinds of error situation to go unnoticed. For example, a DELETE or UPDATE SQL statement will not generate any error if nothing is deleted or updated. It is up to the developer to check how many rows, if any, were affected. This may not be worth doing, but issues of this kind need to be kept in mind when considering how software will work. A good error handling framework makes it easier for a developer to choose between different checking options. Application errors Even without there being a PHP or database error, an application may decide that an error situation has arisen. For some reason, normal processing is impossible, and the user cannot be expected to solve the problem. There are two main choices that will fit with the error handling framework we are considering. One is to use the PHP trigger_error statement. It raises a user error, and allows an error message to be specified. The error that is created will be trapped and passed to the error handler, since we have decided to have our own handler. This mechanism is best used for wholly unexpected errors that nonetheless could arise out of the logic of the application. The other choice is to use a complete try, catch, and throw structure within the application. This is most useful when there are a number of fatal errors that can arise, and are somewhat expected. The CMS extension installer uses this approach to deal with the various possible fatal errors that can occur during an attempt to install an extension. They are mostly related to errors in the XML packaging file, or in problems with accessing the file system. These are errors that need to be reported to help the user in resolving the problem, but they also involve abandoning the installation process. Whenever a situation of this kind arises, try, catch, and throw is a good way to deal with it. Exploring PHP—Error handling PHP provides quite a lot of control over error handling in its configuration. One question to be decided is whether to allow PHP to send any errors to the browser. This is determined by setting the value of display_errors in the php.ini configuration file. It is also possible to determine whether errors will be logged by setting log_errors and to decide where they should be logged by setting error_log. (Often there are several copies of this file, and it is important to find the one that is actually used by the system.) The case against sending errors is that it may give away information useful to crackers. Or it may look bad to users. On the other hand, it makes development and bug fixing harder if errors have to be looked up in a log file rather than being visible on the screen. And if errors are not sent to the screen, then in the event of a fatal error, the user will simply see a blank screen. This is not a good outcome either. Although the general advice is that errors should not be displayed on production systems, I am still rather inclined to show them. It seems to me that an error message, even if it is a technical one that is meaningless to the user, is rather better than a totally blank screen. The information given is only a bare description of the error, with the name and line number for the file having the error. It is unlikely to be a great deal of use to a cracker, especially since the PHP script just terminates on a fatal error, not leaving any clear opportunity for intrusion. You should make your own decision on which approach is preferable. Without any special action in the PHP code, an error will be reported by PHP giving details of where it occurred. Providing our own error handler by using the PHP set_error_handler function gives us far more flexibility to decide what information will be recorded and what will be shown to the user. A limitation on this is that PHP will still immediately terminate on a fatal error, such as attempting a method on something that is not an object. Termination also occurs whenever a parsing error is found, that is to say when the PHP program code is badly formed. It is not possible to have control transferred to a user provided error handler, which is an unfortunate limitation on what can be achieved. However, an error handler can take advantage of knowledge of the framework to capture relevant information. Quite apart from special information on the framework, the handler can make use of the useful PHP debug_backtrace function to find out the route that was followed before the error was reached. This will give information about what called the current code. It can then be used again to find what called that, and so on until no further trace information is available. A trace greatly increases the value of error reporting as it makes it much easier to find out the route that led to the error. When an error is trapped using PHP's try and catch, then it is best to trace the route to the error at the point the exception is thrown. Otherwise, the error trace will only show the chain of events from the exception to the error handler. There are a number of other PHP options that can further refine how errors are handled, but those just described form the primary tool box that we need for building a solid framework.
Read more
  • 0
  • 0
  • 3120

article-image-database-considerations-php-5-cms
Packt
17 Aug 2010
10 min read
Save for later

Database Considerations for PHP 5 CMS

Packt
17 Aug 2010
10 min read
(For more resources on PHP, see here.) The problem Building methods that: Handle common patterns of data manipulation securely and efficiently Help ease the database changes needed as data requirements evolve Provide powerful data objects at low cost Discussion and considerations Relational databases provide an effective and readily available means to store data. Once established, they normally behave consistently and reliably, making them easier to use than file systems. And clearly a database can do much more than a simple file system! Efficiency can quickly become an issue, both in relation to how often requests are made to a database, and how long queries take. One way to offset the cost of database queries is to use a cache at some stage in the processing. Whatever the framework does, a major factor will always be the care developers of extensions take over the design of table structures and software; the construction of SQL can also make a big difference. Examples included here have been assiduously optimized so far as the author is capable, although suggestions for further improvement are always welcome! Web applications are typically much less mature than more traditional data processing systems. This stems from factors such as speed of development and deployment. Also, techniques that are effective for programs that run for a relatively long time do not make sense for the brief processing that is applied to a single website request. For example, although PHP allows persistent database connections, thereby reducing the cost of making a fresh connection for each request, it is generally considered unwise to use this option because it is liable to create large numbers of dormant processes, and slow down database operations excessively. Likewise, prepared statements have advantages for performance and possibly security but are more laborious to implement. So, the advantages are diluted in a situation where a statement cannot be used more than once. Perhaps, even more than performance, security is an issue for web development, and there are well known routes for attacking databases. They need to be carefully blocked. The primary goal of a framework is to make further development easy. Writing web software frequently involves the same patterns of database access, and a framework can help a lot by implementing methods at a higher level than the basic PHP database access functions. In an ideal world, an object-oriented system is developed entirely on the basis of OO principles. But if no attention is paid to how the objects will be stored, problems arise. An object database has obvious appeal, but for a variety of reasons, such databases are not widely used. Web applications have to be pragmatic, and so the aim pursued here is the creation of database designs that occasionally ignore strict relational principles, and objects that are sometimes simpler than idealized designs might suggest. The benefit of making these compromises is that it becomes practical to achieve a useful correspondence between database rows and PHP objects. It is possible that PHP Data Objects (PDO) will become very important in this area, but it is a relatively new development. Use of PDO is likely to pick up gradually as it becomes more commonly found in typical web hosting, and as developers get to understand what it can offer. For the time being, the safest approach seems to be for the framework to provide classes on which effective data objects can be built. A great deal can be achieved using this technique. Database dependency Lest this section create too much disappointment, let me say at the outset that this article does not provide any help with achieving database independence. The best that can be done here is to explain why not, and what can be done to limit dependency. Nowadays, the most popular kind of database employs the relational model. All relational database systems implement the same theoretical principles, and even use more or less the same structured query language. People use products from different vendors for an immense variety of reasons, some better than others. For web development, MySQL is very widely available, although PostgreSQL is another highly regarded database system that is available without cost. There are a number of well-known proprietary systems, and existing databases often contain valuable information, which motivates attempts to link them into CMS implementations. In this situation, there are frequent requests for web software to become database independent. There are, sadly, practical obstacles towards achieving this. It is conceptually simple to provide the mechanics of access to a variety of different database systems, although the work involved is laborious. The result can be cumbersome, too. But the biggest problem is that SQL statements are inclined to vary across different systems. It is easy in theory to assert that only the common core of SQL that works on all database systems should be used. The serious obstacle here is that very few developers are knowledgeable about what comprises the common core. ANSI SQL might be thought to provide a system neutral language, but then not all of ANSI SQL is implemented by every system. So, the fact is that developers become expert in one particular database system, or at best a handful. Skilled developers are conscious of the standardization issue, and where there is a choice, they will prefer to write according to standards. For example, it is better to write: SELECT username, userid, count(userid) AS number FROM aliro_session AS s INNER JOIN aliro_session_data AS d ON s.session_id = d.session_id WHERE isadmin = 0 GROUP BY userid rather than, SELECT username, userid, count(userid) AS number FROM aliro_session AS s, aliro_session_data AS d WHERE s.session_id = d.session_id AND isadmin = 0 GROUP BY userid This is because it makes the nature of the query clearer, and also because it is less vulnerable to detailed syntax variations across database systems. Use of extensions that are only available in some database systems is a major problem for query standardization. Again, it is easy while theorizing to deplore the use of non-standard extensions. In practice, some of them are so tempting that few developers resist them. An older MySQL extension was the REPLACE command, which would either insert or update data depending on whether a matching key was already present in the database. This is now discouraged on the grounds that it achieved its result by deleting any matching data before doing an insertion. This can have adverse effects on linked foreign keys but the newer option of the INSERT ... ON DUPLICATE KEY construction provides a very neat, efficient way to handle the case where data needs to go into the database allowing for what is already there. It is more efficient in every way than trying to read before choosing between INSERT and UPDATE, and also avoids the issue of needing a transaction. Similarly, there is no standard way to obtain a slice of a result set, for example starting with the eleventh item, and comprising the next ten items. Yet this is exactly the operation that is needed to efficiently populate the second page of a list of items, ten per page. The MySQL extension that offers LIMIT and LIMITSTART is ideal for this purpose. Because of these practical issues, independence of database systems remains a desirable goal that is rarely fully achieved. The most practical policy seems to avoid dependencies where this is possible at reasonable cost. The role of the database We already noted that a database can be thought of as uncontrolled global data, assuming the database connection is generally available. So there should be policies on database access to prevent this becoming a liability. One policy adopted by Aliro is to use two distinct databases. The "core" database is reserved for tables that are needed by the basic framework of the CMS. Other tables, including those created by extensions to the CMS framework, use the "general" database. Although it is difficult to enforce restrictions, one policy that is immediately attractive is that the core database should never be accessed by extensions. How data is stored is an implementation matter for the various classes that make up the framework, and a selection of public methods should make up the public interface. Confining access to those public methods that constitute the API for the framework leaves open the possibility of development of the internal mechanisms with little or no change to the API. If the framework does not provide the information needed by extensions, then its API needs further development. The solution should not be direct access to the core database. Much the same applies to the general database, except that it may contain tables that are intended to be part of an API. By and large, extensions should restrict their database operations to their own tables, and provide object methods to implement interfaces across extensions. This is especially so for write operations, but should usually apply to all database operations. Level of database abstraction There have been some clues earlier in this article, but it is worth squarely addressing the question of how far the CMS database classes should go in insulating other classes from the database. All of the discussions here are based on the idea that currently the best available style of development is object oriented. But we have already decided that using a true object database is not usually a practical option for web development. The next option to consider is building a layer to provide an object-relational transformation, so that outside of the database classes, nobody needs to deal with purely relational concepts or with SQL. An example of a framework that does this is Propel, which can be found at http://propel.phpdb.org/trac/. While developments of this kind are interesting and attractive in principle, I am not convinced that they provide an acceptable level of performance and flexibility for current CMS developments. There can be severe overheads on object-relational operations and manual intervention is likely to be necessary if high performance is a goal. For that reason, it seems that for some while yet, CMS developments will be based on more direct use of a relational database. Another complicating factor is the limitations of PHP in respect of static methods, which are obliged to operate within the environment of the class in which they are declared, irrespective of the class that was invoked in the call. This constraint is lifted in PHP 5.3 but at the time of writing, reliance on PHP 5.3 would be premature, software that has not yet found its way into most stable software distributions. With more flexibility in the use of static methods and properties, it would be possible to create a better framework of database-related properties. Given what is currently practical, and given experience of what is actually useful in the development of applications to run within a CMS framework, the realistic goals are as follows: To create a database object that connects, possibly through a choice of different connectors, to a particular database and provides the ability to run SQL queries To enable the creation of objects that correspond to database rows and have the ability to load themselves with data or to store themselves in the database Some operations, such as the update of a single row, are best achieved through the use of a database row object. Others, such as deletion, are often applied to a number of rows, chosen from a list by the user, and are best effected through a SQL query. You can obtain powerful code for achieving the automatic creation of HTML by downloading the full Aliro project. Unfortunately, experience in use has been disappointing. Often, so much customization of the automated code is required that the gains are nullified, and the automation becomes just an overhead. This topic is therefore given little emphasis.
Read more
  • 0
  • 0
  • 1298

article-image-bpel-process-monitoring
Packt
16 Aug 2010
7 min read
Save for later

BPEL Process Monitoring

Packt
16 Aug 2010
7 min read
(For more resources on Oracle, see here.) It is important to understand the complexity of a BPEL process that creates the additional need for active operational monitoring. They are SOA enabled, which means they orchestrate interactions between different systems using a common Web Service Invocation Framework (WSIF). WSIF enables BPEL to build a façade to interact with any system that is Web service enabled. The Web service interactions are called "partner links" in the BPEL framework. This is quite powerful for orchestrating complex business processes that involve new and legacy systems. Grid Control provides means to monitor critical BPEL processes, partner links, and Web services through service tests to determine availability and response time. Grid Control also provides a means of measuring critical metrics for actual requests initiated against each of the Web services deployed on the container. With a combined end-user and request perspective, Grid Control can determine the service availability of all monitored services. Challenges Once BPEL processes are deployed into a staging, preproduction, or a production environment, administrators find it difficult to track the health of these key processes. There is a paucity of tools and operational skills in the BPEL area, so it becomes difficult to understand where to look, and what to look for, when faced with a problem. These processes frequently are the automated representation of critical business functions, and they are required to work as expected. Each process could spawn hundreds or thousands of instances daily. If any process is not performing as expected, in terms of availability or performance, the administrators need to step in and resolve the problem. Administrators are required to fix problems as soon as possible, and typically spend most time triaging the problem to understand potential root causes. Further, in most cases, end users report these problems, whether they are consumers via the Internet or key business partners. If that is the case, the enterprise has already lost revenue or credibility, or both. Solutions Grid Control provides means to monitor critical BPEL processes, partner links, and Web services, through service tests to determine availability and response time. Grid Control also provides a means of measuring critical metrics for actual requests initiated against each of the Web services deployed on the container. Grid Control can determine the service availability of all monitored services by utilizing its active end-user monitoring capabilities. Step-by-step exercises This set of step-by-step exercises will walkthrough the discovery of a BPEL process home page, and setting up monitoring for the process and partner links. Navigating to the BPEL PM target home page Grid Control can monitor several types of targets. The first task is to get to the BPEL PM target home page. All the BPEL-specific monitoring views can be viewed from the target home page. Navigate to the Grid Control home page. In the Target Search region on the right, click on the Search dropdown. Scroll down to locate and click on the BPEL Process Manager target type. Click on the Go button. A list of discovered BPEL Process Manager targets is displayed. Click on the one target name of choice. This takes you to the BPEL PM target home page. If a single BPEL Process Manager target is discovered, the Go button will automatically take you to that target's home page. Navigating to the BPEL process home page The BPEL target home page is mainly an infrastructure view. There is a section within the target home page to view the list of BPEL processes and their monitoring metrics. From the BPEL target home page, click on the Processes tab. All the BPEL processes deployed on the server are discovered and displayed here. Note that the processes are displayed within the domain they are deployed in. Summary throughput process instance information is also displayed in the table. These metrics are gathered by default from the BPEL PM server at a preset polling frequency (collection interval). One can easily change the default polling frequency, as well as set thresholds for these out-of-the-box metrics so that alerts and notifications (with notification rules) can be fired. (Move the mouse over the image to enlarge.) Click on the BPEL process name under the default domain, for example SOAOrderBooking(v1.0). This is the individual BPEL process page. Note the process-specific instance throughput graph. At the bottom, note that all the partner links (at the bottom) for the BPEL process are discovered along with the port type, operation, and WSDL information. Create the BPEL process aggregate service. Note that you need to create the BPEL Infrastructure Service before you attempt to create the BPEL process aggregate service. From the BPEL process page, click on the Create Service button, as shown in the following screenshot: Observe the confirmation message for the aggregate service creation. The aggregate service that was created is listed under the Services section. The previously created infrastructure service has automatically been associated with the aggregate service. In the Services section, starting from the left, you see the service name, type of service, status, and other alerts. The top-level service is the aggregate service. The next service is the infrastructure service—a subservice of the aggregate. Creating a SOAP test to monitor a partner link A synthetic transaction is a proactive way to emulate end user (or client) behavior and catch problems before the end user (or client). A BPEL process typically invokes one or more web services through a partner link framework, usually via SOAP. A synthetic check for testing the BPEL partner link availability and performance is a great way to uncover problems before the service consumers do. Scroll down and select a partner link name from the radio button list, for instance, SelectService. Click on the Add SOAP Test button to create a SOAP test for that partner link. Enter the SOAP Test Name as SelectService_test. Enter the test interval for the Collection Frequency (minutes) as 15. Select Web service port from the Port Types drop-down list as SelectServiceCallbackPort. Enter input parameters in the HTML input fields, for example, SupplierPrice {String} as 12345 and SupplierName {String} as 2. Leave the Basic Authentication Credentials section empty. Click on OK to continue after the fields on the Create SOAP Test page are filled as shown in the following screenshot: Add a beacon. Click on the Add button. From the pop-up window, check and select the available beacon(s), shown in the next screenshot: Beacons are agents that have been configured to issue synthetic tests to test websites, Web services, mail servers, FTP sites, and so on. A beacon is typically installed outside the firewall from a location where users access the website or Web service. A beacon thus "emulates" end user behavior and informs the administrator proactively about any problem with the website or Web service. You can read more about beacons and service management in the Grid Control documentation on the Oracle Technology Network—http://otn.oracle.com. Click on OK to save the SOAP test and beacon settings. Verify availability process creation and view SOAP test. On the BPEL process home page, note the availability Generic Service that was automatically created. Expand the process availability service. For example, SOAOrderBooking(v1.0)_availability and verify that the SOAP test that you just created, for example SelectService_test, has been added. The availability service for the BPEL process is formed when the first SOAP test is created. Note the status of each test, and how it is rolled up (confi gurable) to determine process availability. The status of the SOAP test will take some time to show up, based on the frequency set for the test.
Read more
  • 0
  • 0
  • 1239
article-image-flash-multiplayer-virtual-world-smartfoxserver-using-embedded-web-server-and-database
Packt
16 Aug 2010
4 min read
Save for later

Flash Multiplayer Virtual World with SmartFoxServer Using Embedded Web Server and Database

Packt
16 Aug 2010
4 min read
(For more resources on Flash, see here.) Unlike a deployment environment, it is common to have just once machine acting both as server and client in a development environment. The machine will have SmartFoxServer, web server, and database installed. In this case, there are no noticeable differences between using the embedded or third-party web server and database. It is a good habit to simulate the deployment environment as much as possible in development stage. As we are going to use a third-party web server and database, we will set up a development environment that also uses the third-party server instead of the embedded web server and database in the third part of this article series. Installing Java Development Kit The Java Development Kit includes the essential development tools (JDK) and the Java Runtime Environment (JRE). The development tool compiles the Java source code into byte codes and the JRE is the response to execute the byte codes. We will need several Java compilations in later chapters. SmartFoxServer is build on the Java environment and we need the JRE to start up the server. The JDK and JRE may be pre-installed in some OSs. Installing JDK On Windows The steps for installing JDK on Windows are as follows: Go to http://java.sun.com/javase/downloads/. Click on the Download button of Java. It will lead to the Java SE Downloads page. Select Windows (or Windows x64 for 64-bits Windows) in Platform. Click on Download. If it prompts an optional login request, we can click the Skip this Step to bypass it. Launch the installer after the download. Install the Java Development Kit with all default settings. The Java environment is ready after installation completes. Installing JDK on Mac OSX The Mac OSX comes with its own set of Java environment. We can check the JDK and JRE version by following steps: Launch terminal from Applications | Utilities | Terminal. Type the following and press the Enter key: javac -version The command will output the currently installed version of the Java in the Mac OSX. In my case, it outputs: javac 1.6.0_17. The current version of SmartFoxServer at the time of writing recommends the version 1.6. If the Java is not updated, we can update it via Apple Menu | Software Update. The software update will check for any updates for your existing Mac software, including the Java environment. Installing JDK on Linux We can use the general method to download and install the JDK or use the system specific method to install the package. We will show the general method and the Ubuntu method. Installing for General Linux Go to http://java.sun.com/javase/downloads/index.jsp in browser. Click on the Download button. The platform Linux should be selected automatically. Otherwise, select Linux (or Linux x64 for 64-bit Linux). Click on Continue. If it prompts for login, click on Skip this Step to bypass it. For Redhat or Fedora Linux, choose the rpm-bin file to download. For other Linux, choose the .bin file to download. Launch terminal via Applications | Accessories | Terminal after the download completes. Change the directory to the folder that contains the downloaded package. The download destination varies from different profile settings. In my case, it is in Downloads folder. cd ~/Downloads/ The version is Java 6 Update 20 at the time of writing and the filename is jdk-6u20-linux-i586.bin or jdk-6u20-linux-i586-rpm.bin. Then we make it executable and launch the installer by the following commands: chmod a+x jdk-6u20-linux-i586.bin./jdk-6u20-linux-i586.bin The installer displays the license agreement. Type Yes at the end to agree and continue installation. Press the Enter key after the file’s extraction to end the installation. Installing for Ubuntu Linux Ubuntu users can install the JDK via the apt-get command. We will search for the latest package name of the JDK by the following command: apt-cache search --names-only sun-java.*-jdk The result shows the available JDK packet names. At the time of writing, it is JDK6: sun-java6-jdk - Sun Java(TM) Development Kit (JDK) 6 We use the apt-get command to install the JDK: sudo apt-get install sun-java6-jdk Type in the user password because it requires user’s password and the privilege to use apt-get.
Read more
  • 0
  • 0
  • 3987

article-image-developing-and-deploying-virtual-world-environment-flash-multiplayer
Packt
16 Aug 2010
7 min read
Save for later

Developing and Deploying Virtual World Environment for Flash Multiplayer

Packt
16 Aug 2010
7 min read
(For more resources on Flash, see here.) Comparing SmartFoxServer Lite, Basic, and Pro SmartFoxServer is a commercial product by gotoAndPlay(). There are three package options of SmartFoxServer. They are Lite version, Basic version, and Pro version. The demo license of the SmartFoxServer provides full features with 20 concurrent users maximum without time limitation. We will use the demo license to build the entire virtual world throughout the article. SmartFoxServer Lite The Lite version was the original SmartFoxServer since 2004. The maximum concurrent connection is limited to 50. It supports some core features like message passing, server-side user/room variables, and dynamic room creation. However, the lack of ActionScript 3.0greatly limits the performance and functionality. Moreover, it is being updated slowly so that many new features from Basic and Pro version are missing in Lite version. When we compare the version number of the three options, we will know that Lite version is developing at a slow pace. The version of SmartFoxServer Pro is 1.6.6 at the time of writing. The Basic version is 1.5.9 and the Lite version is only 0.9.1. Because of the slow update, not supporting ActionScript 3 and lack of features, it is not recommended to use Lite version in production. SmartFoxServer Basic SmartFoxServer Basic supports ActionScript 3 and a bunch of advanced features such as administration panel, game room spectators, and moderators. The administration panel lets moderators configure the zones, rooms, and users when the server is running. However, the lack of server-side extension support limits the customizability of the socket server. It also means that all logic must reside on the client side. This raises a security issue that the client may alter the logic to cheat. The Basic version provides enough features to build a Flash virtual world in small scale that does not require high security. If you need a specific server logic and room management or want to put logic in server side to prevent client-side cheating, Pro version is the choice. SmartFoxServer Pro There is a long list of features that are supported in Pro version. There are three features amongst all that distinguish the Pro version, they are: Server-side extension that modifies the server behavior JSON/Raw data protocol message passing Direct database connection Modifying the behavior of server Server-side extension is some server logic that developers can program to modify the default behavior of the internal event handler and add server-side functions to extend the server for specific usage. For example, we may want to override the "user lost" event so that we can save the user properties, telling others that someone is disconnected and something else. In this case, we can write a function in server-side extension to handle all these things when the user lost, instead of running the default behavior that was provided by SmartFoxServer. The SmartFoxServer is written in Java. Therefore the native support language of server-side extension is Java. In order to reduce the development difficulties, SmartFoxServer supports Python and ActionScript as a server-side extension. The support of ActionScript makes it much more convenient for most Flash developers to develop the server-side extension without even knowing Java. Please note that the version of ActionScript supported in server-side extension is ActionScript 1, instead of ActionScript 3. Take a look at the following code snippet on a server-side extension. The functions in server-side extensions are often similar to this one. It comes with arguments to know which user is calling this command at which room. In this snippet there is a command called getSomething and it will use the provided command parameters to get the result and return the result to the corresponding user. function handleRequest(cmd, params, user, fromRoom){ var response = {}; switch (cmd) { case "getSomething": var cpu = params['cpuType’]; response.something = "A Powerful Computer with CPU "+cpu; // send the response back to the client. _server.sendResponse(response,-1,null,[user]); break }} JSON/Raw data protocol JSON (http://www.json.org) is a light-weight text-based data-interchange format. It is designed for both humans and machines to read and write the data easily. For example, we can format a list of users and their information with the following JSON code. {"users": [ { "name" : "Steve", "level" : 12, "position" : { "x" : 6, "y" : 7 }, { "name" : "John", "level" : 5, "position" : { "x" : 26, "y" : 12 }} The default data protocol supported by SmartFoxServer Lite and Basic is XML. The Pro version added support of JSON and raw data protocol make it possible to compress the transfer of data between clients and server. The length of messages between clients and server is much shorter and it means the transmission speed is much faster. Take an example of a client sending data to a server with different protocols. We are now trying to fetch some data from the server, and this is what it looks like when sending a command to the server via different protocol. XML: <dataObj><var n=’name’ t=’s’>extension</var><var n=’cmd’t=’s’>getSomething</var><obj t=’o’ o=’param’><var n=’cpuType’t=’n’>8</var></obj></dataObj> The length of this command is 148 bytes. JSON: {"b":{"p":{"cpuType":8},"r":1,"c":"getSomething","x":"extension"},"t":"xt"} The length of this command is 75 bytes. Raw Data: %xt%extension%getSomething%8% The length of this command is 29 bytes. When comparing with the bytes used to send a command over the network, XML is two times the JSON and five times the raw protocol. We are talking about several byte differences that may not be considered in a broadband Internet. However, it is a must to consider every byte that was sent to the network because we are not talking about 29 bytes versus 148 bytes in the real applications. Imagine there are 2000 players in the virtual world, sending similar commands every second. We are now talking about 2.4Mbit/s versus 500Kbit/s, and this rough statistic already ignores those commands that fetch a long list of results, for example, a long list of items that are owned by the player. The raw protocol format takes less bytes to represent the command because it does not contain the field name of the data. All parameters are position-dependent. In the preceding command, the first parameter stands for an extension message and the second stands for the command name. Other command-specific parameters follow these two parameters. Raw protocol is position-dependent on the passing parameters while JSON is not. It is recommended to use JSON protocol in most case and use the raw data protocol in real-time interaction parts. Also, we should state clearly in comments code what each parameters stands for because others cannot get the field information from the raw data. Accessing the database directly Flash does not provide any database access functions. Flash applications always connect to database via server-side technique. The Pro version of SmartFoxServer provides direct database connectivity in server-side extension. The Flash virtual world will call a function in sever-side extension and it will handle the database connection for the Flash. As the database connectivity is handled in server-side extension, Basic and Lite version does not contain this handy feature. We have to wrap the database access in other server-side technique, such as PHP, to connect database in Basic and Lite version. The two graphs compare the architecture of the database access in SmartFoxServer Pro, Basic, and Lite.
Read more
  • 0
  • 0
  • 3634

article-image-ordering-buildings-flash-virtual-worlds
Packt
16 Aug 2010
2 min read
Save for later

Ordering the Buildings in Flash Virtual Worlds

Packt
16 Aug 2010
2 min read
(For more resources on Flash, see here.) Ordering the buildings The buildings are not well placed on the map. They overlap with each other in a very strange way. That is because we are now viewing the 3D isometric world in 2D screen with wrong ordering. When we view the 3D perspective in the following way, the closer objects should block the view of the objects behind. The buildings in the preceding image do not obey this real-world rule and cause some strange overlapping. We are going to solve this problem in the next section. Ordering the movie clips in Flash In Flash, every movie clip has its own depth. The depth is called z-order or the z-index of the movie clip. A movie clip with bigger z-order number is higher and covers the others with lower z-order when overlapping. By swapping their z-order, we can rearrange the movie clips on how they overlap and create the correct ordering of isometric buildings. Determining an object's location and view According to our tile-based isometric map, the object that locates in larger number of the x and y axis is in front of the object that locates in smaller number of the x and y axis. We can thus compare the isometric x and y coordinate to determine which object is in front. There is a special case when all shapes of the buildings occupy square shapes. In this situation, the order of the movie clip's z order can be easily determined by comparing their y position.
Read more
  • 0
  • 0
  • 5437
Packt
16 Aug 2010
12 min read
Save for later

URL Shorteners – Designing the TinyURL Clone with Ruby

Packt
16 Aug 2010
12 min read
(For more resources on Ruby, see here.) We start off with an easy application, a simple yet very useful Internet application, URL shorteners. We will take a quick tour of URL shorteners before jumping into the design of a simple URL shortener, followed by an in-depth discussion of how we clone our own URL shortener, Tinyclone. All about URL shorteners Internet applications don't always need to be full of features or cover all aspects of your Internet life to be successful. Sometimes it's ok to be simple and just focus on providing a single feature. It doesn't even need to be earth-shatteringly important—it should be just useful enough for its target users. The archetypical and probably most extreme example of this is the URL shortening application or URL shortener. This service offers a very simple but surprisingly useful feature. It provides a shorter URL that represents a normally longer URL. When a user goes to the short URL, he will be redirected to the original URL. For this simple feature, top three most popular URL shortening services (TinyURL, bit.ly, and is.gd) collectively had about 11 million unique visitors, 110 million page views and a reach of about one percent of the Internet in June 2009. In 2008, the most popular URL shortener at that time, TinyURL, was made one of Time Magazine's Top 50 Best Websites. The idea to shorten long and unwieldy URLs into shorter, more manageable ones has been around for some time. One of the earlier attempts to make it a public service is Make A Shorter Link (MASL), which appeared around July 2001. MASL did just that, though the usefulness was debatable as the domain name was long and the shortened URL could potentially be longer than the original. However, the pioneering site that popularized this concept (and subsequently bought over MASL and a few other similar sites) is TinyURL. TinyURL was launched in January 2002 by Kevin Gilbertson to help him to link directly to newsgroup postings which frequently had long URLs. It rapidly became one of the most popular URL shorteners around. In 2008, an estimated 100 similar services came to existence in various forms. URLs or Uniform Resource Locators are resource identifiers that specify where identified resources are available and how they can be retrieved. A popular term for URL is a Web address. Every URL is made up of the following: <resource type>://<username>:<password>@<domain>:<port>/<file path name>?<query string>#<anchor> Not all parts of the URL are required by a browser, if the resource type is missing, it is normally assumed to be http, if the port is missing, it is normally assumed to be 80 (for http). The username, password, query string and anchor components are optional. Initially, TinyURL and similar types of URL shorteners focused on simply providing a short representative URL to their users. Naturally the competitive breadth for shortening URLs was rather well, short. Many chose TinyURL over MASL because TinyURL had a shorter and easier to remember domain name (http://tinyurl.com over http://makeashorterlink.com) Subsequent competition over this space intensified and extended to providing various other features, including custom short URLs (TinyURL, bit.ly), analysis of click-through statistics (bit.ly), advertisements (Adjix, Linkbee), preview pages (TinyURL, is.gd) and so on. The explosive growth of Twitter (from June 2008 to June 2009, Twitter grew 1,164%) opened a new chapter for URL shorteners. Twitter chose a limit of 140 characters for each tweet to accommodate the 160 characters in an SMS message (Twitter was invented as a service for people to use SMS to tell small groups what they are doing). With Twitter's popularity skyrocketing, came the need for users to shorten URLs to fit into the 140 characters limit. Originally Twitter used TinyURL as its default URL shortener and this triggered a steep climb in the usage of TinyURL during the early days of Twitter. However, in May 2009, bit.ly replaced TinyURL as Twitter's default URL shortener and the impact was immediate. For the first time in that period, TinyURL recorded a drop in the number of users in May 2009, dropping from 6.1 million to 5.3 million unique users, while bit.ly jumped from 1.8 million to 2.9 million almost overnight. That's not the end of the story though. In April 2010 during Twitter's Chirp conference, Twitter announced its own URL shortener (twt.tl). As of writing it is still unclear the market share will pan out but it's clear that URL shorteners have good value and everyone is jumping into this market. In December 2009, Google came up with its own two URL shorteners goo.gl and youtu.be. Amazon.com (amzn.to), Facebook (fb.me) and Wordpress (wp.me) all have their own URL shorteners as well. Next, let's do a quick review of why URLs shorteners are so popular and why they attract criticism as well. Here's a quick summary of the benefits: Create short and easy to remember URLs Allow passing of links in character-limited services such as Twitter Create vanity URLs for marketing purposes Can verbally pass URLs The most obvious benefit of having a shortened URL is that it's, well, short. A typical example of an URL gone bad is a link to a location in Google Maps: http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=singapore +flyer&vps=1&jsv=169c&sll=1.352083,103.819836&sspn=0.68645,1.382904&g =singapore&ie=UTF8&latlng=8354962237652576151&ei=Shh3SsSRDpb4vAPsxLS3 BQ&cd=1&usq=Singapore+Flyer Such URLs are meant to be clicked on as it is virtually impossible to pass it around verbally. It might be justifiable if the URL is cut and pasted on documents, but sometimes certain applications will truncate parts of the URL while processing. This makes a long URL difficult to click on and even produces erroneous links. In fact, this was the main motivation in creating most of the earlier URL shorteners—older email clients tend to truncate URLs when they are more than 80 characters. Short links are of course crucial in character-limited message passing systems like Twitter, Plurk, and SMS. Passing long URLs is impossible without URL shorteners. Short URLs are very useful in cases of vanity URLs where for example, the Google Maps link above could be shortened to http://tinyurl.com/singapore-flyer. Such vanity URLs are useful when passing from one person to another, or even when using in a mass marketing way. Sticking to the maps theme in our examples, if you want to give a Google Maps link to your restaurant and put it up in catalogs and brochures, you will not want to give the long URL. Instead you would want a nice, descriptive and short URL. Short URLs are also useful in cases of accessibility. For example, reading out the Google Maps link above is almost impossible, but reading out the TinyURL link (vanity or otherwise) is much easier in comparison. Many popular URL shorteners also provide some form of statistics and analytics on the usage of the links. This feature allows you to track your short URLs to see how many clicks it received and what kind of patterns can be derived from the clicks. Although the metrics are usually not advanced, they do provide basic usefulness. On the other hand, URL shorteners have it fair share of criticisms as well. Here is a summary of the bad side of URL shorteners: Provides opportunity to spammers because it hide original URLs Could be unreliable if dependent on it for redirection Possible undesirable or vulgar short URLs URL shorteners have security issues. When a URL shortener creates a short URL, it effectively hides the original link and this provides opportunity for spammers or other abusers to redirect users to their sites. One relatively mild form of such attack is 'rickrolling'. Rickrolling uses a classic bait-and-switch trick to redirect users to a Rick Astley music video of Never Gonna Give You Up. For example, you might feel that the URL http://tinyurl.com/singapore-flyer goes to Google Map, but when you click on it, you might be rickrolled and redirected to that Rick Astley music video instead. Also, because most short URLs are not customized, it is quite difficult to see if the link is genuine or not just from the URL. Many prominent websites and applications have such concerns, including MySpace, Flickr and even Microsoft Live Messenger, and have one time or another banned or restricted usage of TinyURL because of this problem. To combat spammers and fraud, URL shortening services have come up with the idea of link previews, which allows users to preview a short URL before it redirects the user to the long URL. For example TinyURL will show the user the long URL on a preview page and requires the user to explicitly go to the long URL. Another problem is performance and reliability. When you access a website, your browser goes to a few DNS servers to resolve the address, but the URL shortener adds another layer of indirection. While DNS servers have redundancy and failsafe measures, there is no such assurance from URL shorteners. If the traffic to a particular link becomes too high, will the shortening service provider be able to add more servers to improve performance or even prevent a meltdown altogether? The problem of course lies in over-dependency on the shortening service. Finally, a negative side effect of random or even customized short URLs is that undesirable, vulgar or embarrassing short URLs can be created. Earlier on TinyURL short URLs were predictable and it was exploited, such as embarrassing short URLs that were made to redirect to the White House websites of then U.S. Vice President Dick Cheney and Second Lady Lynne Cheney. We have just covered significant ground on URL shorteners. If you are a programmer you might be wondering, "Why do I need to know such information? I am really interested in the programming bits, the others are just fluff to me." Background information on the application we want to clone is very important. It tells us what why that application exists in the first place and gives us an idea what are the main features (what makes it popular). It also tells us what problems it faces such that we are aware of the problem while programming it, or even avoid it altogether. This is important when we come to the design of the application. Finally it gives us better appreciation of the application and the motivations and issues faced by the product and technical people behind the application we wish to clone. Main features Next, let's list down the features of a URL shortener. The intention in this section is to distill the basic features of the application, features that define the service. Features listed here will be features that make the application what it is. However, as much as possible we want to also explore some additional features that extend the application and are provided by many of its competitors. Most importantly, the features here are mostly features of the most popular and definitive web application in the category. In this article, this will be TinyURL. These are the main features of a URL shortener: Users can create a short URL that represents a long URL Users who visit the short URL will be redirected to the long URL Users can preview a short URL to enable them to see what the long URL is Users can provide a custom URL to represent the long URL Undesirable words are not allowed in the short URL Users are able to view various statistics involving the short URL, including the number of clicks and where the clicks come from (optional, not in TinyURL) URL shorteners are simple web applications and the one that we will design and build will also be simple. Designing the clone Cloning TinyURL is relatively simple but there is some thought behind the design of the application. We will be building a clone of TinyURL called Tinyclone, which will be hosted at the domain http://tinyclone.saush.com. Creating a short URL for each long URL The domain of the short URL is fixed. What's left is the file path name. We need to represent the long URL with a unique file path name (a key), one for each long URL. This means we need to persist the relationship between the key and the URL. One of the ways we can associate the long URL with a unique key is to hash the long URL and use the resulting hash as the unique key. However, the resulting hash might be long and hashing functions could be slow. The faster and easier way is to use a relational database's auto-incremented row ID as the unique key. The database will help ensure the uniqueness of the ID. However, the running row ID number is base 10. To represent a million URLs would already require 7 characters, to represent 1 billion would take up 9 characters. In order to keep the number of characters smaller, we will need a larger base numbering system. In this clone we will use base 36, which is 26 characters of the alphabet (case insensitive) and 10 numbers. Using this system, we will only need 5 characters to represent 1 million URLs: 1,000,000 base 36 = lfls And 1 billion URLs can be represented in just six characters: 1,000,000,000 base 36 = gjdgxs
Read more
  • 0
  • 1
  • 12828

article-image-q-replication-components-ibm-replication-server
Packt
16 Aug 2010
8 min read
Save for later

Q Replication Components in IBM Replication Server

Packt
16 Aug 2010
8 min read
The individual stages for the different layers are shown in the following diagram: The DB2 database layer The first layer is the DB2 database layer, which involves the following tasks: For unidirectional replication and all replication scenarios that use unidirectional replication as the base, we need to enable the source database for archive logging (but not the target table). For multi-directional replication, all the source and target databases need to be enabled for archive logging. We need to identify which tables we want to replicate. One of the steps is to set the DATA CAPTURE CHANGES flag for each source table, which will be done automatically when the Q subscription is created. This setting of the flag will affect the minimum point in time recovery value for the table space containing the table, which should be carefully noted if table space recoveries are performed. Before moving on to the WebSphere MQ layer, let’s quickly look at the compatibility requirements for the database name, the table name, and the column names. We will also discuss whether or not we need unique indexes on the source and target tables. Database/table/column name compatibility In Q replication, the source and target database names and table names do not have to match on all systems. The database name is specified when the control tables are created. The source and target table names are specified in the Q subscription definition. Now let’s move on to looking at whether or not we need unique indexes on the source and target tables. We do not need to be able to identify unique rows on the source table, but we do need to be able to do this on the target table. Therefore, the target table should have one of: Primary key Unique contraint Unique index If none of these exist, then Q Apply will apply the updates using all columns. However, the source table must have the same constraints as the target table, so any constraints that exist at the target must also exist at the source, which is shown in the following diagram: The WebSphere MQ layer This is the second layer we should install and test—if this layer does not work then Q replication will not work! We can either install the WebSphere MQ Server code or the WebSphere MQ Client code. Throughout this book, we will be working with the WebSphere MQ Server code. If we are replicating between two servers, then we need to install WebSphere MQ Server on both servers. If we are installing WebSphere MQ Server on UNIX, then during the installation process a user ID and group called mqm are created. If we as a DBA want to issue MQ commands, then we need to get our user ID added to the mqm group. Assuming that WebSphere MQ Server has been successfully installed, we now need to create the Queue Managers and the queues that are needed for Q replication. This section also includes tests that we can perform to check that the MQ installation and setup is correct. The following diagram shows the MQ objects that need to be created for unidirectional replication: The following figure shows the MQ objects that need to be created for bidirectional replication: There is a mixture of Local Queue (LOCAL/QL) and Remote Queues (QREMOTE/QR) in addition to Transmission Queues (XMITQ) and channels. Once we have successfully completed the installation and testing of WebSphere MQ, we can move on to the next layer—the Q replication layer. The Q replication layer This is the third and final layer, which comprises the following steps: Create the replication control tables on the source and target servers. Create the transport definitions. What we mean by this is that we somehow need to tell Q replication what the source and target table names are, what rows/columns we want to replicate, and which Queue Managers and queues to use. Some of the terms that are covered in this section are: Logical table Replication Queue Map Q subscription Subscription group (SUBGROUP) What is a logical table? In Q replication, we have the concept of a logical table, which is the term used to refer to both the source and target tables in one statement. An example in a peer-to-peer three-way scenario is shown in the following diagram, where the logical table is made up of tables TABA, TABB, and TABC: What is a Replication/Publication Queue Map? The first part of the transport definitions mentioned earlier is a definition of Queue Map, which identifies the WebSphere MQ queues on both servers that are used to communicate between the servers. In Q replication, the Queue Map is called a Replication Queue Map, and in Event Publishing the Queue Map is called a Publication Queue Map. Let’s first look at Replication Queue Maps (RQMs). RQMs are used by Q Capture and Q Apply to communicate. This communication is Q Capture sending Q Apply rows to apply and Q Apply sending administration messages back to Q Capture. Each RQM is made up of three queues: a queue on the local server called the Send Queue (SENDQ), and two queues on the remote server—a Receive Queue (RECVQ) and an Administration Queue (ADMINQ), as shown in the preceding figures showing the different queues. An RQM can only contain one each of SENDQ, RECVQ, and ADMINQ. The SENDQ is the queue that Q Capture uses to send source data and informational messages. The RECVQ is the queue that Q Apply reads for transactions to apply to the target table(s). The ADMINQ is the queue that Q Apply uses to send control messages back to Q Capture. So using the queues in the first “Queues” figure, the Replication Queue Map definition would be: Send Queue (SENDQ): CAPA.TO.APPB.SENDQ.REMOTE on Source Receive Queue (RECVQ): CAPA.TO.APPB.RECVQ on Target Administration Queue (ADMINQ): CAPA.ADMINQ.REMOTE on Target Now let’s look at Publication Queue Maps (PQMs). PQMs are used in Event Publishing and are similar to RQMs, in that they define the WebSphere MQ queues needed to transmit messages between two servers. The big difference is that because in Event Publishing, we do not have a Q Apply component, the definition of a PQM is made up of only a Send Queue. What is a Q subscription? The second part of the transport definitions is a definition called a Q subscription, which defines a single source/target combination and which Replication Queue Map to use for this combination. We set up one Q subscription for each source/target combination. Each Q subscription needs a Replication Queue Map, so we need to make sure we have one defined before trying to create a Q subscription. Note that if we are using the Replication Center, then we can choose to create a Q subscription even though a RQM does not exist. The wizard will walk you through creating the RQM at the point at which it is needed. The structure of a Q subscription is made up of a source and target section, and we have to specify: The Replication Queue Map The source and target table The type of target table The type of conflict detection and action to be used The type of initial load, if any, should be performed If we define a Q subscription for unidirectional replication, then we can choose the name of the Q subscription—for any other type of replication we cannot. Q replication does not have the concept of a subscription set as there is in SQL Replication, where the subscription set holds all the tables which are related using referential integrity. In Q replication, we have to ensure that all the tables that are related through referential integrity use the same Replication Queue Map, which will enable Q Apply to apply the changes to the target tables in the correct sequence. In the following diagram, Q subscription 1 uses RQM1, Q subscription 2 also uses RQM1, and Q subscription 3 uses RQM3: What is a subscription group? A subscription group is the name for a collection of Q subscriptions that are involved in multi-directional replication, and is set using the SET SUBGROUP command. Q subscription activation In unidirectional, bidirectional, and peer-to-peer two-way replication, when Q Capture and Q Apply start, then the Q subscription can be automatically activated (if that option was specified). For peer-to-peer three-way replication and higher, when Q Capture and Q Apply are started, only a subset of the Q subscriptions of the subscription group starts automatically, so we need to manually start the remaining Q subscriptions.
Read more
  • 0
  • 0
  • 3620
Modal Close icon
Modal Close icon