Monday, October 19, 2009

Chapter 5. Design in Construction










 < Free Open Study > 







Chapter 5. Design in Construction



cc2e.com/0578



Contents



  • Design Challenges page 74

  • Key Design Concepts page 77

  • Design Building Blocks: Heuristics page 87

  • Design Practices page 110

  • Comments on Popular Methodologies page 118



Related Topics



  • Software architecture: Section 3.5

  • Working classes: Chapter 6

  • Characteristics of high-quality routines: Chapter 7

  • Defensive programming: Chapter 8

  • Refactoring: Chapter 24

  • How program size affects construction: Chapter 27



Some people might argue that design isn't really a construction activity, but on small projects, many activities are thought of as construction, often including design. On some larger projects, a formal architecture might address only the system-level issues and much design work might intentionally be left for construction. On other large projects, the design might be intended to be detailed enough for coding to be fairly mechanical, but design is rarely that complete�the programmer usually designs part of the program, officially or otherwise.



On small, informal projects, a lot of design is done while the programmer sits at the keyboard. "Design" might be just writing a class interface in pseudocode before writing the details. It might be drawing diagrams of a few class relationships before coding them. It might be asking another programmer which design pattern seems like a better choice. Regardless of how it's done, small projects benefit from careful design just as larger projects do, and recognizing design as an explicit activity maximizes the benefit you will receive from it.



Cross-Reference





For details on the different levels of formality required on large and small projects, see Chapter 27, "How Program Size Affects Construction."




Design is a huge topic, so only a few aspects of it are considered in this chapter. A large part of good class or routine design is determined by the system architecture, so be sure that the architecture prerequisite discussed in Section 3.5 has been satisfied. Even more design work is done at the level of individual classes and routines, described in Chapter 6, "Working Classes," and Chapter 7, "High-Quality Routines."



If you're already familiar with software design topics, you might want to just hit the highlights in the sections about design challenges in Section 5.1 and key heuristics in Section 5.3.














     < Free Open Study > 



    mod_jk





























    Chapter 13 -
    The AJP Connector
    byVivek Chopra, Ben Galbraithet al.
    Wrox Press 2003































    mod_jk


    As we saw in Chapter 11, to integrate Tomcat with a web server we need a redirector module that will forward client requests for JSP pages and servlets from the web server to Tomcat. This is done by matching the URL pattern of the request to a mapping in a configuration file. The JSP pages/servlets then handle the forwarded request, generate an appropriate dynamic response and send it back to the client via the module. To address this requirement, Apache's Jakarta project provides a module called mod_jk.



    The following schematic diagram indicates the role of mod_jk in the combination of Tomcat and Apache. Here we see that Apache, with the help of mod_jk, redirects all requests for any JSP/servlet components. There may be one or more running instances of Tomcat that will serve these client requests. The redirector usually comes as a DLL or shared object module (.dll for Windows and .so file for Unix/Linux) that plugs into the web server, so Tomcat is said to be a plug-in for Apache:







    If you've previously configured Apache to use mod_jserv, remove any ApJServMount directives from your httpd.conf file. If you're including tomcat-apache.conf or tomcat.conf, you'll want to remove them as well as they are specific to mod_jserv. These steps are necessary because the mod_jserv configuration directives are not compatible with mod_jk.





    The Apache JServ Protocol


    The Apache JServ Protocol (AJP) is a packet-oriented, TCP/IP-based protocol. It provides a communication channel between the Apache web server process and the running instances of Tomcat. Various versions of this protocol are available, including versions 1.2, 1.3, and 1.4. As AJP 1.3 is the most commonly used and well-tested version, we'll use it for our discussion here. Some of the noticeable features of AJP 1.3) are:




    • Good performance




    • Support for SSL




    • The facility to get information about encryption and client certificates




    AJP increases performance by making the web server reuse already open TCP-level connections with the Tomcat container, and as such, saves the overhead of opening new socket connections for each request. This is a concept similar to that of a connection pool. In the request-response cycle (completion of a request by getting a response corresponding to it), when a connection gets assigned to a particular request, it will not be reused until that request-response cycle is completed. This makes things simple by avoiding the cost of some more opened connections.






    The AJP Connector


    Tomcat provides a connector that implements the AJP protocol. Most versions of Tomcat support multiple versions of AJP (for example, Tomcat 3.x supports 1.2 and 1.3 whereas Tomcat 4.1.x supports 1.3 and 1.4) and for each AJP version, a connector Java class is provided in the Tomcat installation. Such a class is called an AJP connector.



    It is easy to find out which class is providing support for which version of AJP because the class name itself contains the AJP version. For example, in Tomcat 4.0, we'll find a class called org.apache.ajp.tomcat4.Ajp13Connector, which will support AJP version 1.3. Similarly, for AJP version 1.4, Tomcat provides a class named org.apache.ajp.tomcat4.Ajp14Connector. This AJP connector can be configured in the server.xml file of Tomcat. We'll soon cover how to define the AJP connectors.



    The New mod_jk2


    We have already seen how Tomcat 4.0 provides an AJP connector for coupling Tomcat with a web server like Apache. In Tomcat 4.1.x, a new type of connector called JK2 has been introduced. The functional objective of this connector is the same as that of the original AJP connector, that is, to support the coupling of Tomcat with a web server like Apache. However, it is modified and improved to support the new architecture of Tomcat 4.1.x. This new type of connector supports AJP versions 1.3 and 1.4. Tomcat 4.1.x provides an implementation of this connector as the Coyote connector.


    As we know, mod_jk is the module that provides the bridge between Tomcat and Apache. JK2 is the next generation and the corresponding module for Apache is available as mod_jk2.








    Worker Implementations with mod_jk


    A worker is a Tomcat instance that is running to serve JSP/servlet requests coming from another web server. In most cases, there is only a single Tomcat process, but sometimes we will need to run multiple workers to implement load balancing or site partitioning (mainly required for sites with heavy traffic). We'll see how to achieve this in the Tomcat Load Balancing with Apache section.


    Each worker is identified by a host name/IP and port number combination. Here host means the machine name on which the given Tomcat instance is running and port refers to the port on which that instance is listening for any requests.






    Plug-In vs. In-Process


    Worker implementation in Tomcat with a web server can be done in two ways:





    • Using Tomcat as a plug-in


      The most common implementation of Tomcat with Apache is using the Tomcat process as a plug-in to the running web server process. In this case, mod_jk is required as a redirector component. We'll need to configure the web server plug-in so that it can look up the different Tomcat workers and forward requests to them.





    • Using Tomcat as an in-process worker


      This is a special type of worker implementation. In this case, the web server opens a JVM in its own process and executes Tomcat. Here Tomcat shares the same address space as that of the server process. This is a special type of deployment that provides an advantage in terms of request processing speed and better use of resources. We are not going to cover in-process workers in this chapter because, although Tomcat 3.x supports them, Tomcat 4.x doesn't and there are no plans to implement them in the future.









    Multiple Tomcat Workers


    There are a number of situations where we may use a multiple worker setup:




    • We may want different contexts to be served by different Tomcat workers. This setup will provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.




    • We may want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different entities.




    • We may want to provide load balancing, where we run multiple Tomcat workers each on a machine of its own (or maybe on the same machine) and distribute the requests between them.








    Getting mod_jk


    For Windows, we need the mod_jk.dll for Apache. The Apache 1.3 version is available from the download directory on the Jakarta Project web site: http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.2.3/bin/win32/i386/. After downloading it, just copy the mod_jk.dll to the modules subdirectory of Apache. The Apache 2.0 version is available here: http://www.acg-gmbh.de/mod_jk/.






    Important 

    The version of mod_jk is not dependent on the version of Tomcat. The Tomcat 3.3 distribution of mod_jk will function correctly with Tomcat 4.x and other 3.x versions of Tomcat, such as Tomcat 3.2.1. This is quite logical when we think about it; it's a redirector module residing in the web server process and providing a standard interface for the Tomcat container.



    For other platforms, we can get mod_jk.so for Apache 1.3.x from its appropriate download directory: http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.2.3/bin/linux/i386/. After downloading it, just copy it to the libexec subdirectory of Apache.


    The Tomcat connectors are handled by a separate subproject of Jakarta, and as such, so are mod_jk and mod_jk2. To make the availability of the Tomcat connectors streamlined, the Jakarta Project has put up a separate URL that is expected to have both the versions of the module (binary and source). The URL is: http://jakarta.apache.org/builds/jakarta-tomcat-connectors/. However, at the time of writing, this download area is largely empty, with only a few connectors and platforms represented.


    For the new version of Apache (2.0) the complete range of binaries/sources is not yet populated at the above location, although there are a couple of resources for mod_jk apart from Apache's site. You can get the mod_jk module by either downloading a binary or you could build one of your own.



    Building mod_jk On Windows

    Here are some basic steps for building mod_jk.dll on Windows:




    • Download the source of the latest Apache web server from the Apache site (http://www.apache.org/dist/httpd/) and unpack the distribution into any convenient directory such as C:\Apache





    • Download the latest connectors source from the Jakarta site (http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.0.4/src/jakarta-tomcat-connectors-4.0.4-src.zip) and unpack it to a convenient directory such as C:\jakarta-tomcat-connectors-4.0.4-src




    • Set the environment variables:





      • %APACHE2_HOME% - for the Apache source distribution





      • %JAVA_HOME% - for the J2SE installation






    • Now with Microsoft Visual C++, open the DSP file in C:\jakarta-tomcat-connectors-4.0.4-src\jk\native\apache-2.0\mod_jk.dsp or C:\jakarta-tomcat-connectors-4.0.4-src\jk\native\apache-1.3\mod_jk.dsp depending on your server




    • Using the build option, build the mod_jk.dll




    • Copy mod_jk.dll to the modules directory of the binary Apache installation




    The mod_jk2 source is also in this distribution; use the C:\jakarta-tomcat-connectors-4.0.4-src\jk\native2\server\apache2\mod_jk2.dsp file.





    Building mod_jk on Unix/Linux

    Here are some basic steps for building mod_jk.so on Linux:




    • We can get the needed source for the connectors from the Jakarta site: http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.0.4/src/jakarta-tomcat-connectors-4.0.4-src.tar.gz.




    • Create a convenient directory for building the connector like /usr/local/src/jakarta-tomcat-connectors. We'll refer to this as $CONNECTOR_HOME.




    • Change to the directory $CONNECTOR_HOME/jk/native.




    • Run ./buildconf.sh to create a configure script.




    • Run ./configure --with-apxs=<APACHE_HOME>/bin/apxs. This command will configure mod_jk.so for the version of Apache that apxs belongs to.




    • Now run make.




    • We'll see mod_jk.so in $CONNECTOR_HOME/jk/native/apache-<verison>, where <version> is the version of Apache we configured for.





    • make install isn't implemented yet, so copy mod_jk.so to the libexec (Apache 1.3) or modules (Apache 2.0) directory.





    mod_jk2 has a similar procedure:




    • Change to the directory $CONNECTOR_HOME/jk/native2




    • Run ./buildconf.sh to create a configure script




    • For Apache 1.3 run ./configure --with-apxs=<APACHE_HOME>/bin/apxs and for Apache 2.0 run ./configure --with-apxs2=<APACHE_HOME>/bin/apxs





    • Now run make




    • We'll see mod_jk2.so in $CONNECTOR_HOME/jk/build/jk2/apache2




    • Copy mod_jk2.so into libexec or modules as appropriate for your version of Apache




    Both modules also come with Ant build scripts. Go into the jk directory, edit build.properties, and run:




    $ ant
    $ ant native


    Providing you have libtool, the native code for the connectors should be compiled.





















    The Invisible Playground











     < Day Day Up > 











    The Invisible Playground



    From the electronically mediated spaces of A.I. we turn to another game that emphasizes the play of its cultural environment: the LARP,or live-action role-playing game. LARPs also blur the boundaries between the inside and outside of a game, but do so through very different means. Live-Action Role-Playing Games are direct descendents of tabletop role-playing games such as Dungeons & Dragons. As in tabletop RPGs, LARP players take on the persona of fictional characters, defined through formal game statistics as well as through narrative backstory and an invented personality.


    Live-Action Role-Playing Games, however, do not take place around a table. Instead, LARPs occur in real physical spaces, as players walk about and interact with each other, dramatically acting out their characters' actions in real-time. Although LARPs do have Game Masters that plan and referee the sessions, as well as rules that handle combat and other complex player actions, most LARP activity consists of social interaction, as players converse "in character" to make plans, pursue narrative threads, and scheme against each other. Live-Action Role-Playing Games can take place in outdoor or indoor settings, in private or public spaces. The location in which the LARP takes place, as well as the dress and interaction of the players, depends largely on the narrative setting of the LARP.A Medie-val-themed LARP might occur in a wilderness environment or a Renaissance Fair. A futuristic LARP might take place in a series of convention hall rooms or in the house of one of the players.


    Nick Fortugno, a game designer and LARP Game Master, ran a LARP for many years in New York City based on Vampire: The Masquerade. His game, set in present day NYC, met regularly in public spaces that ranged from Washington Square Park to Grand Central Station. The players all took the role of vampires, ancient and powerful creatures that live secretly among humans. In typical Vampire: The Masquerade games, emphasis is not on physical confrontation or on players hunting humans for blood. Instead, the interest of the game comes from baroque power struggles waged between the aristocratic vampire clans. Fortugno's LARP, titled Seasons of Darkness, was designed along these lines, and was a game of dense social politics and intricate storytelling. Seasons of Darkness successfully engaged with its cultural environment in a variety of ways.




    Public Spaces


    Although many LARPs take place exclusively in isolated settings, most Seasons of Darkness sessions were held in public urban spaces. Through this design decision, Fortugno (and Tami Meyers, the game's administrator) created a game that intrinsically blurred the boundaries of the magic circle. In most games, even real-world physical games, the play takes place in a field, on a court, or someplace set aside specifically for the game. Seasons of Darkness did not use an artificially designed space, but instead appropriated existing ones. The players integrated their "found" context into the game play in many ways. A balcony overlooking the World Trade Center's Winter Garden, for example, might be used to heighten dramatic effect for a player delivering a speech to other players below; the same balcony might also be used strategically, as a vantage point for spying.


    The game-space of Seasons of Darkness was congruent not just with the material setting but also with the cultural environment of New York City. Media, signage, and unknowing passersby were all fodder for the game. A character on the run might duck into a throng of commuters, camouflaging herself among the passing crowds in an attempt to evade her pursuers. Or two players might be inspired by a clothing store window display to have a conversation about current fads in "human" culture. This use of public space as the space of the game greatly increased options for narrative play. As we first introduced in Interactivity, a game's space of possibility is the event-space of all possible game actions that might occur in the course of play. The space of possibility even in a closed magic circle can be quite large. But chance events and a constant flow of people and culture through a session of Seasons of Darkness made the game's space of possibility truly infinite. The game was played nowhere and everywhere at once, as players continually improvised and invented new ways to engage with their environment.






    Real-World Interaction


    As with most LARPs, Seasons of Darkness players played their game by moving, speaking, and gesturing "in character." In contrast to most games, in which game actions are stylized, artificial gestures (move a plastic token to a new space on the board when it is your turn; pass the ball to certain players in certain ways), Seasons of Darkness players made use of naturalized behaviors. In Freeze Tag, touching another player on the arm has formal ramifications for play. But in a LARP,touching another player on the arm usually has the same communicative meaning it does in everyday life: perhaps it is a gesture of empathy, or a silent request for the recipient to stop speaking. This is a significant departure from more typical games. The blurring and erasure of the magic circle takes place not only in terms of the game's setting, but also on the level of the player's interactions. The core mechanics of a game are basic game actions or set of actions that players repeat over and over as they play. In the case of Seasons of Darkness, the game's core mechanics overlapped with the behaviors of everyday life. Gestures, speech, dramatic skills: these tools for social interaction were part of the cultural environment each player brought to the game. Although social communication occurs in most games, in Seasons of Darkness these activities were themselves core game actions.


    This is not to say that the game didn't have its own set of stylized play actions; it certainly did. Combat and the use of supernatural powers required stylized behavior, which Fortungno designed as part of the game. It might be the case, for example, that a tap on the arm did not denote an innocent communicative speech-gesture, but instead signaled the use of a magical action. In Seasons of Darkness, a player that had used a special power to turn invisible crossed his or her arms. This gesture signified invisibility, and other players had to act as if the invisible player was not present.


    There is an important distinction to make here. Although it is true that a LARP blurs the border of the magic circle, the boundary is nowhere close to being completely eradicated. Despite its lamination with the actions and events of daily life, the game remains capable of generating its own meanings.The meaning of the crossed-arm gesture is artificial, not a part of our everyday lexicon of interaction. Yet this is entirely consistent with what we already know about games. As we discussed in Games as the Play of Simulation, the metacommunicative aspect of player consciousness creates what folklorist Gary Allen Fine calls "layers of meaning" in which game character, game player, and real-world context exist together within a web of interconnected cognitive frameworks.






    Emergent Storytelling


    Whereas some LARPs rely on pregenerated storylines and tightly scripted events, the narrative of Seasons of Darkness was a largely emergent system. Fortugno encouraged bottom-up instead of top-down narratives: many of the most significant story events were player-produced: the result of characters scheming and plotting against one another. Each session was a complex system, with the characters bumping into each other like narrative particles. Every interaction between characters built on previous ones, adding up to larger patterns of narrative behavior. In managing these patterns from session to session, Fortugno had to balance emergent with embedded narrative elements. The unexpected, emergent qualities of the game kept it moving in lively, unpredictable directions. But over the course of the years that the game was played, Fortugno also developed elaborately embedded plots that were only fully realized during the game's final climax.


    Emergence takes place within a context, the environment of the system. In Seasons of Darkness, narrative contexts were established out of the complex backstory of the game, which was derived from a host of sources: vampire lore and legend; the mythos of the published game rules; a fictional history of NYC vampires that Fortugno had written; established events of previous game sessions; consistent character personalities and their allegiances and enmities; and the public setting and other elements of the cultural environment. Any conversation or interaction between characters took place within a rich narrative context brimming with story potential.






    Meta-Narratives


    Playing a game in a public space has its challenges, especially when the players are pretending to be vampires. Large groups of players, milling about for hours late at night, could attract unwanted attention from police and security guards. Part of the play of the game included negotiating the friction between the real-world settings and the unusual way that players inhabited them. But remarkably enough, this very negotiation was a site of meaningful play.


    In the narrative universe of the game, vampires live in secret, pretending to be human (thus the "masquerade" of Vampire: The Masquerade). The most severe crime a vampire can commit is to leak information to human society about the existence of vampires. For this reason, players speaking about matters of vampire clan politics or supernatural occult powers lower their voices when non-players walk nearby. Players manifest the in-game narrative of secrecy by pretending that passersby need to be kept in the dark about the sinister truth. At the same time, players maintain another form of secret information: the fact that they are playing a game.The secret meanings of the game, like the fact that a player with crossed arms is "invisible," remain unknown to the general public.


    There is a beautiful double logic to the way these game elements play out. Just as vampires in the fictional game-world keep their existence to themselves, players of the game secret away the very presence of the magic circle. Games as Systems of Information explored the ways that games manipulate public and private information in order to drive meaningful play. In Seasons of Darkness, the game itself was a kind of private information, kept hidden from the public. This approach is in contrast to most games, where both players and spectators acknowledge the presence of the magic circle, and the distinction between players and non-players is immediately evident. The special information that Seasons of Darkness players have about the existence of the game is more than the formal information about its rules: it is cultural information, information that defines the play community and binds it together.


    The private knowledge that players have about the game acts to exemplify the narrative itself. Players' imaginative existence as non-human vampires is heightened by the secret status they hold within the public cultural environment where the game takes place. Private knowledge about the game functions as a form of procedural representation, a concept we introduced in Games as the Play of Simulation, in which signification arises from a dynamic process. A crowd of hapless tourists parts to reveal the menacing black-clad figure of an enemy vampire striding confidently toward you: this is a powerful moment of procedural narrative that could only happen in a LARP.But unlike most forms of procedural representation, where the closed set of rules and game interactions generate a depiction, here representation arises by layering the game onto the real world. The blurring of the game with its cultural environment is itself an act of representation.






    Current Events



    The Seasons of Darkness game was set in the real world, in the present day. As a result, political events occurring locally, nationally, and globally could be incorporated into the game narrative. For example, in the game narrative, Rudolph Giuliani, the mayor of New York City for the duration of the game, was a mind-controlled stooge of one of the more powerful players. As the Game Master, Fortugno had free reign to tie real-world events to the narrative play of the game; he freely encouraged players to do so as well. When fashion designer Gianni Versace was murdered, the clan of vampires that influence and guide human art and culture played their characters in full mourning for the entire game session following the news. Building on this creative game action, Fortugno decided to make the death a vampiric assassination with larger political implications.


    In this way, Seasons of Darkness was a system of open culture, exchanging meaning with its cultural context and transforming that meaning into game-specific narratives with integrated outcomes affecting future play. Fortugno encouraged a player-as-producer paradigm, encouraging players to modify and transform the game's meaning through independent acts of creation. Although Fortugno always had final approval of a player's appropriation of a real-world event, the shared context of the game and its storyline meant that he very rarely had to exercise censuring authority. The significance of player-production in Seasons of Darkness lies in the fact that players were not simply inventing an isolated game object such as a Quake skin or a work of fan fiction. Their act of creation consisted of locating an event in the real world and stretching the game narrative to accommodate it. In Seasons of Darkness, the cultural environment of current events was the raw material for player-production.


    Each of these design elements, acting in concert, created an extremely meaningful experience, supporting a play community of several dozen players for more than five years. Each game element was the result of careful game design choices. The danger and difficulty of designing a game as fully integrated into its cultural environment as Seasons of Darkness is that the game can run away with itself. Because of its intentional play with the boundaries of the magic circle, the game has the potential to blend too well into its environment. If it becomes too ambiguous, the shared safety and trust that allows a play community to persist can disappear.


    Acknowledging this danger, Fortugno kept the game design tightly constrained in many respects. Treating the published game as an open system, he re-wrote the rules, streamlining the formal game mechanics so players could focus on role-playing and storytelling. Although the game existed in public spaces, there were always constraints on where players could travel and what they could do during a game. The time of a game session was also clearly marked: every session began and ended with a Peter Pan-inspired ritual in which Fortugno blew imaginary pixie dust and pink smoke over the players. Even in a game with such permeable borders, the time and space of the magic circle remained unambiguously demarcated.


    As we have noted many times, game design is a second-order design process. Game designers create play experiences, but only indirectly, by creating rules and structures which then give rise to play. As a game designer, Fortugno skillfully manipulated the game's formal structures and their relationships to cultural contexts, balancing tight constraint with an open-ended integration into the game's cultural environment.The result was the passionate and refined play of Seasons of Darkness.





















     < Day Day Up > 



    Chapter 26. Threads



    [ Team LiB ]






    Chapter 26. Threads




      Section 26.1. 
      Introduction


      Section 26.2. 
      Basic Thread Functions: Creation and Termination


      Section 26.3. 
      str_cli Function Using Threads


      Section 26.4. 
      TCP Echo Server Using Threads


      Section 26.5. 
      Thread-Specific Data


      Section 26.6. 
      Web Client and Simultaneous Connections (Continued)


      Section 26.7. 
      Mutexes: Mutual Exclusion


      Section 26.8. 
      Condition Variables


      Section 26.9. 
      Web Client and Simultaneous Connections (Continued)


      Section 26.10. 
      Summary

      Exercises




    [ Team LiB ]



    Definitions








     

     










    Definitions



    Often a sentence or paragraph provides the definition of an unfamiliar word for you. Look for definitions set off by commas, in parentheses, or dashes. Also, look for words that signal that a definition is coming, such as the following:

































    or





    and





    that is





    in short





    in other words



     














       

       


      Hour 21. COM with .NET








       

       



      Hour 21. COM with .NET


      The computer industry is probably one of the fastest moving industries in existence today. How many times have you heard people complain that the hardware they just bought will be obsolete in a short amount of time? Not only does this liquidity apply to hardware sales but also to software development. Software development is constantly changing to keep up with the latest breakthroughs in programming. The latest and greatest software you just purchased is soon replaced by a new and better version in less than a year. The component your company purchased from a third-party vendor is soon replaced by a component with greater flexibility and newer features.


      The Component Object Model (COM) was a breakthrough programming model. Finally there was a technology in which software could literally be built using a variety of reusable components. It also broke the barrier that existed between differing programming languages by allowing code written in one language to be used by another language. By applying a standard consisting of strict programming rules and certain design guidelines, any programming languages adhering to these rules could be used together in a seamless programming environment. However, with every advantage there is always a disadvantage. So, what was the disadvantage of using COM?


      Simply put, COM was just too difficult to use for the average programmer. Sure, using components or ActiveX controls within Visual Basic was a somewhat trivial matter. However, take a group of programmers and ask how many can implement connection points within ATL or explain the differences between aggregation and containment, and you would see very few hands raised.


      One of the design tenants of the .NET Framework is to create a "componentized" programming environment without the complexities of COM. COM still exists within the .NET Framework, and many .NET objects are simply wrappers around COM objects, but the complexities of COM itself is almost transparent to the developer. The problem with any major shift in programming paradigms, though, is transitioning from one state to the other. This being the case, the .NET Framework was built to work with components written using COM, and vice versa. This ability to work between managed .NET objects and objects written using COM is known as COM Interop.



      In this hour you will learn:



      • How the .NET Framework is designed to handle .NET assembly and COM object communication


      • How to instantiate and use a COM object within a managed C++ application


      • How to use a .NET assembly and its associated classes within a native C++ application using COM













       

       





      Top

      Overview



















      Chapter 12 - Exception Callback

      Java Thread Programming
      Paul
      Hyde






      size=1>  size=2>Copyright � 1999 Sams
      Publishing




















      size=5>Chapter 12: size=5>Exception Callback












      size=4>Overview












      size=2>Exceptions can be thrown just about anywhere in a Java
      program. Methods must declare all of the exceptions they might throw
      except for
      size=2>RuntimeException
      and its subclasses. A
      size=2>RuntimeException
      can occur on just about every line of code (just think of the fact
      that
      size=2>NullPointerException size=2> can be thrown anytime a method is invoked if the object
      reference s
      size=2>nullsize=2>!).












      size=2>When an exception occurs and is not immediately caught, it
      propagates up the call stack until it either is caught by one of the
      invoking methods, or remains uncaught. For methods called from the
      size=2>main() method,
      the exception can potentially float all the way back up to
      size=2>main() and get
      reported there. However, when a new thread is spawned, a brand new
      call stack is created. This call stack starts with the
      color=#010100 face="Courier New" size=2>run() color=#010100 face=Arial size=2> method. The color=#010100 face="Courier New" size=2>run() color=#010100 face=Arial size=2> method does not declare that it
      throws any exceptions and should therefore catch all of
      them.












      size=2>Many times Java developers are frustrated by the fact that
      they cannot catch exceptions that occur in other threads. In this
      chapter, I’ll show you a way to pass exceptions that occur inside an
      active class to another class to signal it that a potential problem
      has occurred.












      valign="top" bgcolor="#FFFFFF">

      Toc



      14.7 Application Patterns











       < Day Day Up > 





      14.7 Application Patterns



      This section examines two patterns of evolving Web services from existing Web applications.



      1. One pattern is the browser-to-server pattern, which wraps an existing application as a service using a SOAP message as the service invocation. The Web server provides a runtime execution container that defines its own security model with policy information derived from a deployment descriptor configured by the Deployer of the Web application (see Section 3.7.3 on page 70). This pattern typically includes a mechanism for associating the identity of the invoking entity�the Web browser client�with the executing application instance and allows the application to continue to function as it did before.

        In the J2EE instance, this would manifest itself as the creation of a CSIv2 identity assertion (see Section 3.12 on page 99). A CSIv2 identity assertion uses an implicit trust model in the sense that the client and the server rely on the middleware configuration to ensure that the identity is established within a security context provided by the J2EE environment itself. An advantage of this model is that the runtime maintains the ID-mapping and name-assertion lifetime constraints, whereas mechanisms for maintaining a valid token can be provided by the middleware. A disadvantage is that the model for delegating an identity requires that the delegated application-level identity be the same as the invocation identity of the intermediary and hence the security context. This creates a coupling between the middleware and the application-level delegation logic�the run-as deployment descriptor element in J2EE�and another coupling between the middleware and the requirement for the security context to support cascaded delegation, auditing, and nonrepudiation.

      2. The second pattern involves rewriting the application with a modular design to create smaller tasks that can be combined in different ways to perform more complicated transactions. Each component is able to externalize its output into a message that the following component can take as input. This pattern uses SOAP messages to trigger each event. The messaging agents and message queues can be built into the runtime server below the application level. Sometimes, the messaging agents become the security-aware part of the runtime and control the flow of information along its path, based on security attributes in the header of the message.

        Sometimes, the security attributes get added into the message structure itself, as is the case with digital signatures. The trust model for this type of messaging relies on the specification of an explicit trust model. In this model, the trust will be explicit, or direct, in the sense that the client and the server rely on coupling the identity information along with the message explicitly and thus do not rely on the underlying security context. This requires that the service handler be able to establish the identity of the caller, based on the WS-Security UsernameToken element, which is specified in the SOAP header, and based on the trust on the entity that created the assertion tokens. Thus, in a direct, or explicit, trust model, an authentication/authorization authority has to be known and digitally sign the assertions at the time of the authentication/authorization event. A certificate associated with the signature can be used to identify the trusted authority and validate the signature. A trusted timestamp is included to indicate the assertion validity period. An advantage of this type of trust model is that the message can pass through multiple intermediaries. Authorization and delegation decisions can be made in a standard way by the intermediaries without modifying the name assertion of the originator of the message request.

        If implemented in an enveloped way, it is also possible to build audit trails capable of asserting evidence of nonrepudiation, as each intermediary could wrap a message with its own name assertion. A disadvantage of this model is that the end point has to do some additional processing to make sure that the originator name assertion is valid both from a trust standpoint and a time standpoint.



      Both patterns implement security in the runtime, and both rely on a mapping of an external form of an identity into a runtime interpretation of that identity and into a set of rules about the identity and its capabilities. The differences relate to who does the mapping and whether the information is in an externalized form that can be middleware independent and persistent.













         < Day Day Up > 



        Section 11.2. Stylesheet Switching







        11.2. Stylesheet Switching

        Stylesheet switching is a concept that has been around for almost as long as stylesheets. It is another way in which developers make their applications feel more Windows-like by giving users control over the style of the page.

        11.2.1. Creating the Stylesheets

        When you're creating the ability to switch styles directly in an Ajax application, first you must craft the stylesheet in a way that makes it easy to switch. Unless you plan to do a lot of rework, you will have to break the CSS rules into multiple files. This method of style switching will also be easier if you set up the structure to support the different stylesheets that will be created. Figure 11-6 shows a simple structure for CSS files.

        Figure 11-6. A possible structure for CSS files


        Obviously, this isn't the only way to set up the structure. However, I've found that this structure makes it easy to quickly find the rules I'm looking for. This screen directory contains a separate file for the structure, font, and color (or theme) that will be used for the page. Inside this directory you can have two more directories: font-sizes and themes. The font-sizes directory will hold all the alternative CSS files for controlling the sizes the font can have, and the themes directory will hold any alternative color schemes the page might have.

        You can find a slightly simpler setup in the print directory. This is because the developer will normally not want the end user to have as much control over how the page will be printed as she does how the pages are viewed on-screen. Therefore, there are no choices for font sizes or themes within the current directory. There are merely the three files for structure, font, and color, as there are in the screen directory.

        First we'll look at the three main files in the screen and print directories so that you can have a better understanding of what each file will contain. Once these files are set up, we can turn our attention to the alternate stylesheet files:


        screen.css

        The screen.css file contains all the screen CSS style rules for the following property types: boxes and layout, lists, and text. The screen CSS file holds the rules for the structure of the page and is not interested in anything that has to do with fonts or colors.


        fonts.css

        The fonts.css file contains all the screen CSS style rules for the font properties. This file is used to control the default font family, sizes, weights, and so forth.


        colors.css

        The colors.css file contains all the screen CSS style rules for the color and background property types. In this file, you set all of the page's color attributes and background settings.

        The following shows an example of what the structure.css file would contain:


        body {
        line-height: 1.5em;
        margin: 0;
        padding: 0;
        }

        a:hover {
        text-decoration: none;
        }

        tr td {
        border-style: solid;
        border-width: 1px;
        padding: 2px 4px;
        }

        a > img {
        border-style: none;
        }

        p.required {
        text-align: center;
        }

        .f_right {
        float: right;
        }

        #bodyFooter {
        clear: both;
        padding: 3px;
        text-transform: uppercase;
        }




        Here is an example of what the fonts.css file would contain:


        body {
        font-family: Arial, Helvetica, sans-serif;
        font-size: 1em;
        }

        a:hover {
        font-style: italic;
        }

        tr td {
        font-size: .9em;
        }

        p.required {
        font-weight: bold;
        }

        #bodyFooter {
        font-size: .75em;
        }


        Finally, here is an example of what the colors.css file would contain:


        body {
        background: #fff url('../..//images/bodyBackground.png') no-repeat fixed 0 0;
        color: #000;
        }

        a:hover {
        background-color: transparent;
        color: #0c0;
        }

        tr td {
        background-color: transparent;
        border-color: #000;
        color: #000;
        }

        a > img {
        vertical-align: middle;
        }

        p.required {
        background-color: transparent;
        color: #f00;
        }

        #bodyFooter {
        background-color: #009;
        color: #fff;
        }




        There is no difference between the content of the files in the print and screen directories. What is different is the unit of measure that is used. Screen files are more likely to use px and em units, for example, whereas print files are more likely to use pt, cm, or in. The difference is in the two types of units: relative and absolute.

        The relative units that CSS supports are pixels (px), x-height (ex), relative size (em), and percentage (%). The absolute units that CSS supports are centimeters (cm), inches (in), millimeters (mm), points (pt), and picas (pc). The difference is that absolute units are assumed to be the same distance across all browsers, screen resolutions, and printer faces (one inch should be one inch wherever it is used). Relative units, on the other hand, may vary because of differences in browser rendering, screen resolutions, and printer faces.


        11.2.2. Alternate Stylesheets

        Now that the default files are defined, it is time to consider what alternatives the user may need. Of course, alternate stylesheets can be used for theme switching that has nothing to do with giving the user greater accessibility. In this case, the developer merely wants to give the user different options regarding how the page looks or flows. No matter what the intention, or what the alternate stylesheets are going to do to the page, the basics on how to switch the CSS files with JavaScript will be the same.

        I touched on the basic structure of an alternate stylesheet link at the beginning of the chapter. Now we will take a closer look at what we need to make main and alternate stylesheet links. Consider the following:


        <link type="text/css" rel="stylesheet" media="screen" title="medium"
        href="screen/font-sizes/medium.css" />
        <link type="text/css" rel="alternate stylesheet" media="screen" title="smaller"
        href="screen/font-sizes/smaller.css" />
        <link type="text/css" rel="alternate stylesheet" media="screen" title="larger"
        href="screen/font-sizes/larger.css" />
        <link type="text/css" rel="alternate stylesheet" media="screen" title="monochrome"
        href="screen/themes/mono




        In this example, there is one main stylesheet link and three alternative ones. You must place the alternate keyword in the row attribute of the <link> element. This not only tells the browser that the link is supposed to be the alternative so as not to break browser functionality, but it also allows for easier parsing to determine the alternative ones in JavaScript. Each link also contains a title attribute which, strictly speaking, is not necessary for our JavaScript code, but is another way to make sure we are grabbing the appropriate stylesheets. More important, the title attribute is necessary for the browser to recognize that the link is an alternative link.

        You can provide three different types of stylesheets for the browser: persistent, preferred, and alternate. Persistent stylesheets use the keyword stylesheet in the rel attribute but have no title attribute set; preferred stylesheets use the keyword stylesheet in the rel attribute and have a title attribute set; and alternate stylesheets, as we just discussed, have the alternate keyword in the rel attribute and do have a title attribute set. Paul Sowden wrote a great article, "Alternative Style: Working with Alternate Style Sheets," for A List Apart in 2001 that explains this better (http://alistapart.com/stories/alternate/).


        11.2.3. The Switching Object

        We built some alternate stylesheets, and now we need to enable the user to switch between the different choices without having to rely on the functionality provided by the browser. So, if the user is going to rely on our application, we must provide the means to do the necessary switching.

        It does not matter whether we provide the choices in a drop down or in a list, as long as there is an intuitive means to apply the switching functionality. The following example provides the user with a list of choices of alternate stylesheets:


        <div id="styleChoicesContainer">
        <ul id="styleChoicesList">
        <li>style choices: </li>
        <li>
        <a href="setStyle.php?s=default"
        onclick="return StyleSwitcher.setActive('default');">
        default
        </a>
        </li><li>
        <a href="setStyle.php?s=alternate1"
        onclick="return StyleSwitcher.setActive('alternate1');">
        alternate 1
        </a>
        </li><li>
        <a href="setStyle.php?s=alternate2"
        onclick="return StyleSwitcher.setActive('alternate2');">
        alternate 2
        </a>
        </li><li>
        <a href="setStyle.php?s=alternate3"
        onclick="return StyleSwitcher.setActive('alternate3');">
        alternate 3
        </a>
        </li><li>
        <a href="setStyle.php?s=alternate4"
        onclick="return StyleSwitcher.setActive('alternate4');">
        alternate 4
        </a>
        </li>
        </ul>
        </div>




        It would be easy to style this list for horizontal display with a little CSS. But this does nothing until we write functionality behind the list. Example 11-2 shows the JavaScript required for us to make the list functional.

        Example 11-2. A simple style-switching object


        /* Example 11-2. A simple style-switching object. */

        /**
        * This object, StyleSwitcher, contains all of the functionality to get and set an
        * alternative style chosen by the user from a list provided by the application. It
        * contains the following methods:
        * - setActive(p_title)
        * - getActive( )
        */
        var StyleSwitcher = {
        /**
        * This method, setActive, takes the passed /p_title/ variable and sets the
        * appropriate alternate stylesheet as the current enabled one.
        *
        * @param {String} p_title The title that is to be set as active.
        * @member StyleSwitcher
        * @return Returns false so that the click event will be ignored.
        * @type Boolean
        */
        setActive: function(p_title) {
        /* Get a list of the <link> elements in the document */
        var links = document.getElementsByTagName('link');

        /*
        * Loop through the list, setting the appropriate <link> elements to
        * disabled, and set the <link> element with the title attribute equal to
        * /p_title/ to active.
        */
        for (var i = links.length; i > 0;) {
        /* Get the current <link> element */
        var iLink = links[i--];

        /* Is this element an appropriate stylesheet to mark? */
        if (iLink.getAttribute('rel').indexOf('style') != -1 &&
        iLink.getAttribute('title')) {
        iLink.disabled = true;
        /* Is this element the one we are looking for? */
        if (iLink.getAttribute('title') == p_title)
        iLink.disable = false;
        }
        }
        /* Set the cookie to the passed /p_title/ variable, and do not let it expire
        * for one year.
        */
        Cookie.set('appStyle', p_title, 365);
        return (false);
        },
        /**
        * This method, getActive, returns the current active stylesheet node (<link>
        * element) in the document, provided that there is one to return.
        *
        * @member StyleSwitcher
        * @return Returns the active stylesheet node, if one exists.
        * @type Node
        */
        getActive: function( ) {
        /* Get a list of the <link> elements in the document */
        var links = document.getElementsByTagName('link');

        /*
        * Loop through the list until the active stylesheet is located, then
        * return it.
        */
        for (var i = links.length; i > 0;) {
        /* Get the current link element */
        var iLink = links[i--];

        /* Is this the currently active <link> element? */
        if (iLink.getAttribute('rel').indexOf('style') != -1 &&
        iLink.getAttribute('title') && !iLink.disabled)
        return (iLink.getAttribute('title'));
        }
        return (null);
        }
        };




        Now when the user clicks on one of the choices on our list, the active stylesheet will change to the corresponding <link> element located in our document's <head> element. Figure 11-7 and Figure 11-8 demonstrate what dynamic changing of stylesheets might look like.

        Figure 11-7. The original page before switching styles


        Figure 11-8. The same page once the styles have switched


        11.2.4. Remembering the User's Selection

        Our style switcher is fine, but it only changes the style for the user for the currently active session. The next time the user visits the page, the page will default to the stylesheet the developer chose, and not what the user had selected. We need a way to save the user's choice between browser sessions. And of course, the use of cookies will do the trick. Example 11-3 shows an easy cookie object that you can implement in a page.

        Example 11-3. cookie.js: A simple cookie object


        /**
        * @fileoverview Example 11-3. cookie.js: A simple cookie object.
        *
        * This file, cookie.js, contains a simple cookie object that can be used to get and
        * set a cookie as well as erase cookies and check to see if a given browser even
        * supports cookies.
        */

        /**
        * This object, Cookie, is simply a mechanism to allow for easier access of the
        * document.cookie object for the page. It contains the following methods:
        * - set(p_name, p_value, p_expires)
        * - get(p_name)
        * - erase(p_name)
        * - accept( )
        */
        var Cookie = {
        /**
        * This method, set, creates a cookie with the name equal to /p_name/ with a
        * value of /p_value/ that expires at the specified /p_expires/ should it
        * exist, returning whether the cookie was created or not.
        *
        * @member Cookie
        * @param {String} p_name The name for the cookie to be set.
        * @param {String} p_value The value for the cookie to be set.
        * @param {Float} p_expires The time before the cookie to be set expires.
        * @return Returns whether the cookie was set or not.
        * @type Boolean
        */
        set: function(p_name, p_value, p_expires) {
        /* The expires string for the cookie */
        var expires = '';

        /* Was an expires time sent to the method? */
        if (p_expires != undefined) {
        /* Get a base time for the expiration date */
        var expirationDate = new Date( );

        /* Set the expiration to one day times the passed /p_expires/ value */
        expirationDate.setTime(expirationDate.getTime( ) + (86400000 *
        parseFloat(p_expires)));
        /* Create the expires string for the cookie */
        expires = '; expires=' + expirationDate.toGMTString( );
        }
        return (document.cookie = escape(name) + '=' + escape(p_value || '') +
        expires);
        },
        /**
        * This method, get, returns the cookie with a name equal to the passed /p_name/
        * variable if one exists.
        *
        * @member Cookie
        * @param {String} p_name The name for the cookie to return.
        * @return Returns the cookie data if it exists or /null/ otherwise.
        * @type String
        */
        get: function(p_name) {
        /* Get the matching cookie */
        var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(p_name)
        + '=([^;\\s]*)'));

        return (cookie ? unescape(cookie[2]) : null);
        },
        /**
        * This method, erase, removes the cookie with the passed /p_name/ variable from
        * the document. It returns the erased cookie (i.e., null if erase succeeded,
        * the cookie otherwise).
        *
        * @member Cookie
        * @param {String} p_name The name for the cookie to erase.
        * @return Returns the cookie after it is erased.
        * @type Boolean | String
        */
        erase: function(p_name) {
        /* Get the cookie with the passed /p_name/ variable */
        var cookie = Cookie.get(p_name) || true;

        /*
        * Set the cookie with the passed /p_name/ variable to an empty string, and
        * make it expire
        */
        Cookie.set(p_name, '', -1);
        return (cookie);
        },
        /**
        * This method, accept, tests to see if the browser accepts cookies and returns
        * the results of this test.
        *
        * @member Cookie
        * @return Returns whether the browser accepts cookies or not.
        * @type Boolean
        */
        accept: function( ) {
        /* Can the test be accomplished using the browser's built-in members? */
        if (typeof navigator.cookieEnabled == 'boolean')
        return (navigator.cookieEnabled);
        /* Attempt to set and erase a cookie and return the results */
        Cookie.set('_test', '1');
        return (Cookie.erase('_test') === '1');
        }
        };




        We must incorporate this cookie object into the style-switching object from Example 11-2. It is not enough to just store the user's choice in a cookie. We must also provide a way to choose the user's choice from the cookie when the page first loads. Example 11-4 shows how we do this.

        Example 11-4. Using cookies to store user choices incorporated in our original style switcher


        /*
        * Example 11-4. Using cookies to store user choices incorporated in our original
        * style switcher.
        */

        /**
        * This object, StyleSwitcher, contains all of the functionality to get and set an
        * alternate style chosen by the user from a list provided by the application. It
        * contains the following methods:
        * - setActive(p_title)
        * - getActive( )
        * - getPreferred( )
        * - loadStyle( )

        */
        var StyleSwitcher = {
        /**
        * This method, setActive, takes the passed /p_title/ variable and sets
        * the appropriate alternate style sheet as the current enabled one. It then
        * stores this choice into a cookie for future use.
        *
        * @member StyleSwitcher
        * @param {String} p_title The title that is to be set as active.
        * @return Returns false so that the click event will be ignored.
        * @type Boolean
        * @requires Cookie This method uses the Cookie object to store the
        * user's selection.
        * @see Cookie#set

        */
        setActive: function(p_title) {
        /* Get a list of the <link> elements in the document */
        var links = document.getElementsByTagName('link');

        /*
        * Loop through the list, setting the appropriate <link> elements to
        * disabled, and set the <link> element with the title attribute equal to
        * /p_title/ to active.
        */
        for (var i = links.length; i > 0;) {
        /* Get the current <link> element */
        var iLink = links[i--];

        /* Is this element an appropriate stylesheet to mark? */
        if (iLink.getAttribute('rel').indexOf('style') != -1 &&
        iLink.getAttribute('title')) {
        iLink.disabled = true;
        /* Is this element the one we are looking for? */
        if (iLink.getAttribute('title') == p_title)
        iLink.disable = false;
        }
        }

        /*
        * Set the cookie to the passed /p_title/ variable, and do not let it expire
        * for one year
        */
        Cookie.set('appStyle', p_title, 365);

        return (false);
        },
        /**
        * This method, getActive, returns the current active stylesheet node (<link>
        * element) for the page, provided that there is one to return.
        *
        * @member StyleSwitcher
        * @return Returns the active stylesheet node, if one exists.
        * @type Node
        */
        getActive: function( ) {
        /* Get a list of the <link> elements in the document */
        var links = document.getElementsByTagName('link');

        /*
        * Loop through the list until the active stylesheet is located, then
        * return it
        */
        for (var i = links.length; i > 0;) {
        /* Get the current <link> element */
        var iLink = links[i--];

        /* Is this the currently active <link> element? */
        if (iLink.getAttribute('rel').indexOf('style') != -1 &&
        iLink.getAttribute('title') && !iLink.disabled)
        return (iLink.getAttribute('title'));
        }
        return (null);
        },
        /**
        * This method, getPreferred, returns the preferred stylesheet title for the
        * page, provided that there is one to return.
        *
        * @member StyleSwitcher
        * @return Returns the preferred stylesheet title, if one exists.
        */
        * @type String
        getPreferred: function( ) {
        /* Get a list of the <link> elements in the document */
        var links = document.getElementsByTagName('link');

        /*
        * Loop through the list until the preferred stylesheet is located, then
        * return it.
        */
        for (var i = links.length; i > 0;) {
        /* Get the current <link> element */
        var iLink = links[i--];

        /* Is this the preferred <link> element? */
        if (iLink.getAttribute('rel').indexOf('style') != -1 &&
        iLink.getAttribute('rel').indexOf('alt') == -1 &&
        iLink.getAttribute('title'))
        return (iLink.getAttribute('title'));
        }
        return (null);
        },
        /**
        * This method, loadStyle, loads the stylesheet for the application,
        * attempting to first get it from the cookie, and if not from there, then the
        * preferred stylesheet for the page is selected instead.
        *
        * @member StyleSwitcher
        * @requires Cookie This method uses the Cookie object to get the
        * user's selection.
        * @see Cookie#get
        */
        loadStyle: function( ) {
        /* Get the cookie, and extract the appropriate title to set active */
        var cookie = Cookie.get('appStyle');
        var title = ((cookie) ? cookie : this.getPreferred( ));

        /* Set the active stylesheet for the page */
        this.setActive(title);
        }
        };

        try {
        /* Load the style sheet for the page */
        Event.observe(window, 'load', StyleSwitcher.loadStyle, false);
        } catch (ex) {}












        Game Genres

        Game Genres


        A game genre is a type or category of game. As with movies, there are many game genres, and they are often hard to classify. Some games may fit in more than one genre. Here's a list of the most popular genres.


        Action
        An action game has moving objects and focuses on your timing, reflexes, hand-eye coordination, and quick thinking to achieve a good score. Most games have some action in them but aren't necessarily considered "action games." Space Invaders and Half-Life are good examples of action games.


        Adventure
        Often confused with RPGs, adventure games let you control a character in an environment while the story is discovered. Unlike what happens in an RPG, your actions do not affect your character's overall abilities. Examples of adventure games range from Super Mario Brothers to the games in the King's Quest series.


        Casino
        One of the most popular genres to play on the Internet is casino (that is, gambling) games, such as poker and roulette.


        Educational
        In an educational game, the goal is to educate the player. This game can also be a part of another genre; for instance, you can have an educational puzzle game.


        First-person shooter
        This style of game lets you see a world through the character's eyes as you run around and try to shoot anything that moves. Typically the action in these games takes precedence over the story.


        Puzzle
        A puzzle game, also called a logic game, challenges your mind more than your reflexes. Many puzzle games are timed or limit the amount of time in which you can make a move. Games like Tetris and Sobokan are good examples of puzzle games. Puzzle games also include some classics like chess and checkers.


        Sports
        A sports game is an action game with rules that mimic those of a specific sport. For instance, NHL 2002, by Electronic Arts, is an ice hockey sports game.


        Role-playing game (RPG)
        An RPG is a game in which you, the game player, control a character in its environment. In this environment you encounter other beings and interact with them. Depending on your actions and choices, the character's attributes (such as fighting ability, magical powers, and agility) change, and so may the story. Baldur's Gate is an RPG.


        Strategy
        This type of game focuses on your resourcefulness and deal-making ability as you try to build and/or run something. In some games, your goal is to successfully build and run a city; in others, what you have to build or run can be anything from an army to a roller coaster.




        Chapter&nbsp;11.&nbsp;Word Processing









        Chapter 11. Word Processing


        I think I can safely assume that you are acquainted with word processing. It's the most widely used application among computer users. Word processing is used to create documents as simple as a letter or as complex as a corporate report, a newsletter, or a legal document. The leading word processors are Microsoft Word and WordPerfect.


        OpenOffice is an office suite, similar to Microsoft Office or WordPerfect Office. OpenOffice Writer is the word processor in OpenOffice. It has functionality equal to either of the leading word processors. It includes all the advanced features, such as spell checking, mail merge, storing graphics in the document, drawing in the document, and others.


        Word processing applications store both the content of the document and the information needed for formatting the text. A word processing document file includes information about margins, text size, indents, font style and type, and many other things. Different word processing documents store the formatting information differently. Consequently, one word processing application can't open documents from another word processing program. However, most word processors provide features that allow the exchange of documents with major word processors. For instance, Word can convert WordPerfect files, and vice versa.


        OpenOffice Writer can read Word files. In fact, it converts Word files more successfully than any other application. Word can't read OpenOffice Writer files in Writer format, but OpenOffice Writer can save documents in Word format, so that Word can open them. Writer also reads and writes documents in formats, such as HTML and RTF, that are general formats, allowing document exchange with other word processing applications. Read more about document formats in the section "Document File Formats."










          2.2 Servlets



          [ Team LiB ]






          2.2 Servlets



          The
          JSP specification is based on the Java servlet specification. In
          fact, JSP pages are often combined with servlets in the same
          application. In this section, we take a brief look at what a servlet
          is, and then discuss the concepts shared by servlets and JSP pages.
          In Chapter 3, we'll take a closer
          look at how JSP pages are actually turned into servlets
          automatically.



          If you're already familiar with servlets, this is
          old news. You can safely skip the rest of this chapter.




          2.2.1 Advantages over Other Server-Side Technologies



          In
          simple terms, a servlet is a piece of code that adds new
          functionality to a server (typically a web server), just like CGI and
          proprietary server extensions such as NSAPI and ISAPI. But compared
          to other technologies, servlets have a number of advantages:




          Platform and vendor independence



          All the major web servers and application servers support servlets,
          so a servlet-based solution doesn't tie you to one
          specific vendor. Also, servlets are written in the Java programming
          language, so they can be used on any operating system with a Java
          runtime environment.




          Integration



          Servlets are developed in Java and can therefore take advantage of
          all other Java technologies, such as JDBC for database access, JNDI
          for directory access, RMI for remote resource access, etc. Starting
          with Version 2.2, the servlet specification is part of the Java 2
          Enterprise Edition (J2EE), making servlets an important ingredient of
          any large-scale enterprise application, with formalized relationships
          to other server-side technologies such as Enterprise JavaBeans.




          Efficiency



          Servlets execute in a process that is running until the servlet-based
          application is shut down. Each servlet request is executed as a
          separate thread in this permanent process. This is far more efficient
          that the CGI model, where a new process is created for each request.
          First of all (and most obvious), a servlet doesn't
          have the overhead of creating the process and loading the CGI script
          and possibly its interpreter. But another timesaver is that servlets
          can also access resources that remain loaded in the process memory
          between requests, such as database connections and persistent state.




          Scalability



          By virtue of being written in Java and the broad support for
          servlets, a servlet-based application is extremely scalable. You can
          develop and test the application on a Windows PC using the standalone
          servlet reference implementation, and deploy it on anything from a
          more powerful server running Linux and Apache to a cluster of
          high-end servers with an application server that supports
          loadbalancing and failover.




          Robustness and security



          Java is a strongly typed programming language. This means that you
          catch a lot of mistakes in the compilation phase that you would only
          catch during runtime if you used a script language such as Perl.
          Java's error handling is also much more robust than
          C/C++, where an error such as division by zero typically brings down
          the whole server.



          In addition, servlets use specialized interfaces to server resources
          that aren't vulnerable to the traditional security
          attacks. For instance, a CGI Perl script typically uses shell command
          strings composed of data received from the client to ask the server
          to do things such as send email. People with nothing better to do
          love to find ways to send data that will cause the server to crash,
          remove all files on the hard disk, or plant a virus or a backdoor
          when the server executes the command. While a CGI script programmer
          must be very careful to screen all input to avoid these threats, such
          problems are almost nonexistent with a servlet because it
          doesn't communicate with the server in the same
          insecure way.[2]

          [2] However, servlet-based web sites are
          vulnerable to so-called cross site scripting attacks (see http://www.cert.org/advisories/CA-2000-02.html)
          the same way all dynamic web sites are, no matter which technology is
          used.





          As you will see in Chapter 3, JSP inherits all
          these advantages because it's based on the servlet
          specification.





          2.2.2 Servlet Containers



          A servlet container is the connection
          between a web server and the servlets. It provides the runtime
          environment for all the servlets on the server as defined by the
          servlet specification, and is responsible for loading and invoking
          those servlets when the time is right. The container typically loads
          a servlet class when it receives the first request for the servlet,
          gives it a chance to initialize itself, and then asks it to process
          the request. Subsequent requests use the same, initialized servlet
          until the server is shut down. The container then gives the servlet a
          chance to release resources and save its state (for instance,
          information accumulated during its lifetime).



          There are many different types of servlet containers. Some containers
          are called
          add-ons,
          or
          plug-ins,
          and are used to add servlet support to web servers without native
          servlet support (such as Apache and IIS). They can run in the same
          operating-system process as the web server or in a separate process.
          Other containers are standalone servers. A
          standalone server includes
          web server functionality to provide full support for HTTP in addition
          to the servlet runtime environment. Containers can also be
          embedded in other servers, such as a
          climate-control system, to offer a web-based interface to the system.
          A container bundled as part of an application server can distribute
          the execution of servlets over multiple hosts. The server can balance
          the load evenly over all containers, and some servers can even
          provide failover capabilities in case a host crashes.



          No matter what type it is, the servlet container is responsible for
          mapping an incoming request to a servlet registered to handle the
          resource identified by the URI and passing the request message to
          that servlet. After the request is processed, it's
          the container's responsibility to convert the
          response created by the servlet into an HTTP response message and
          send it back to the client. This is illustrated in Figure 2-4.




          Figure 2-4. Request dispatching





          2.2.3 Servlet Contexts and Web Applications



          A Java web application is typically made up
          by a combination of several different types of resources: JSP pages,
          servlets, applets, static HTML pages, custom tag libraries and other
          Java class files. Containers compliant with the Servlet 2.2
          specification (or later), support a standard, portable way to package
          all these resources, along with a web application deployment
          descriptor containing information about how all the resources fit
          together. The deployment descriptor and all the other web application
          files are arranged in a well-defined hierarchy within an archive
          file, called a web application
          archive
          (WAR). All compliant
          containers provide tools for installing a WAR file or a special
          directory where a WAR file is automatically picked up (such as the
          webapps directory in Tomcat). Most containers
          also support web applications deployed directly in a filesystem using
          the same file structure as is defined for the WAR file, which can be
          convenient during development.



          Within the container, each web application is represented by a
          servlet context. The
          servlet context is associated with a unique URI path prefix called
          the context
          path, as shown in Figure 2-4.
          For instance, your human resources application can be associated with
          the context path /hr and your sales tracking
          system with the context path /sales. This allows
          one servlet container to distinguish between the different
          applications it serves and dispatch requests like
          /sales/report?month=Jan to the sales tracking
          application and /hr/emplist to the human
          resources application.



          The remaining URI path is then used within the selected context to
          decide how to process the request by comparing it to path-mapping
          rules defined by the application's deployment
          descriptor. Rules can be defined to send all requests starting with
          /report to one servlet and requests starting
          with /forecast to another. Another type of
          mapping rule can say that one servlet handles all requests with paths
          ending with a specific file extension, such as
          .jsp. This is how JSP page requests are handled.
          Figure 2-4 shows how the different parts of the URI
          paths are used to direct the request processing to the right resource
          through the container and context.



          Each context is self-contained and doesn't know
          anything about other applications running in the same container.
          References between the servlets and JSP pages in the application are
          commonly relative to the context path and, therefore, are referred to
          as
          context-relative paths. By using context-relative paths
          within the application, a web application can be deployed using any
          context path.



          Finally, a context can hold objects shared by all components of the
          application,[3] such as database connections and other shared resources
          needed by multiple servlets and JSP pages.

          [3] Special considerations must be taken for
          applications distributed over multiple servers. Chapter 18 describes this in more detail.



          The web application structure, the deployment file format, and the
          ability to share objects among components in an application are three
          important parts of the servlet specification that also apply to JSP.
          We will look at all these areas in much greater detail later in this
          book, starting with the basics in Chapter 5 and
          adding more advanced features as needed in the following
          chapters.








            [ Team LiB ]