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

How-To Tutorials

7019 Articles
article-image-how-bridge-client-server-gap-using-ajax-part-ii
Packt
15 Oct 2009
7 min read
Save for later

How to Bridge the Client-Server Gap using AJAX (Part II)

Packt
15 Oct 2009
7 min read
AJAX and events Suppose we wanted to allow each dictionary term name to control the display of the definition that follows; clicking on the term name would show or hide the associated definition. With the techniques we have seen so far, this should be pretty straightforward: $(document).ready(function() { $('.term').click(function() { $(this).siblings('.definition').slideToggle(); });}); When a term is clicked, this code finds siblings of the element that have a class of definition, and slides them up or down as appropriate. All seems in order, but a click does nothing with this code. Unfortunately, the terms have not yet been added to the document when we attach the click handlers. Even if we managed to attach click handlers to these items, once we clicked on a different letter the handlers would no longer be attached. This is a common problem with areas of a page populated by AJAX. A popular solution is to rebind handlers each time the page area is refreshed. This can be cumbersome, however, as the event binding code needs to be called each time anything causes the DOM structure of the page to change. We can implement event delegation, actually binding the event to an ancestor element that never changes. In this case, we'll attach the click handler to the document using .live() and catch our clicks that way: $(document).ready(function() { $('.term').live('click', function() { $(this).siblings('.definition').slideToggle(); });}); The .live() method tells the browser to observe all clicks anywhere on the page. If (and only if) the clicked element matches the .term selector, then the handler is executed. Now the toggling behavior will take place on any term, even if it is added by a later AJAX transaction. Security limitations For all its utility in crafting dynamic web applications, XMLHttpRequest (the underlying browser technology behind jQuery's AJAX implementation) is subject to strict boundaries. To prevent various cross-site scripting attacks, it is not generally possible to request a document from a server other than the one that hosts the original page. This is generally a positive situation. For example, some cite the implementation of JSON parsing by using eval() as insecure. If malicious code is present in the data file, it could be run by the eval() call. However, since the data file must reside on the same server as the web page itself, the ability to inject code in the data file is largely equivalent to the ability to inject code in the page directly. This means that, for the case of loading trusted JSON files, eval() is not a significant security concern. There are many cases, though, in which it would be beneficial to load data from a third-party source. There are several ways to work around the security limitations and allow this to happen. One method is to rely on the server to load the remote data, and then provide it when requested by the client. This is a very powerful approach as the server can perform pre-processing on the data as needed. For example, we could load XML files containing RSS news feeds from several sources, aggregate them into a single feed on the server, and publish this new file for the client when it is requested. To load data from a remote location without server involvement, we have to get a bit sneakier. A popular approach for the case of loading foreign JavaScript files is injecting <script> tags on demand. Since jQuery can help us insert new DOM elements, it is simple to do this: $(document.createElement('script')) .attr('src', 'http://example.com/example.js') .appendTo('head'); In fact, the $.getScript() method will automatically adapt to this technique if it detects a remote host in its URL argument, so even this is handled for us. The browser will execute the loaded script, but there is no mechanism to retrieve results from the script. For this reason, the technique requires cooperation from the remote host. The loaded script must take some action, such as setting a global variable that has an effect on the local environment. Services that publish scripts that are executable in this way will also provide an API with which to interact with the remote script. Another option is to use the <iframe> HTML tag to load remote data. This element allows any URL to be used as the source for its data fetching, even if it does not match the host page's server. The data can be loaded and easily displayed on the current page. Manipulating the data, however, typically requires the same cooperation needed for the <script> tag approach; scripts inside the <iframe> need to explicitly provide the data to objects in the parent document. Using JSONP for remote data The idea of using <script> tags to fetch JavaScript files from a remote source can be adapted to pull in JSON files from another server as well. To do this, we need to slightly modify the JSON file on the server, however. There are several mechanisms for doing this, one of which is directly supported by jQuery: JSON with Padding, or JSONP. The JSONP file format consists of a standard JSON file that has been wrapped in parentheses and prepended with an arbitrary text string. This string, the "padding", is determined by the client requesting the data. Because of the parentheses, the client can either cause a function to be called or a variable to be set depending on what is sent as the padding string. A PHP implementation of the JSONP technique is quite simple: <?php print($_GET['callback'] .'('. $data .')');?> Here, $data is a variable containing a string representation of a JSON file. When this script is called, the callback query string parameter is prepended to the resulting file that gets returned to the client. To demonstrate this technique, we need only slightly modify our earlier JSON example to call this remote data source instead. The $.getJSON() function makes use of a special placeholder character, ?, to achieve this. $(document).ready(function() { var url = 'http://examples.learningjquery.com/jsonp/g.php'; $('#letter-g a').click(function() { $.getJSON(url + '?callback=?', function(data) { $('#dictionary').empty(); $.each(data, function(entryIndex, entry) { var html = '<div class="entry">'; html += '<h3 class="term">' + entry['term'] + '</h3>'; html += '<div class="part">' + entry['part'] + '</div>'; html += '<div class="definition">'; html += entry['definition']; if (entry['quote']) { html += '<div class="quote">'; $.each(entry['quote'], function(lineIndex, line) { html += '<div class="quote-line">' + line + '</div>'; }); if (entry['author']) { html += '<div class="quote-author">' + entry['author'] + '</div>'; } html += '</div>'; } html += '</div>'; html += '</div>'; $('#dictionary').append(html); }); }); return false; });}); We normally would not be allowed to fetch JSON from a remote server (examples.learningjquery.com in this case). However, since this file is set up to provide its data in the JSONP format, we can obtain the data by appending a query string to our URL, using ? as a placeholder for the value of the callback argument. When the request is made, jQuery replaces the ? for us, parses the result, and passes it to the success function as data just as if this were a local JSON request. Note that the same security cautions hold here as before; whatever the server decides to return to the browser will execute on the user's computer. The JSONP technique should only be used with data coming from a trusted source.
Read more
  • 0
  • 0
  • 3204

article-image-extending-project-governance-service-oriented-architecture-part2
Packt
15 Oct 2009
14 min read
Save for later

Extending Project Governance for Service Oriented Architecture-part2

Packt
15 Oct 2009
14 min read
Beginning Your SOA Journey Many organizations start their journey towards SOA through some sort of grass roots effort. Unfortunately, these efforts normally result in what's known as JBOS (Just a Bunch of Services). Typically, a project that had previously used some form of distributed component technology, such as Enterprise Java Beans, has now chosen to use XML or SOAP and HTTP, instead. The issue with this approach is that the service boundary that establishes the consumer and provider relationship really doesn't exist when one team is responsible for both the consumer and the provider. Eventually, the organization will encounter a situation where the development of the service and development of the consumer takes place in a separate project. This could be due to there being more than one consumer, a B2B scenario where services are developed for consumption by partner companies, a large program that involves many independently managed projects, or simply a decision that the organization makes as it learns more about SOA. In our example, this was exactly the case. There was a program that encompassed three separate projects, two that involved development of service consumers, and one that handled the service development. The two consumers were the front-end for the auto insurance system and the front-end for the home insurance system. Spencer's project was responsible for creating a new service that provided an abstraction layer in front of the data systems for both applications. Key Project Roles The nice thing about projects and programs is that they have an explicit hierarchy. If a developer has a question or concern, they work with the project architect. The project architect may take things to the project manager, and the project manager may take things to the sponsor. If it's a program, then there's likely a hierarchy of architects and project managers, but everything bubbles its way up to the top. Everyone working on the project understands the objectives, the scope, the milestones, and the deadlines. This explicit hierarchy is the first, and often only, source of governance within the project. Within the project we have one piece of the governance puzzle: people. The challenge, however, is that the people only have authority within the project. If your SOA adoption efforts are broader than that single project or program, you'll likely run into problems. In our Advasco example, Spencer ran into exactly this problem. Initially, Spencer only had to deal with project managers that were within the overall program. These project managers knew that the desired outcome was a shared, accurate, complete view of the customer, and it would be achieved through usage of the new service. As a result, they worked together with Spencer to ensure that outcome would be reached. When Spencer went outside of the program, however, his position of authority did not go with him. When he met with Ryan, he had no perceived or explicit authority. Even though the company had recognized a need to improve its image with its customers, the scope of that effort within IT was limited to the home and auto insurance areas. Therefore, for Ryan, service reuse was not on his list of desired outcomes, and regardless of how good Spencer made it sound, it was not something that he was willing to risk for the outcomes that he did desire. The Service Contract In this example, we clearly had a service provider, Spencer and his team, and two service consumers, the auto insurance application whose development efforts were managed by Jennifer and the home insurance application managed by Mark. A key aspect of this example is that these three efforts were independently managed, even though all being under a common program. A service should be independent of all consumers and this begins at the time that version one is developed, not at the time version one goes into production. In our example, imagine if the service development was under the management of either Mark's project or Jennifer's project. If a conflict arose, whose project would win out? Clearly, the project manager that oversees the service development effort has the upper hand, and will likely make decisions that will benefit their own project first. By separating out the service development as an independently managed effort, both of the two consumers are now equal, as they should be. When we have the notion of a service consumer and a service provider, we need an explicit representation of the relationship between them, and that relationship is a service contract. This is no different than how we deal with services in the real world. If you hire a crew to replace the roof on your home, the first step is for you and the construction crew to sign a contract that governs the work. It provides governance by establishing policies. These include the hours that work will take place, the time in which the work will be done, the payment schedule and conditions, the behavior of the crew in the event of bad weather, and so on. In the world of SOA, the service contract is the collection of policies that govern the interaction between a service consumer and a service provider. That contract states the messages that will be exchanged, the URIs to be utilized, and more. In this article, the initial focus was on two factors: the functional interface and the delivery schedule of the implementation. This is where most organizations start as the functional interface and a working implementation of that interface are clearly the minimum mandatory elements. It is no surprise that terminology like contract-first quickly sprung up as the varying technical approaches started to gain in popularity. This article also addressed another key element of service contracts. In the real world, a contract is a binding agreement between two parties. Using our earlier roofing example, if the contractor replaces the roof on your house as well as the roof on your neighbor's house, he would have one contract with you and one contract with your neighbor. While you and your neighbor are both receiving the same service (a new roof) the terms and conditions around that service are likely to be different. You may both have been presented a standard contract to begin with, but from that point on, each one of you may have made your own adjustments or additions. The same approach needs to hold true for technology services. You may choose to expose a subset of operations to one consumer, while another consumer may have access to all operations. In our example, Spencer's efforts initially fell short. He had initial conversations with Jennifer, but the only thing that came out of it was some agreement on when things had to go live. There was no discussion of the service interface, no discussion of the delivery schedule of milestone releases, or anything else. Given that this service was only going to be consumed internally, the development of the interface should have been a joint effort of both the consumer and provider. Spencer's team would bring domain knowledge from the provider's side, Jennifer's team would bring domain knowledge from the consumer's side, and together they would establish a service interface that was amenable to both. Instead, Spencer's team developed the initial service interface in a vacuum, creating something that may have met their needs, but did not meet the needs of the consumer. Meeting the needs of the consumer is the most important aspect of providing a service. The second mistake that Spencer made was that he did not establish a formal definition of the handoffs that would be required between his team and Jennifer's team. In providing Jennifer's team an endpoint that could be used during development, he thought he was doing the right thing, but then when that endpoint changed out from underneath them, since, after all, it was under development, it had an impact on the trust between Jennifer's team and his team. This particular situation can be a challenging one for many organizations, because the basic design of their environments often assumes that everything required for a project is under the control of the project team, and can therefore be promoted through the environments in lock-step. Now, when service consumers and the service provider are being developed according to their own timelines, instability can be introduced. The appropriate way to handle this situation is to make explicit those policies that govern the interaction between the service consumers and the service provider during the design and development phase, rather than dealing with situations that arise on an ad hoc basis. The service provider has the responsibility for delivering a stable version of the service at various points throughout the project, and deploying it onto a stable platform that only changes according to the policies within the contracts enacted with the consumer teams. For example, suppose both the service consumer and service provider are taking an iterative approach to the development of their solutions. In order to allow the service consumer adequate time for testing and feedback, the service provider may only promote a subset of their iteration builds to an integration environment for use by the service consumer. The service consumer would be required to provide feedback within a specified amount of time in order to have the fix included in a subsequent integration release. This is shown in the following figure: In short, within a single project, iterative, agile development can certainly take precedence. Across projects, however, the handoffs should be formalized and explicitly specified as part of the service contract, especially when two or more consumers are involved. Adding SOA to Traditional Project Governance While the big change for the organization is learning how to manage the consumer-provider relationship, we can't forget about traditional project governance. Today, your organization may make use of architecture reviews, design reviews, code reviews, and operational readiness reviews as part of the software development process. These reviews already embody the three components of governance: people, policies, and process. These reviews more than likely involve resources from outside the project that the enterprise has positioned as authorities. An architecture review may involve enterprise architects, more senior architects, or other architectural peers. A design review may involve architects or senior developers. A code review may involve senior developer or other development peers. The operational readiness review probably involves members of the operational areas to ensure that a handoff to the support teams will be successful. In order for these reviews to be successful, the policies that need to be followed for architecture, design, coding, and deployment need to be known to the project team. In the absence of documented policies that encourage the desired behavior, these reviews tend to be a show of power by the review team, where it is simply an exercise in trying to find something about the project to make the statement that they know better than the project team. Meanwhile, the project team plays a guessing game trying to determine what the review team wants to see, usually winding up wrong. In short, without documented policies, the review tends to be a lose-lose situation for all involved. The process is the part that can vary. Some organizations choose to utilize a formal review process where an hour or two of time is scheduled with the reviewing body, the team prepares a formal presentation, and the review takes place. However, it doesn't need to be this heavyweight. Any of these reviews could also be done in a more informal manner, with a single meeting between a recognized authority for the review being done and the project architect or technical lead. If there is a formal technical hierarchy in the organization, the process may simply be part of the normal conversation that a project architect has with their architecture manager on a regular basis. Finally, an organization can even choose to have no review process, and simply trust that the decision makers on the project have awareness of the policies that must be followed. So how does SOA change the current governance model for projects? Presuming your existing governance model is working, the only thing that SOA introduces is additional policies. If your existing governance model isn't working, consider making a change. You now have a project that is building a new artifact, the service. While we discussed the importance of involving potential consumers in the definition of the service interface, the enterprise also has a role. Policies that are normally enforced by an external review board are typically associated with ensuring consistency across projects. When building services, the areas for consistency are: The technologies used for the service implementation The technologies used for communication between the consumer and the provider The representation of the information that is transferred between the consumers and the provider Service Implementation Technologies The first area that an enterprise may strive for consistency is in the technologies used to build services, also known as service platform technologies. There's a good chance that an organization may already have some standardization in this area, such as a single Java EE application server. Even if they do, there is still room for standardization. At a minimum, the organization will need a general purpose application server and an associated development framework, such as a Java EE application server or Windows Server and the Microsoft .NET framework. Both of these platforms provide libraries for many different types of service communication technologies, as well as a robust library of open-source frameworks either as alternative or as extensions for other purposes. Depending on your organization, you may have one or many of these platforms. A general principle that organizations try to use is to not have two tools for the same job. That being said, if an organization has a federated IT department, whether due to past acquisitions, geographic needs, or other reasons, each of these separate IT groups may have their own standards. In addition to the general purpose application server, another common service platform is the automated process platform, frequently associated with the use of BPEL technologies. This is a new breed of development platform tailored towards the orchestration of other services. Typically, it involves a graphical modeler, providing a drag-and-drop metaphor for connecting services in an orchestrated sequence, such as shown in the following figure: Depending on the product chosen, it may include some out-of-the-box adapters for doing common activities, such as retrieving records from a relational database, publishing messages to an enterprise messaging systems, or sending an email message. The recommended approach for determining the appropriate number of service platforms is to first determine the service types that an organization may need to provide. A service type is a class of service with a specific set of capabilities that may lend itself to specific technologies. Common types for which you may consider having specific platforms include: Composite services Automated (Orchestrated) processes Integration services Presentation services Management services Information services Content subscription services General business services Composite services are, as the name implies, services that are built from other services. This typically involves combining the output of several services and combining it to be delivered to a consumer through a single service. Automated processes, as was discussed earlier, are about the orchestration of a collection of services to perform a higher level function. Frequently, composite services can be thought of as a subset of the overall space of automated processes. Integration services are services that are geared towards communication with third-party systems, such as SAP and Oracle. These are frequently associated with Enterprise Application Integration, or EAI, technologies. While EAI, as a category, has lost favor, there is still plenty of need for integration technologies in communicating with these complex application platforms. Presentation services are services that provide user interface functionality, whether simply content in a presentation-friendly format, or fully featured presentation components suitable for composition in a portal context. Management services are services that are geared towards the management of IT systems, typically leveraging technologies like SNMP (Simple Network Management Protocol) and JMX (Java Management Extensions) for communication. Information services are services that are intended for data access and manipulation. These are typically marketed as Data Service Platforms or Enterprise Information Integration products. Content subscription services, such as news feeds, are intended to provide content to consumers on a subscription basis using technologies such as RSS (Really Simple Syndication) and Atom. General business services is the final service type, and is intended to be the catch-all for other services that don't cleanly fit into any of the previous categories. These would normally be implemented using a general purpose application server platform.
Read more
  • 0
  • 0
  • 1272

article-image-dotnetnukeskinning-creating-containers
Packt
15 Oct 2009
9 min read
Save for later

DotNetNukeSkinning: Creating Containers

Packt
15 Oct 2009
9 min read
Creating our first container In VWD (Visual Web Developer), from the Solution Explorer window, find the following location and create a new folder called FirstSkin: ~/Portals/_default/Containers/ Add a new item by right-clicking on this new folder. Add a new HTML file and call it Container.htm. Similarly, add a CSS and an XML file, Container.css and Container.xml respectively. Clear out all the code in the newly created files that VWD initializes it with. DNN tokens for containers These tokens, however, have applied mostly to creating skins, not containers. Containers have their own set of tokens to use here. The following is a listing of them. We'll be working with them throughout the rest of this article. Actions: This is the menu that will appear when you hover over the triangle. It is traditionally placed to the left of the icon and title of the module. Title: As you can imagine, this is the title of the module displayed in the container. This is usually placed at the top. Icon: Most of the modules don't have an icon, but many of the administrative pages in DotNetNuke have icons assigned to them. You can always assign icons to your modules, but none of them are set by default. Visibility: This skin object is traditionally displayed as a plus or a minus sign inside a small square. It acts as a toggle to show or hide/collapse or expand the content of the module. Content Pane: Similar to when we created our skin, this is where the content goes. The difference here is that we have only one content pane. It is required in order to make the container work. LINKACTIONS: This isn't used very often in containers. It is a listing of links that gives you access to the same things contained in the ACTIONS skin object. PRINTMODULE: This is the small printer icon you see in the preceding screenshot. When you click on it, it allows you to print the contents of the module. ACTIONBUTTON: This skin object allows you to display items as links or image links to commonly used items found in the actions menu. The last item on that list, the ActionButton, is different from the others in that we can have several uses of it in different ways. When used as a token, you would place them in your container HTM file as [ACTIONBUTTON:1], [ACTIONBUTTON:2], [ACTIONBUTTON:3], and so on. As you can imagine, we would define what each of these action buttons refer to. We do this in the XML file with an attribute called CommandName. For example, the following is a code snippet of what you could have to add as an action button: <Objects> <Object> <Token>[ACTIONBUTTON:1]</Token> <Settings> <Setting> <Name>CommandName</Name> <Value>AddContent.Action</Value> </Setting> <Setting> <Name>DisplayIcon</Name> <Value>True</Value> </Setting> <Setting> <Name>DisplayLink</Name> <Value>True</Value> </Setting> </Settings> </Object> Looking at the CommandName attribute, we can have several values which will determine which of the action buttons will be inserted into our container. The following is a listing: AddContent.Action: This typically allows you to add content, or in this case of the Text/HTML module, edit the content of the module. SyndicateModule.Action: This is an XML feed button, if it is supported by the module. PrintModule.Action: This is the printer icon allowing the users to print the content of the module. Yes, this is the second way of adding it as we already have the PRINTMODULE token. ModuleSettings.Action: This is a button/link which takes you to the settings of the module. ModuleHelp.Action—This is a help question mark icon/link that we've seen in the preceding screenshots. Adding to the container Now that we know what can be added, let's add them to our new container. We'll start off with the HTM file and then move on to the CSS file. In our HTM file, add the following code. This will utilize all of the container tokens with the exception of the action buttons, which we'll add soon. <div style="background-color:White;"> ACTIONS[ACTIONS] <hr /> TITLE[TITLE] <hr /> ICON[ICON] <hr /> VISIBILITY[VISIBILITY] <hr /> CONTENTPANE[CONTENTPANE] <hr /> LINKACTIONS[LINKACTIONS] <hr /> PRINTMODULE[PRINTMODULE]</div> Go to the skin admin page (Admin | Skins on the menu). Now that we have a container in the folder called FirstSkin, we'll now get a little added benefit: When you select FirstSkin as the skin to deal with, the container will be selected as well, so you can work with them as a unit or as a Skin Package. Go ahead, parse the skin package and apply our FirstSkin container. Go to the Home page. It may not be pretty, but pretty is not what we were looking for. This container, as it sits, gives us a better illustration of how each token is displayed with a convenient label beside each. There are a few things to point out here, besides we'll be taking out our handy labels and putting in some structure. Our module has no icon, so we won't see one here. If you go to the administrative pages, you will see the icon. The LINKACTIONS is a skin object that you'll use if you don't want to use the action menu ([ACTIONS]). Table Structure The structure of our container will be quite similar to how we laid out our skin. Let's start off with a basic table layout. We'll have a table with three rows. The first row will be for the header area which will contain things like the action menu, the title, icon, and so forth. The second row will be for the content. The third row will be for the footer items, like the printer and edit icon/links. Both the header and footer rows will have nested tables inside to have independent positioning within the cells. The markup which defines these three rows has been highlighted: <table border="0" cellpadding="0" cellspacing="0" class="ContainerMainTable"> <tr> <td style="padding:5px;"> <table border="0" cellpadding="0" cellspacing="0" class="ContainerHeader"> <tr> <td style="width:5px;">[ACTIONS]</td> <td style="width:5px;">[ICON]</td> <td align="left">[TITLE]</td> <td style="width:5px;padding-right:5px;" valign="top">[VISIBILITY]</td> <td style="width:5px;">[ACTIONBUTTON:4]</td> </tr> </table> </td> </tr> <tr> <td class="ContainerContent"> [CONTENTPANE] </td> </tr> <tr> <td style="padding:5px;"> <table border="0" cellpadding="0" cellspacing="0" class="ContainerFooter"> <tr> <td>[ACTIONBUTTON:1]</td> <td>[ACTIONBUTTON:2]</td> <td></td> <td>[ACTIONBUTTON:3]</td> <td style="width:10px;">[PRINTMODULE]</td> </tr> </table> </td> </tr></table> Making necessary XML additions The action buttons we used will not work unless we add items to our XML file. For each of our action buttons, we'll add a token element, then a few setting elements for each. There are three specific settings we'll set up for each: CommandName, DisplayIcon, and DisplayLink. See the following code: <Objects> <Object> <Token>[ACTIONBUTTON:1]</Token> <Settings> <Setting> <Name>CommandName</Name> <Value>AddContent.Action</Value> </Setting> <Setting> <Name>DisplayIcon</Name> <Value>True</Value> </Setting> <Setting> <Name>DisplayLink</Name> <Value>True</Value> </Setting> </Settings> </Object> <Object> <Token>[ACTIONBUTTON:2]</Token> <Settings> <Setting> <Name>CommandName</Name> <Value>SyndicateModule.Action</Value> </Setting> <Setting> <Name>DisplayIcon</Name> <Value>True</Value> </Setting> <Setting> <Name>DisplayLink</Name> <Value>False</Value> </Setting> </Settings> </Object> <Object> <Token>[ACTIONBUTTON:3]</Token> <Settings> <Setting> <Name>CommandName</Name> <Value>ModuleSettings.Action</Value> </Setting> <Setting> <Name>DisplayIcon</Name> <Value>True</Value> </Setting> <Setting> <Name>DisplayLink</Name> <Value>False</Value> </Setting> </Settings> </Object> <Object> <Token>[ACTIONBUTTON:4]</Token> <Settings> <Setting> <Name>CommandName</Name> <Value>ModuleHelp.Action</Value> </Setting> <Setting> <Name>DisplayIcon</Name> <Value>True</Value> </Setting> <Setting> <Name>DisplayLink</Name> <Value>False</Value> </Setting> </Settings> </Object></Objects> The CommandName is the attribute that determines which action button is used by the ordinal numeric values. Notice that these four action buttons use different CommandName values as you might expect. The DisplayIcon attribute is a Boolean (true/false or yes/no) value indicating whether or not the icon is displayed; the DisplayLink is similar and used for setting if the text is used as a link. A good example of both is the EditText ([ACTIONBUTTON:1]) in our Text/HTML module on the Home page. Notice that it has both the icon and the text as links to add/edit the content of the module.
Read more
  • 0
  • 0
  • 6142

article-image-layout-dojo-part-2
Packt
15 Oct 2009
12 min read
Save for later

Layout in Dojo: Part 2

Packt
15 Oct 2009
12 min read
GridContainer There are a lot of sites available that let you add a lot of rss feeds and assorted widgets to a personal page, and which then also let you arrange them by dragging the widgets themselves around the page. One of the most known examples is iGoogle, Google's personal homepage for users with a staggering amount of widgets that are easy to move around. This functionality is called a GridContainer in Dojo. If you're not familiar with the concept and have never used a service which lets you rearrange widgets, it works like this: The GridContainer defines a number of different columns, called zones. Each column can contain any number of child widgets, including other containers (like AccordionContainer or BorderContainer). Each child widget becomes draggable and can be dragged into a new position within its own column, or dragged to a new position in another column. As the widget gets dragged, it uses a semi-transparent 'avatar'. As the widget gets dragged, possible target drop zones open up and close themselves dynamically under the cursor, until the widget is dropped on one of them. When a widget is dropped, the target column automatically rearranges itself to make the new widget fit. Here is an example from test_GridContainer.html in /dojox/layout/tests/. This is what the GridContainer looks like from the beginning: It has three columns (zones) defined which contain a number of child widgets. One of them is a Calendar widget, which is then dragged to the second column from its original position in the third: Note the new target area being offered by the second column. This will be closed again if we continue to move the cursor over to the first column. Also, in the example above, transparency of 1.0 (none) is added to the avatar, which looks normal. Finally, the widget is dropped onto the second column, both the source and target column arrange their widgets according to whether one has been added or removed. The implications of this is that it becomes very simple to create highly dynamical interfaces. Some examples might be: An internal "dashboard" for management or other groups in the company which needs rearrangeable views on different data sources. Portlets done right. Using dojox.charting to create different diagrammatic views on data sources read from the server, letting the user create new diagrams and rearranging them in patterns or groups meaningful to the current viewer. A simple front-end for a CMS-system, where the editor widget is used to enter text, and the user can add, delete or change paragraphs as well as dragging them around and rearranging their order. An example of how to create a GridContainer using markup (abbreviated) is as follows: <div id="GC1" dojoType="dojox.layout.GridContainer" nbZones="3" opacity="0.7" allowAutoScroll="true" hasResizableColumns="false" withHandles="true" acceptTypes="dijit.layout.ContentPane, dijit.TitlePane, dijit.ColorPalette, dijit._Calendar"><div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane">Content Pane n?1 !</div><div dojoType="dijit.TitlePane" title="Ergo">Non ergo erunt homines deliciis ...</div><div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane">Content Pane n?2 !</div><div dojoType="dijit.layout.ContentPane" title="Intellectum">Intellectum est enim mihi quidem in multis, et maxime in me ipso, sed paulo ante in omnibus, cum M....</div><div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane">Content Pane n?3 !</div><div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane">Content Pane n?4 !</div><div dojoType="dijit._Calendar"></div></div> The GridContainer wraps all of its contents.These are not added is not added in a hierarchical manner, but instead all widgets are declared inside the GridContainer element. When the first column's height is filled, the next widget in the list gets added to the next column, and so on. This is a quite unusual method of layout, and we might see some changes to this mode of layout since the GridContainer is very much beta [2008]. The properties for the GridContainer are the following: //i18n: Object//Contain i18n ressources.i18n: null,//isAutoOrganized: Boolean://Define auto organisation of children into the grid container.isAutoOrganized : true,//isRightFixed: Boolean//Define if the right border has a fixed size.isRightFixed:false,//isLeftFixed: Boolean//Define if the left border has a fixed size.isLeftFixed:false,//hasResizableColumns: Boolean//Allow or not resizing of columns by a grip handle.hasResizableColumns:true,//nbZones: Integer//The number of dropped zones.nbZones:1,//opacity: Integer//Define the opacity of the DnD Avatar.opacity:1,//minColWidth: Integer//Minimum column width in percentage.minColWidth: 20,//minChildWidth: Integer//Minimun children with in pixel (only used for IE6 that doesn't//handle min-width css propertyminChildWidth : 150,//acceptTypes: Array//The gridcontainer will only accept the children that fit to//the types.//In order to do that, the child must have a widgetType or a//dndType attribute corresponding to the accepted type.acceptTypes: [],//mode: String//location to add columns, must be set to left or right(default)mode: "right",//allowAutoScroll: Boolean//auto-scrolling enable inside the GridContainerallowAutoScroll: false,//timeDisplayPopup: Integer//display time of popup in milisecondstimeDisplayPopup: 1500,//isOffset: Boolean//if true : Let the mouse to its original location when moving//(allow to specify it proper offset)//if false : Current behavior, mouse in the upper left corner of//the widgetisOffset: false,//offsetDrag: Object//Allow to specify its own offset (x and y) onl when Parameter//isOffset is trueoffsetDrag : {}, ////withHandles: Boolean//Specify if there is a specific drag handle on widgetswithHandles: false,//handleClasses: Array//Array of classes of nodes that will act as drag handleshandleClasses : [], The property isAutoOrganized, which is set to true by default, can be set to false, which will leave holes in your source columns, and require you to manage the space in the target columns yourself. The opacity variable is the opacity for the 'avatar' of the dragged widget, where 1 is completely solid, and 0 is completely transparent. The hasResizableColumns variable also adds SplitContainer/BorderContainer splitters between columns, so that the user can change the size ratio between columns. The minColWidt/minChildWidth variables manage the minimum widths of columns and child widgets in relation to resizing events. The AcceptTypes variable is an important property, which lets you define which classes you allow to be dropped on a column. In the above example code, that string is set to dijit.layout.ContentPane, dijit.TitlePane, dijit.ColorPalette, dijit._Calendar. This makes it impossible to drop an AccordionContainer on a column. The reason for this is that certain things would want to be fixed, like status bars or menus, but still inside one of the columns. The withHandles variable can be set to true if you want each widget to get a visible 'drag handle' appended to it. RadioGroup The source code of dojox.layout.RadioGroup admits that it probably is poorly named, because it has little to do with radio buttons or groups of them, per se, even if this was probably the case when it was conceived. The RadioGroup extends the StackContainer, doing something you probably had ideas about the first time you saw it – adding flashy animations when changing which child container is shown. One example of how to use StackContainer and its derivatives is an information box for a list of friends. Each information box is created as a ContentPane which loads its content from a URL. As the user clicks on or hovers over the next friend on a nearby list, an event is triggered to show the next item (ContentPane) in the stack. Enter the RadioGroup, which defines its own set of buttons that mirror the ContentPanes which it wraps. The unit test dojox/layout/tests/test_RadioGroup.html defines a small RadioGroup in the following way: <div dojoType="dojox.layout.RadioGroup" style="width:300px; height:300px; float:left;" hasButtons="true"><div dojoType="dijit.layout.ContentPane" title="Dojo" class="dojoPane" style="width:300px; height:300px; "></div><div dojoType="dijit.layout.ContentPane" title="Dijit" class="dijitPane" style="width:300px; height:300px; "></div><div dojoType="dijit.layout.ContentPane" title="Dojox" class="dojoxPane" style="width:300px; height:300px; "></div></div> As you can see, it does not take much space. In the test, the ContentPanes are filled with only the logos for the different parts of Dojo, defined as background images by CSS classes. The RadioGroup iterates over each child ContentPane, and creates a "hover button" for it, which is connected to an event handler which manages the transition, so if you don' t have any specific styling for your page and just want to get a quick mock-up done, the RadioGroup is very easy to work with. The default RadioGroup works very much like its parent class, StackContainer, mostly providing a simple wrapper that generates mouseover buttons. In the same file that defines the basic RadioGroup, there are two more widgets: RadioGroupFade and RadioGroupSlide. These have exactly the same kind of markup as their parent class, RadioGroup. RadioGroupFade looks like this in its entirety: dojo.declare("dojox.layout.RadioGroupFade", dojox.layout.RadioGroup, { // summary: An extension on a stock RadioGroup, that fades the //panes. _hideChild: function(page){ // summary: hide the specified child widget dojo.fadeOut({ node:page.domNode, duration:this.duration, onEnd: dojo.hitch(this,"inherited", arguments) }).play(); }, _showChild: function(page){ // summary: show the specified child widget this.inherited(arguments); dojo.style(page.domNode,"opacity",0); dojo.fadeIn({ node:page.domNode, duration:this.duration }).play(); }}); As you can see, all it does is override two functions from RadioGroup which manage how to show and hide child nodes upon transitions. The basic idea is to use the integral Dojo animations fadeIn and fadeOut for the effects. The other class, RadioGroupSlide, is a little bit longer, but not by much. It goes beyond basic animations and uses a specific easing function. In the beginning of its definition is this variable: // easing: Function// A hook to override the default easing of the pane slides.easing: "dojo.fx.easing.backOut", Later on, in the overridden _hide and _showChild functions, this variable is used when creating a standalone animation: ...this._anim = dojo.animateProperty({ node:page.domNode, properties: { left: 0, top: 0 }, duration: this.duration, easing: this.easing, onEnd: dojo.hitch(page,function(){ if(this.onShow){ this.onShow(); } if(this._loadCheck){ this._loadCheck(); } })});this._anim.play();   What this means is that it is very simple to change (once again) what kind of animation is used when hiding the current child and showing next, which can be very usable. Also, you can see that it is very simple to create your own subclass widget out of RadioGroup which can use custom actions when child nodes are changed. ResizeHandle The ResizeHandle tucks a resize handle, as the name implies, into the corner of an existing element or widget. The element which defines the resize handle itself need not be a child element or even adjacent to the element which is to receive the handle. Instead the id of the target element is defined as an argument to the ResizeHandle as shown here: <div dojoType="dijit.layout.ContentPane" title="Test window" style="width: 300px; height: 200px; padding:10px; border: 1px solid #dedede; position: relative; background: white;" id="testWindow"> ...<div id="hand1" dojoType="dojox.layout.ResizeHandle" targetId="testWindow"></div> </div> In this example, a simple ContentPane is defined first, with some custom styling to make it stand out a little bit. Further on in the same pages comes a ResizeHandle definition which sets the targetId property of the newly created ResizeHandle to that of the ContentPane ('testWindow'). The definition of the ResizeHandle class shows some predictable goodies along with one or two surprises: //targetContainer: DomNode//over-ride targetId and attch this handle directly to a//reference of a DomNodetargetContainer: null,//resizeAxis: String//one of: x|y|xy limit resizing to a single axis, default to xy ...resizeAxis: "xy",//activeResize: Boolean//if true, node will size realtime with mouse movement,//if false, node will create virtual node, and only resize target//on mouseUp.activeResize: false,//activeResizeClass: String//css class applied to virtual resize node.activeResizeClass: 'dojoxResizeHandleClone',//animateSizing: Boolean//only applicable if activeResize = false. onMouseup, animate the//node to the new size.animateSizing: true,//animateMethod: String//one of "chain" or "combine" ... visual effect only.combine will "scale"//node to size, "chain" will alter width, then heightanimateMethod: 'chain',//animateDuration: Integer//time in MS to run sizing animation. if animateMethod="chain",//total animation playtime is 2*animateDuration.animateDuration: 225,//minHeight: Integer//smallest height in px resized node can beminHeight: 100,//minWidth: Integer//smallest width in px resize node can beminWidth: 100, As could be expected, it is simple to change if the resizing is animated during mouse move or afterwards (activeResize: true/false). If afterwards, the animateDuration declares in milliseconds the length of the animation. A very useful property is the ability to lock the resizing action to just one of the two axes. The resizeAxis property defaults to xy, but can be set to only x or only y as well. Both restricts resizing to only one axis and also changes the resize cursor to show correct feedback to which axis is 'active' at the moment. If you at any point want to remove the handle, calling destroy() on it will remove it from the target node without any repercussions.
Read more
  • 0
  • 0
  • 3398

article-image-documenting-our-application-apache-struts-2-part-1
Packt
15 Oct 2009
12 min read
Save for later

Documenting our Application in Apache Struts 2 (part 1)

Packt
15 Oct 2009
12 min read
Documenting Java Everybody knows the basics of documenting Java, so we won't go into much detail. We'll talk a bit about ways of writing code whose intention is clear, mention some Javadoc tricks we can use, and highlight some tools that can help keep our code clean. Clean code is one of the most important ways we can document our application. Anything we can do to increase readability will reduce confusion later (including our own). Self-documenting code We've all heard the myth of self-documenting code. In theory, code is always clear enough to be easily understood. In reality, this isn't always the case. However, we should try to write code that is as self-documenting as possible. Keeping non-code artifacts in sync with the actual code is difficult. The only artifact that survives a project is the executable, which is created from code, not comments. This is one of the reasons for writing self-documenting code. (Annotations, XDoclet, and so on, make that somewhat less true.) There are little things we can do throughout our code to make our code read as much like our intent as possible and make extraneous comments just that: extraneous. Document why, not what Over-commenting wastes everybody's time. Time is wasted in writing a comment, reading it, keeping that comment in sync with the code, and, most importantly, a lot of time is wasted when a comment is not accurate. Ever seen this? a += 1; // increment a This is the most useless comment in the world. Firstly, it's really obvious we're incrementing something, regardless of what that something is. If the person reading our code doesn't know what += is, then we have more serious problems than them not knowing that we're incrementing, say, an array index. Secondly, if a is an array index, we should probably use either a more common array index or make it obvious that it's an array index. Using i and j is common for array indices, while idx or index is less common. It may make sense to be very explicit in variable naming under some circumstances. Generally, it's nice to avoid names such as indexOfOuterArrayOfFoobars. However, with a large loop body it might make sense to use something such as num or currentIndex, depending on the circumstances. With Java 1.5 and its support for collection iteration, it's often possible to do away with the index altogether, but not always. Make your code read like the problem Buzzphrases like Domain Specific Languages (DSLs) and Fluent Interfaces are often heard when discussing how to make our code look like our problem. We don't necessarily hear about them as much in the Java world because other languages support their creation in more "literate" ways. The recent interest in Ruby, Groovy, Scala, and other dynamic languages have brought the concept back into the mainstream. A DSL, in essence, is a computer language targeted at a very specific problem. Java is an example of a general-purpose language. YACC and regular expressions are examples of DSLs that are targeted at creating parsers and recognizing strings of interest respectively. DSLs may be external, where the implementing language processes the DSL appropriately, as well as internal, where the DSL is written in the implementing language itself. An internal DSL can also be thought of as an API or library, but one that reads more like a "little language". Fluent interfaces are slightly more difficult to define, but can be thought of as an internal DSL that "flows" when read aloud. This is a very informal definition, but will work for our purposes Java can actually be downright hostile to some common DSL and fluent techniques for various reasons, including the expectations of the JavaBean specification. However, it's still possible to use some of the techniques to good effect. One typical practice of fluent API techniques is simply returning the object instance in object methods. For example, following the JavaBean specification, an object will have a setter for the object's properties. For example, a User class might include the following: public class User {private String fname;private String lname;public void setFname(String fname) { this.fname = fname; }public void setLname(String lname) { this.lname = lname; }} Using the class is as simple as we'd expect it to be: User u = new User();u.setFname("James");u.setLname("Gosling"); Naturally, we might also supply a constructor that accepts the same parameters. However, it's easy to think of a class that has many properties making a full constructor impractical. It also seems like the code is a bit wordy, but we're used to this in Java. Another way of creating the same functionality is to include setter methods that return the current instance. If we want to maintain JavaBean compatibility, and there are reasons to do so, we would still need to include normal setters, but can still include "fluent" setters as shown here: public User fname(String fname) {this.fname = fname;return this;}public User lname(String lname) {this.lname = lname;return this;} This creates (what some people believe is) more readable code. It's certainly shorter: User u = new User().fname("James").lname("Gosling"); There is one potential "gotcha" with this technique. Moving initialization into methods has the potential to create an object in an invalid state. Depending on the object this may not always be a usable solution for object initialization. Users of Hibernate will recognize the "fluent" style, where method chaining is used to create criteria. Joshua Flanagan wrote a fluent regular expression interface, turning regular expressions (already a domain-specific language) into a series of chained method calls: Regex socialSecurityNumberCheck =new Regex(Pattern.With.AtBeginning.Digit.Repeat.Exactly(3).Literal("-").Repeat.Optional.Digit.Repeat.Exactly(2).Literal("-").Repeat.Optional.Digit.Repeat.Exactly(4).AtEnd); Whether or not this particular usage is an improvement is debatable, but it's certainly easier to read for the non-regex folks. Ultimately, the use of fluent interfaces can increase readability (by quite a bit in most cases), may introduce some extra work (or completely duplicate work, like in the case of setters, but code generation and/or IDE support can help mitigate that), and may occasionally be more verbose (but with the benefit of enhanced clarity and IDE completion support). Contract-oriented programming Aspect-oriented programming (AOP) is a way of encapsulating cross-cutting functionality outside of the mainline code. That's a mouthful, but essentially it means is that we can remove common code that is found across our application and consolidate it in one place. The canonical examples are logging and transactions, but AOP can be used in other ways as well. Design by Contract (DbC) is a software methodology that states our interfaces should define and enforce precise specifications regarding operation. "Design by Contract" is a registered trademark of Interactive Software Engineering Inc. Other terms include Programming by Contract (PbC) or Contract Oriented Programming (COP). How does COP help create self-documenting code? Consider the following portion of a stack implementation: public void push(final Object o) {stack.add(o);} What happens if we attempt to push a null? Let's assume that for this implementation, we don't want to allow pushing a null onto the stack. /*** Pushes non-null objects on to stack.*/public void push(final Object o) {if (o == null) return;stack.add(o);} Once again, this is simple enough. We'll add the comment to the Javadocs stating that null objects will not be pushed (and that the call will fail/return silently). This will become the "contract" of the push method—captured in code and documented in Javadocs. The contract is specified twice—once in the code (the ultimate arbiter) and again in the documentation. However, the user of the class does not have proof that the underlying implementation actually honors that contract. There's no guarantee that if we pass in a null, it will return silently without pushing anything. The implied contract can change. We might decide to allow pushing nulls. We might throw an IllegalArgumentException or a NullPointerException on a null argument. We're not required to add a throwsclause to the method declaration when throwing runtime exceptions. This means further information may be lost in both the code and the documentation. Eiffel has language-level support for COP with the require/do/ensure/end construct. It goes beyond the simple null check in the above code. It actively encourages detailed pre- and post-condition contracts. An implementation's push() method might check the remaining stack capacity before pushing. It might throw exceptions for specific conditions. In pseudo-Eiffel, we'd represent the push() method in the following way: push (o: Object) require o /= null do -- push end A stack also has an implied contract. We assume (sometimes naively) that once we call the push method, the stack will contain whatever we pushed. The size of the stack will have increased by one, or whatever other conditions our stack implementation requires. Java, of course, doesn't have built-in contracts. However, it does contain a mechanism that can be used to get some of the benefits for a conceptually-simple price. The mechanism is not as complete, or as integrated, as Eiffel's version. However, it removes contract enforcement from the mainline code, and provides a way for both sides of the software to specify, accept, and document the contracts themselves. Removing the contract information from the mainline code keeps the implementation clean and makes the implementation code easier to understand. Having programmatic access to the contract means that the contract could be documented automatically rather than having to maintain a disconnected chunk of Javadoc. SpringContracts SpringContracts is a beta-level Java COP implementation based on Spring's AOP facilities, using annotations to state pre- and post-contract conditions. It formalizes the nature of a contract, which can ease development. Let's consider our VowelDecider that was developed through TDD. We can also use COP to express its contract (particularly the entry condition). This is a method that doesn't alter state, so post conditions don't apply here. Our implementation of VowelDecider ended up looking (more or less) like this: public boolean decide(final Object o) throws Exception {if ((o == null) || (!(o instanceof String))) {throw new IllegalArgumentException("Argument must be a non-null String.");}String s = (String) o;return s.matches(".*[aeiouy]+.*");} Once we remove the original contract enforcement code, which was mixed with the mainline code, our SpringContracts @Precondition annotation looks like the following: @Precondition(condition="arg1 != null && arg1.class.name == 'java.lang.String'",message="Argument must be a non-null String")public boolean decide(Object o) throws Exception {String s = (String) o;return s.matches(".*[aeiouy]+.*");} The pre-condition is that the argument must not be null and must be (precisely) a string. (Because of SpringContracts' Expression Language, we can't just say instanceof String in case we want to allow string subclasses.) We can unit-test this class in the same way we tested the TDD version. In fact, we can copy the tests directly. Running them should trigger test failures on the null and non-string argument tests, as we originally expected an IllegalArgumentException. We'll now get a contract violation exception from SpringContracts. One difference here is that we need to initialize the Spring context in our test. One way to do this is with JUnit's @BeforeClass annotation, along with a method that loads the Spring configuration file from the classpath and instantiates the decider as a Spring bean. Our class setup now looks like this: @BeforeClass public static void setup() {appContext = new ClassPathXmlApplicationContext("/com/packt/s2wad/applicationContext.xml");decider = (VowelDecider)appContext.getBean("vowelDecider");} We also need to configure SpringContracts in our Spring configuration file. Those unfamiliar with Spring's (or AspectJ's) AOP will be a bit confused. However, in the end, it's reasonably straightforward, with a potential "gotcha" regarding how Spring does proxying. <aop:aspectj-autoproxy proxy-target-class="true"/><aop:config><aop:aspect ref="contractValidationAspect"><aop:pointcut id="contractValidatingMethods"expression="execution(*com.packt.s2wad.example.CopVowelDecider.*(..))"/><aop:around pointcut-ref="contractValidatingMethods"method="validateMethodCall"/></aop:aspect></aop:config><bean id="contractValidationAspect"class="org.springcontracts.dbc.interceptor.ContractValidationInterceptor"/><bean id="vowelDecider"class="com.packt.s2wad.example.CopVowelDecider" /> The SpringContracts documentation goes into it a bit more and the Spring documentation contains a wealth of information regarding how AOP works in Spring. The main difference between this and the simplest AOP setup is that our autoproxy target must be a class, which requires CGLib. This could also potentially affect operation. The only other modification is to change the exception we're expecting to SpringContract's ContractViolationCollectionException, and our test starts passing. These pre- and post-condition annotations use the @Documented meta-annotation, so the SpringContracts COP annotations will appear in the Javadocs. It would also be possible to use various other means to extract and document contract information. Getting into details This mechanism, or its implementation, may not be a good fit for every situation. Runtime performance is a potential issue. As it's just some Spring magic, it can be turned off by a simple configuration change. However, if we do, we'll lose the value of the on-all-the-time contract management. On the other hand, under certain circumstances, it may be enough to say that once the contracts are consistently honored under all of the test conditions, the system is correct enough to run without them. This view holds the contracts more as an acceptance test, rather than as run-time checking. Indeed, there is an overlap between COP and unit testing as the way to keep code honest. As unit tests aren't run all the time, it may be reasonable to use COP as a temporary runtime unit test or acceptance test.
Read more
  • 0
  • 0
  • 2808

article-image-monitoring-cups-part2
Packt
15 Oct 2009
7 min read
Save for later

Monitoring CUPS- part2

Packt
15 Oct 2009
7 min read
How SNMP Behaves in the CUPS Web Interface In the CUPS web interface under the Administration tab, the option Find New Printers is used to discover printers that support SNMPv1. This will search and list the available network printers. The discovery of printers is based on the directive configuration done in the /etc/cups/snmp.conf file. On the basis of the search list, you can add a printer using the Add This Printer option. The process is very similar to the Add Printer wizard. Overview of Basic Debugging in CUPS-SNMP In the snmp.conf, we started discussion about various debugging levels in CUPS support. If the directive DebugLevel is set to anything other than 0, you will get the output accordingly. The debugging mode can be made active using the following command. As the SNMP backend supports debugging mode, the command for setting up debugging mode changes depending on the shell prompt. The SNMP backend is located at /usr/lib/cups/backend/snmp when using the Bourne, Bash, Z, or Korn shells. The following command will output verbose debugging information into the cupssnmp.log file when using those shells: $CUPS_DEBUG_LEVEL=1 /usr/lib/cups/backend/snmp 2>&1 | tee cupssnmp.log On Mac OS X, the SNMP backend is located /usr/libexec/cups. The following command will be used: $CUPS_DEBUG_LEVEL=1 /usr/libexec/cups/backend/snmp 2>&1 | tee cupssnmp.log If you are using the C or Tcsh shells, you can use the following command. $(setenv CUPS_DEBUG_LEVEL 1; /usr/lib/cups/backend/snmp) |& tee cupssnmp.log An example of the output might look like this: DEBUG: Scanning for devices in "public" via "@LOCAL"... DEBUG: 0.000 Sending 46 bytes to 192.168.0.255... DEBUG: 0.001 Received 50 bytes from 192.168.0.250... DEBUG: community="public" DEBUG: request-id=1213875587 DEBUG: error-status=0 DEBUG: 1.001 Scan complete! The above output shows that doesn't find any printer at the specified DeviceURI. The above shows the output at the basic debugging level; more information can be found if we use level 2 or 3. Overview of mailto.conf The CUPS provides the facility to send notifications through email. It can be done by integrating the local mail server with CUPS. The configuration file is /etc/cups/mailto.conf, and contains several directives and the characteristics and behavior of the local mail server and email notification for CUPS. We normally use each of the following directives in our daily communication done through mail. The Cc Directive The directive Cc (carbon copy) is used to specify an additional recipient for all email notifications. By default, the value directive is not set and the email is sent only to the administrator. The following examples shows that how email IDs can be specified with this directive. Cc kajol@cupsgrp.com Cc Kajol Shah <ks@cupsgrp.com> The From Directive This directive is used to specify the sender's name in the email notifications. By default, the ServerAdmin address specified in the cupsd.conf file is used. The following are some examples that show how the sender's email is specified with this directive: From cupsadmin@cupsgrp.com From Your CUPS Printer <cupsadmin@cupsgrp.com> The Sendmail Directive The directive Sendmail specifies the command to run and deliver an email locally. If there is an SMTPServer directive, then this directive cannot be used. If both directives appear in the mailto.conf file, then only the last directive is used. The following example shows how this directive can be specified. The default value for this directive is /usr/sbin/sendmail. Sendmail /usr/sbin/sendmail Sendmail /usr/lib/sendmail -bm -i The SMTPServer Directive This directive is used to specify an IP address or hostname of an SMTP mail server. As we have seen previously, this directive cannot be used with the Sendmail directive, and if both Sendmail and SMTPServer directives don't appear in the mailto.conf file, then the default Sendmail will be considered. The following are examples of the SMTP server: SMTPServer mail.mailforcups.com SMTPServer 192.168.0.17 The Subject Directive The Subject directive is used if you want to prefix some text to the subject line in each email that CUPS sends out. The following examples show how a prefix can be specified with this directive. By default, no prefix string is added: Subject [CUPS_ALERTS] Subject URGENT CUPS NOTICE Monitoring SNMP Printers As discussed, CUPS supports SNMPv1 for discovering SNMP enabled printers. This Simple Network Management Protocol-SNMP is used for managing networking printers. We can use any network monitoring tools that supports SNMP for monitoring these SNMP-enabled printers. You can check various open-source network monitoring tools at: http://www.openxtra.co.uk/network-management/monitor/open-source/ I would recommend you to use Cacti, which is a frontend to an RRDTool (Round Robin Database Tool) that collects and stores data in a MySQL database. The frontend is completely written in PHP. The advantage of Cacti over other network monitoring tool is that it has built-in SNMP capabilities and like other monitoring tools such as Nagios, it has its internal mechanism to check certain aspects of the infrastructure. It also provides a frontend for maintaining customized scripts, which an administrator normally creates. But the most important factor is that it is much easier to configure than Nagios. RRDTool is a system that stores high performance logging data and displays related time-series graphs. You can get more information about RRDTool from: http://oss.oetiker.ch/rrdtool/ Downloading and Installing Cacti The pre-requisites of Cacti include MySQL database, PHP, RRDTool, net-snmp, and PHP supported web servers such as Apache or IIS. You can get detailed information about the pre-requisites for Cacti installation at: http://www.cacti.net/downloads/docs/html/requirements.html The current stable release of Cacti is 0.8.7b. You can download various versions of Cacti for different platforms from: http://www.cacti.net/download_cacti.php You can get installation information for Cacti and its pre-requisites on the UNIX/Linux platform from: http://www.cacti.net/downloads/docs/html/install_unix.html The following URL will help you install Cacti on the Windows platform: http://www.cacti.net/downloads/docs/html/install_windows.html You can proceed further by clicking on Next. The next screen shows two options for a new install or an upgrade. If you want to do fresh installation, use the option New Install and click on Next. The screen also displays some useful information such as database user, database hostname, database name, and OS that was specified while configuring Cacti. If you want to upgrade the Cacti, follow the instructions mentioned here: http://www.cacti.net/downloads/docs/html/upgrade.html And then select the upgrade from cacti-current-version option and click on Next to proceed further. The following screen appears, which shows the recommended path of the binary files such as RRDTool, PHP, snmpwalk, snmpgetV, snmpbulkwalk, snmpgetnext, and information related to the Cacti log file and versions for net-snmp and RRDTool. If you found any change in the path with your installation, it should be modified first. Otherwise, Cacti may not work properly. Click on Finish to complete the installation procedure. Once the installation is finished and the next screen will ask for authentication. You need to use the username and the password mentioned in your database configuration to log into a Cacti application: You can use default login information to log in for the first time. Once you click on Login, the next screen will force you to change your password. Once the password is changed, you can see the main page of Cacti that contains two major tabs: console and graphs apart from other generalized options. The console tab contains various options related to the template and graphs management, whereas the graphs tab contains related graphs.  
Read more
  • 0
  • 0
  • 8288
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-jquery-ui-accordion-widget-part-2
Packt
15 Oct 2009
7 min read
Save for later

jQuery UI Accordion Widget - Part 2

Packt
15 Oct 2009
7 min read
Accordion animation You may have noticed the default slide animation built into the accordion. Apart from this, there are two other built-in animations that we can easily make use of. We can also switch off animations entirely by supplying false as the value of the animated property, although this doesn't look too good! The other values we can supply are bounceslide and easeslide. However, these aren't actually unique animations as such. These are different easing styles which don't change the animation itself but instead, alter the way it runs. You should note at this stage that additional jQuery plugins are required for these easing methods. For example, the bounceslide easing method causes the opening drawer to appear to bounce up and down slightly as it reaches the end of the animation. On the other hand, easeslide makes the animation begin slowly and then builds up to its normal speed. Let's take a moment to look at these different easing methods now. Change accordion11.html so that it appears as follows: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <link rel="stylesheet" type="text/css" href="styles/accordionTheme2.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 12</title> </head> <body> <div id="myAccordion"> <span class="corner topLeft"></span><span class="corner topRight"></span><span class="corner bottomLeft"></span> <span class="corner bottomRight"></span> <div><a href="#">Header 1</a><div>Wow, look at all this content that can be shown or hidden with a simple click!</div></div> <div><a href="#">Header 2</a><div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti.</div> </div> <div><a href="#">Header 3</a><div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus. </div> </div> </div> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/jquery.easing.1.3.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/jquery.easing.compatibility.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //set custom easing var accOpts = { animated: "bounceslide" } //turn specified element into an accordion $("#myAccordion").accordion(accOpts); }); </script> </body> </html> Save this file as accordion12.html. We've used a couple of new script files in the source code. The jquery.easing.1.3.js file is the latest version of the easing plugin, and the jquery.easing.compatibility.js plugin which enables the latest version of the easing file to work without any further modifications. The easing type names were renamed in version 1.2 of the easing plugin. Both of these files can be found on the jQuery site. The built-in easing effects, based on a series of equations created by Robert Penner in 2006, are very easy to use and create a great effect which can help build individuality into accordion implementations Plugins There are many jQuery plugins available. These are often developed by the open-source community instead of the library's authors and can be used with jQuery and jQuery UI. A good place to find plugins is on the jQuery site itself at http://plugins.jquery.com/. Some of these plugins, such as the easing plugin, work with the library components, while other plugins, such as the compatibility plugin, assist other plugins. Accordion events The accordion defines the custom change event which is fired after a drawer on the accordion opens or closes. To react to this event, we can use the change configuration property to specify a function to be executed every time the event occurs. In a new file in your text editor, add the following code: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <link rel="stylesheet" type="text/css" href="styles/accordionTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 13</title> </head> <body> <div id="myAccordion"> <span class="corner topLeft"></span><span class="corner topRight"></span><span class="corner bottomLeft"></span> <span class="corner bottomRight"></span> <div><a href="#">Header 1</a><div id="panel1">Wow, look at all this content that can be shown or hidden with a simple click!</div> </div> <div><a href="#">Header 2</a><div id="panel2">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti.</div></div> <div><a href="#">Header 3</a><div id="panel3">Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> </div> </div> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //define config object var accOpts = { //add change event callback change: function(e, ui) { alert($(ui.newContent).attr("id") + " was opened, " + $(ui.oldContent).attr("id") + " was closed"); } }; $("#myAccordion").accordion(accOpts); }); </script> </body> </html> Save this as accordion13.html. In this example, we use the change configuration property to specify an anonymous callback function which is executed every time the event is triggered. This function will automatically receive two objects as arguments. The first object is the event object which contains information about the event. The second object is an object containing useful information about the accordion widget, such as the content drawer that just opened or closed. In the mark-up for the accordion, we have given each of the content drawer <div> elements an id attribute which can be used in the alert generated by the change callback. We can use the ui.newContent and ui.oldContent properties to obtain the relevant content drawer and display its id in the alert. The accordion widget also defines the accordion change event which is fired after a drawer on the accordion opens or closes. To react to this event, we can use the standard jQuery bind() method to specify a callback function, just like with the tabs widget.
Read more
  • 0
  • 0
  • 2049

article-image-games-fortune-scratch-14
Packt
15 Oct 2009
4 min read
Save for later

Games of Fortune with Scratch 1.4

Packt
15 Oct 2009
4 min read
Fortune-teller Most of us enjoy a good circus, carnival, or county fair. There's fun, food, and fortunes. Aah, yes, what would a fair be without the fortune-teller's tent? By the end of this article, you'll know everything you need to spin your fortunes and amaze your friends with your wisdom. Before we start the first exercise, create a new project and add two sprites. The first sprite will be the seeker. The second sprite will be the teller. Choose any sprites you want. My seeker will be a clam and my teller will be a snowman. If you want to add a background, go ahead. Time for action – create a list of questions In order to have a successful fortune-telling, we need two things: a question and an answer. Let's start by defining some questions and answers: Select the seeker from the list of sprites. From the Variables palette, click the Make a list button. In the list name dialog box, type questions and select For this sprite only. Click OK to create the list. Several new blocks display in the Variables palette, and an empty block titled seeker questions displays on the stage. Let's think about a couple of questions we may be tempted to ask, such as the following: Will my hair fall out? How many children will I have? Let's add our proposed questions to the questions list. Click the plus sign located in the bottom-left corner of the seeker questions box (on the stage) to display a text input field. Type Will my hair fall out? Press the plus sign again and enter the second question: How many children will I have? We now have two questions in our list. To automatically add the next item in the list, press enter. Let's add a say for 2 secs block to the scripts area of the seeker sprite so that we can start the dialog. From the Variables palette, drag the item of questions block to the input value of the say for 2 secs block. Double-click on the block and the seeker asks, "Will my hair fall out?" Change the value on the item block to last and double-click the block again. This time the seeker asks, "How many children will I have?" What just happened? I'm certain you could come up with a hundred different questions to ask a fortune-teller. Don't worry, you'll get your chance to ask more questions later. Did you notice that the new list we created behaved a lot like a variable? We were able to make the questions list private; we don't want our teller to peek at our questions, after all. Also, the list became visible on the screen allowing us to edit the contents. The most notable difference is that we added more than one item, and each item corresponds to a number. We essentially created a numbered list. If you work with other programming languages, then you might refer to lists as arrays. Because the seeker's questions were contained in a list, we used the item block to provide special instructions to the     say block in order to ask the question. The first value of the item block was position, which defaulted to one. The second value was the name of the list, which defaulted to questions. In contrast, if we used a variable to store a question, we would only need to supply the name of the variable to the say block. Have a go hero Create an answers list for the teller sprite, and add several items to the list. Remember, there are no wrong answers in this exercise. Work with an item in a list We can use lists to group related items, but accessing the items in the list requires an extra level of specificity. We need to know the name of the list and the position of the item within the list before we can do anything with the values. The following table shows the available ways to access a specific item in a list.
Read more
  • 0
  • 0
  • 3302

article-image-debugging-multithreaded-applications-singlethreaded-c
Packt
15 Oct 2009
6 min read
Save for later

Debugging Multithreaded Applications as Singlethreaded in C#

Packt
15 Oct 2009
6 min read
We can identify threads created using both the BackgroundWorker component and the Thread class. We can also identify the main application thread and we learned about the information shown by the Threads window. However, we must debug the encryption process to solve its problem without taking into account the other concurrent threads. How can we successfully debug the encryption engine focusing on one thread and leaving the others untouched? We can use the Threads window to control the execution of the concurrent thread at runtime without having to make changes to the code. This will affect the performance results, but it will allow us to focus on a specific part of the code as if we were working in a single-threaded application. This technique is suitable for solving problems related to a specific part of the code that runs in a thread. However, when there are problems generated by concurrency we must use other debugging tricks that we will be learning shortly. The Threads window does a great job in offering good runtime information about the running threads while offering a simple way to watch, pause, and resume multiple threads. Time for action – Leaving a thread running alone You must run the encryption procedure called by ThreadEncryptProcedure. But you want to focus on just one thread, in order to solve the problem that the FBI agents detected. Changing the code is not an option, because it will take more time than expected, and you might introduce new bugs to the encryption engine. Thus, let's freeze the threads we are not interested in! Now, we are going to leave one encryption thread running alone to focus on its code without the other threads disturbing our debugging procedure: Stay in the project, SMSEncryption. Clear all the breakpoints. Press Ctrl + Shift + F9 or select Debug | Delete AllBreakpoints in the main menu. Make sure the Threads window is visible. Define a breakpoint in the line int liThreadNumber = (int)poThreadParameter; in the ThreadEncryptProcedure procedure code. Enter or copy and paste a long text, using the same lines (with more than 30,000 lines) in the Textbox labeled Original SMS Messages, as shown in the following image: Click on the Run in a thread button. The line with the breakpoint defined in the ThreadEncryptProcedure procedure is shown highlighted as the next statement that will be executed. The current thread will be shown with a yellow arrow on the left in the Threads window. Right-click on each of the other encryption threads and select Freeze in the context menu that appears, in order to suspend them. If the current thread is Encryption #1 and there are four cores available, you will freeze the following threads—Encryption #0, Encryption #2, and Encryption #3. Right-click on the Main thread and select Freeze in the context menu that appears, in order to suspend it (we do not want the BackgroundWorker to start and interfere with our work). The only working thread that matters will be Encryption #1, as shown in the following image: Run the code step-by-step inspecting values as you do with single-threaded applications. What just happened? It is easy to debug a multi hreaded application focusing on one thread instead of trying to do it with all the threads running at the same time. We could transform a complex multi threaded application into a single-threaded application without making changes to the code. We did it at runtime using the multithreading debugging features offered by the C# IDE. We suspended the execution of the concurrent threads that would disturb our step-by-step execution. Thus, we could focus on the code being executed by just one encryption thread. Freezing and thawing threads Freezing a thread suspends its execution. However, in the debugging process, we would need to resume the thread execution. It can be done at any point of ti me by right-clicking on a suspended thread and selecting Thaw in the context menu that appears, as shown in the following image: By Freezing and Thawing threads (suspending and resuming), we can have an exhaustive control over the threads running during the debugging process. It helps a lot when we have to solve bugs related to concurrency as we can easily analyze many contexts without making changes to the code—which could generate new bugs. Nevertheless, when developing multithreaded applications, we must always test the execution with many concurrent threads running to make sure it does not have concurrency bugs. The debugging techniques allow us to isolate the code for evaluation purposes, but the final tests must use the full multithreading potential. Viewing the call stack for each running thread Each thread has its own independent stack. Using the Call Stack window, we can move through the methods that were called, as we are used to doing so in single-threaded applications. The main difference in doing this with multithreaded applications is that when the active thread changes, the Call Stack window will also show different content. Debugging a multi hreaded application using the techniques we are learning is an excellent way to understand how the different threads run and will improve our parallel programming skills. To show the call stack for the active thread, press Ctrl + Alt + C or go to Debug | Windows | Call Stack in the main menu. Make sure the Threads window is also visible to take into account the active thread when analyzing the call stack, as shown in the following image: Have a go hero – Debugging and enhancing the encryption algorithm Using the multithreaded debugging techniques we have learned so far, develop a new version of this application with the encryption problem solved. Take into account everything we have studied about freezing and thawing threads. Check the randomly generated garbage and the way it is applied to the generated encrypted string. Making some changes to it, you can have a robust encryption process that differentiates each output with the same input text. You can improve the new versions by using new randomly generated garbage to enhance the encryption algorithms. Oh no! You have to explain to the agents the changes you made to the encryption procedure, and how it works.  
Read more
  • 0
  • 0
  • 5802

article-image-short-and-long-running-processes-soa-part1
Packt
15 Oct 2009
5 min read
Save for later

Short and Long-Running Processes in SOA-part1

Packt
15 Oct 2009
5 min read
Short and Long-Running Processes As a process moves from activity to activity, it consumes time, and each activity adds to the overall duration. But different sorts of activities have different durations, and it's not uncommon to observe a ten-step process that outpaces, say, a five-step one. It depends, of course, on what those activities are doing. In SOA, process cycle times range from one second or less to one or more years! The latter sort need not have a large number of activities. The pyramids might have been built rock-by-rock over several decades, but protracted SOA processes typically span only a few dozen tasks, a handful of which consume almost the entire interval. As we discuss in this article, most of that time is spent waiting. The disputes process often requires several months to complete, because at various times it sits idle waiting for information from the customer, the merchant, or the back office. Business processes crawl along at human speed, it often makes sense to let SOA manage the end-to-end flow. It's not easy to build an SOA process engine that can simultaneously blaze through a sub-second process but keep on top of a one that hasn't moved in weeks. On the other hand, when a long-running process rouses, we expect the engine to race very quickly to the next milestone. The central argument of this article is that both long-running and short-running processes run in very quick bursts, but whereas a short-running process runs in a single burst, a long-running process might have several bursts, separated by long waits. To support long-running processes, the process engine needs a strategy to keep state. In this article, we examine the fundamental differences between long-running and short-running processes. We discuss how to model state, and demonstrate how to build a long-running process as a combination of several short-running processes tied together by state. We also show how to compile short-running BPEL processes to improve the execution speed of a burst. Process Duration—the Long and Short of It SOA processes have the following types of activities: Tasks to extract, manipulate, or transform process data Scripts or inline code snippets Calls to systems and services, both synchronous and asynchronous Events, including timed events, callbacks, and unsolicited notifications from systems The first three sorts of activities execute quickly, the first two in the order of milliseconds, the third often sub-second but seldom more than a few seconds (in the case of a synchronous call to a slow system). These activities are active: as the process navigates through them, it actively performs work, and in doing so ties up the process engine. Event times are generally much longer and more variable. Events come from other systems, so (with the exception of timed events) the process cannot control how quickly they arrive. The process passively waits for events, in effect going to sleep until they come. An event can occur at the beginning of a process—indeed, every SOA process starts with an event—or in the middle. An event in the middle is called an intermediate event. The segment of a process between two events is called a burst. In the following figure, events are drawn as circles, activities as boxes, and bursts as bounding boxes that contain activities. Process (a), for example, starts with an event and is followed by two activities—Set Data and Sync Call—which together form a burst. Process (b) starts with an event, continues with a burst (consisting of the activities Set Data and Call System Async), proceeds to an intermediate event (Fast Response), and concludes with a burst containing the activity Sync Call. Process (c) has two intermediate events and three bursts, and (d) has a single intermediate event and two bursts. Processes are classified by duration as follows: Short-running: The process runs comparatively quickly, for not more than a few seconds. Most short-running processes run in single burst (as in process (a) in the figure), but some have intermediate events with fast arrival times—as in (b), where the intermediate event, a response to an asynchronous system call, arrives in about two seconds—and thus run in multiple bursts. TIBCO's BusinessWorks and the BPEL compiler described later in the article are optimized to run both single-burst and multiple-burst short-running processes. BEA's Weblogic Integration can run single-burst, short-running processes with limited overhead, but, as discussed further next, treats cases like (b) as long-running. Long-running: The process has multiple bursts, and the waiting times of its intermediate events are longer than the process engine itself is expected to run before its next restart! In process (d), for example, the engine is restarted for maintenance while the process waits two days for a human action. The process survives the restart because its state is persisted. At the end of its first burst (that is, after the Assign Work step), the engine writes the state to a database, recording the fact that the process is now waiting on an event for a human action. When the engine comes back up, it fetches the state from the database to remember where it left off. Most BPEL processes are long-running. In Weblogic Integration, stateful processes can run for arbitrarily long durations. Mid-running: The process has multiple bursts, but the waiting times of its intermediate events last no more than a few minutes, and do not need to be persisted. Stakeholders accept the risk that if the process engine goes down, in-flight processes are lost. Chordiant's Foundation Server uses mid-running processes to orchestrate the interaction between agent and customer when the customer dials into a call center. The call is modeled as a conversation, somewhat like a sequence of questions and answers. A burst, in this design, processes the previous answer (for example, the Process Answer activity in (c)) and prepares the next question (Prepare Question). Intermediate events (Get Answer) wait for the customer to answer. State is held in memory
Read more
  • 0
  • 0
  • 3879
article-image-watching-multiple-threads-c
Packt
15 Oct 2009
6 min read
Save for later

Watching Multiple Threads in C#

Packt
15 Oct 2009
6 min read
We can use the BackgroundWorker component and then the Thread class to create new threads independent of the main application thread. The applications can respond to UI events, while the processing continues, and take full advantage of multiple cores, and can thus run faster. However, we are used to debugging applications that run in just one thread (the main thread), and there are many changes in the debugging process that generate great confusion when following the classic procedures running many concurrent threads. How can we successfully debug applications that are running many concurrent threads? Time for action – Understanding the difficulty in debugging concurrent threads Your cellular phone rings! The FBI agents have detected a problem with an encryption engine. When the application receives the same messages many times during a certain period, the encryption process generates exactly the same results, as shown in the following image: Thus, hackers could easily break the code once they discover this important bug. They ask for your help. Of course, you want to cooperate because you do not want the FBI agents to get angry with you. However, you need to debug the multithreaded encryption engine, and you have never done that! Let's create a solution for this problem! First, we are going to try to debug the multithreaded application the same way we do with a single-threaded application to understand the new problems we might face: Open the project, SMSEncryption. Define a breakpoint in the line int liThreadNumber = (int)poThreadParameter; in the ThreadEncryptProcedure procedure code. Press F5 or select Debug | Start Debugging in the main menu. Enter or copy and paste a long text (with more than 5,000 lines) in the Textbox labeled Original SMS Messages and click on the Run in a thread button. The line with the breakpoint defined is shown highlighted as the next statement that will be executed. Press F10 or select, Debug | Step Over in the main menu two or three times (depending on the number of cores you have in the computer). As you can see, the next statement that gets executed is the same even when you try to go on with the next one. It seems that the statement is not being executed. However, inspecting the value of poThreadParameter (the parameter passed to the ThreadEncryptProcedure procedure) shows that it changes each time you step over the statement, as shown in the following image: Stop the application and repeat the steps 1 to 5 to make sure you are not crazy because of parallelism, multithreading, and the FBI agents! What just happened? You are getting nervous about the debugging process! Do not worry. We will learn how to debug your encryption engine while the FBI agents kindly prepare a cup of fresh cappuccino for you. The debugger executed each new Thread class instance call to the Start method, with this line: prloThreadList[liThreadNumber].Start(liThreadNumber); Then, it entered in the ThreadEncryptProcedure method (we have used the same method for every created encryption thread) with different values for the poThreadParameter parameter. Therefore, you stayed in the same statement as many times as the threads were created (equivalent to the number of cores available in the computer) in the following line: int liThreadNumber = (int)poThreadParameter; As we can see, debugging this way is very confusing, because the IDE switches from one thread to another, and you loose control over the statements that are going to be executed next. In a debugging process, you need to know in which part of the application you are. As we tested our first attempt to debug a multithreaded application, we tried the same technique as with single-threaded applications. There are new subjects to learn and new techniques to use. Debugging concurrent threads When we need to inspect values, execute a procedure step-by-step, and find solutions to problems related to some specific code, the best way to achieve that with a multithreaded application is to work with it as a single-threaded application. But, how can we do that? It is very simple. We must run one thread at a time and freeze the other concurrent threads while we are debugging the thread in which we are interested and on which we are focusing. When we debug single-threaded applications, we are aware of the method in which we are positioned and its context. In multithreaded applications, we must also be aware of the thread in which we are positioned. If we do not know in which thread we are executing statements, we will be completely confused in just a few seconds, as happened in our previous activity. We must tailor our multithreaded applications to simplify the debugging process. If we do not do this, the debugging process will be a nightmare. Indeed, we do not want that to happen! Time for action – Finding the threads You wonder where the threads are. How can you guess in which thread you are working while executing the application step-by-step? You are an excellent C# programmer, but multithreaded debugging is very confusing. You do not want the FBI agents to realize that you are in trouble. However, you must hurry up, because they have a great training in detecting nervous people in the course of their usual interrogations. Now, we are going to use the IDE features to help us find the threads in a multithreaded application: Using the same project that we used in the previous example, with the same breakpoint defined, press F5 or select Debug | Start Debugging in the main menu. Enter or copy and paste a long text (with more than 5,000 lines) in the Textbox labeled Original SMS Messages and click on the Run in a thread button. The line with the breakpoint defined is shown highlighted as the next statement that will be executed. Select Debug | Windows | Threads in the main menu or press Ctrl + Alt + H. The Threads window will be shown, displaying all the threads created by the application process, as shown in the following image: The yellow arrow in the left of the thread list points out the current thread—the thread for which the IDE is showing the current statement. Press F10 or select Debug | Step Over in the main menu. As you can see, the next statement is the same again, but the current thread pointed out in the thread list changes, as shown in the following image: Go on running the application step-by-step and watch how the current thread changes. Observe the Threads window throughout your debugging process. What just happened? You found the threads in the debugging process. Now, you believe you will be able to make the necessary changes to the application if you learn a few debugging techniques quickly. The Threads window displays the list of threads created by the application process. Many of them are created automatically by the C# runtime. The others are created by the Thread class instances and the BackgroundWorker component we have in the application. Using the Threads window, we can easily determine in which thread we are executing when debugging a multithreaded application. It is indeed very helpful. Remember that each thread has its own stack.  
Read more
  • 0
  • 0
  • 3554

article-image-measures-and-measure-groups-microsoft-analysis-services-part-1
Packt
15 Oct 2009
12 min read
Save for later

Measures and Measure Groups in Microsoft Analysis Services: Part 1

Packt
15 Oct 2009
12 min read
In this two-part article by Chris Webb, we will look at measures and measure groups, ways to control how measures aggregate up, and how dimensions can be related to measure groups. In this part, will cover useful properties of measures, along with built-in measure aggregation types and dimension calculations. Measures and aggregation Measures are the numeric values that our users want to aggregate, slice, dice and otherwise analyze, and as a result, it's important to make sure they behave the way we want them to. One of the fundamental reasons for using Analysis Services is that, unlike a relational database it allows us to build into our cube design business rules about measures: how they should be formatted, how they should aggregate up, how they interact with specific dimensions and so on. It's therefore no surprise that we'll spend a lot of our cube development time thinking about measures. Useful properties of Measures Apart from the AggregateFunction property of a measure, which we'll come to next, there are two other important properties we'll want to set on a measure, once we've created it. Format string The Format String property of a measure specifies how the raw value of the measure gets formatted when it's displayed in query results. Almost all client tools will display the formatted value of a measure, and this allows us to ensure consistent formatting of a measure across all applications that display data from our cube. A notable exception is Excel 2003 and earlier versions, which can only display raw measure values and not formatted values. Excel 2007 will display properly formatted measure values in most cases, but not all. For instance, it ignores the fourth section of the Format String which controls formatting for nulls. Reporting Services can display formatted values in reports, but doesn't by default; this blog entry describes how you can make it do so:  http://tinyurl.com/gregformatstring. There are a number of built-in formats that you can choose from, and you can also build your own by using syntax very similar to the one used by Visual BASIC for Applications (VBA) for number formatting. The Books Online topic FORMAT_STRING Contents gives a complete description of the syntax used. Here are some points to bear in mind when setting the Format String property: If you're working with percentage values, using the % symbol will display your values multiplied by one hundred and add a percentage sign to the end. Note that only the display value gets multiplied by hundred—the real value of the measure will not be, so although your user might see a value of 98% the actual value of the cell would be 0.98. If you have a measure that returns null values in some circumstances and you want your users to see something other than null, don't try to use a MDX calculation to replace the nulls—this will cause severe query performance problems. You can use the fourth section of the Format String property to do this instead—for example, the following: #,#.00;#,#.00;0;NA will display the string NA for null values, while keeping the actual cell value as null without affecting performance. Be careful while using the Currency built-in format: it will format values with the currency symbol for the locale specified in the Language property of the cube. This combination of the Currency format and the Language property is frequently recommended for formatting measures that contain monetary values, but setting this property will also affect the way number formats are displayed: for example, in the UK and the USA, the comma is used as a thousands separator, but in continental Europe it is used as a decimal separator. As a result, if you wanted to display a currency value to a user in a locale that didn't use that currency, then you could end up with confusing results. The value €100,101 would be interpreted as a value just over one hundred Euros to a user in France, but in the UK, it would be interpreted as a value of just over one hundred thousand Euros. You can use the desired currency symbol in a Format String instead, for example '$#,#.00', but this will not have an effect on the thousands and decimal separators used, which will always correspond to the Language setting. You can find an example of how to change the language property using a scoped assignment in the MDX Script here: http://tinyurl.com/gregformatstring. Similarly, while Analysis Services 2008 supports the translation of captions and member names for users in different locales, unlike in previous versions, it will not translate the number formats used. As a result, if your cube might be used by users in different locales you need to ensure they understand whichever number format the cube is using. Display folders Many cubes have a lot of measures on them, and as with dimension hierarchies, it's possible to group measures together into folders to make it easier for your users to find the one they want. Most, but not all, client tools support display folders, so it may be worth checking whether the one you intend to use does. By default each measure group in a cube will have its own folder containing all of the measures on the measure group; these top level measure group folders cannot be removed and it's not possible to make a measure from one measure group appear in a folder under another measure group. By entering a folder name in a measure's Display Folder property, you'll make the measure appear in a folder underneath its measure group with that name; if there isn't already a folder with that name, then one will be created, and folder names are case-sensitive. You can make a measure appear under multiple folders by entering a semi-colon delimited list of names as follows: Folder One; Folder Two. You can also create a folder hierarchy by entering either a forward-slash / or back-slash delimited list (the documentation contradicts itself on which is meant to be used—most client tools that support display folders support both) of folder names as follows: Folder One; Folder TwoFolder Three. Calculated measures defined in the MDX Script can also be associated with a measure group, through the Associated_Measure_Group property, and with a display folder through the Display_Folder property. These properties can be set either in code or in Form View in the Calculations tab in the Cube Editor: If you don't associate a calculated measure with a measure group, but do put it in a folder, the folder will appear at the same level as the folders created for each measure group. Built-in measure aggregation types The most important property of a measure is AggregateFunction; it controls how the measure aggregates up through each hierarchy in the cube. When you run an MDX query, you can think of it as being similar to a SQL SELECT statement with a GROUP BY clause—but whereas in SQL you have to specify an aggregate function to control how each column's values get aggregated, in MDX you specify this for each measure when the cube is designed. Basic aggregation types Anyone with a passing knowledge of SQL will understand the four basic aggregation types available when setting the AggregateFunction property: Sum is the commonest aggregation type to use, probably the one you'll use for 90% of all the measures. It means that the values for this measure will be summed up. Count is another commonly used property value and aggregates either by counting the overall number of rows from the fact table that the measure group is built from (when the Binding Type property, found on the Measure Source dialog that appears when you click on the ellipses button next to the Source property of a measure, is set to Row Binding), or by counting non-null values from a specific measure column (when Binding Type property is set to Column Binding). Min and Max return the minimum and maximum measure values. There isn't a built-in Average aggregation type—as we'll soon see, AverageOfChildren does not do a simple average—but it's very easy to create a calculated measure that returns an average by dividing a measure with AggregateFunction Sum by one with AggregateFunction Count, for example: CREATE MEMBER CURRENTCUBE.[Measures].[Average Measure Example] ASIIF([Measures].[Count Measure]=0, NULL,[Measures].[Sum Measure]/[Measures].[Count Measure]); Distinct Count The DistinctCount aggregation type counts the number of distinct values in a column in your fact table, similar to a Count(Distinct) in SQL. It's generally used in scenarios where you're counting some kind of key, for example, finding the number of unique Customers who bought a particular product in a given time period. This is, by its very nature, an expensive operation for Analysis Services and queries that use DistinctCount measures can perform worse than those which use additive measures. It is possible to get distinct count values using MDX calculations but this almost always performs worse; it is also possible to use many-to-many dimensions to get the same results and this may perform better in some circumstances; see the section on "Distinct Count" in the "Many to Many Revolution" white paper, available at http://tinyurl.com/m2mrev. When you create a new distinct count measure, BIDS will create a new measure group to hold it automatically. Each distinct count measure needs to be put into its own measure group for query performance reasons, and although it is possible to override BIDS and create a distinct count measure in an existing measure group with measures that have other aggregation types, we strongly recommend that you do not do this. None The None aggregation type simply means that no aggregation takes place on the measure at all. Although it might seem that a measure with this aggregation type displays no values at all, that's not true: it only contains values at the lowest possible granularity in the cube, at the intersection of the key attributes of all the dimensions. It's very rarely used, and only makes sense for values such as prices that should never be aggregated. If you ever find that your cube seems to contain no data even though it has processed successfully, check to see if you have accidentally deleted the Calculate statement from the beginning of your MDX Script. Without this statement, no aggregation will take place within the cube and you'll only see data at the intersection of the leaves of every dimension, as if every measure had AggregateFunction None. Semi-additive aggregation types The semi-additive aggregation types are: AverageOfChildren FirstChild LastChild FirstNonEmpty LastNonEmpty They behave the same as measures with aggregation type Sum on all dimensions except Time dimensions. In order to get Analysis Services to recognize a Time dimension, you'll need to have set the dimension's Type property to Time in the Dimension Editor. Sometimes you'll have multiple, role-playing Time dimensions in a cube, and if you have semi-additive measures, they'll be semi-additive for just one of these Time dimensions. In this situation, Analysis Services 2008 RTM uses the first Time dimension in the cube that has a relationship with the measure group containing the semi-additive measure. You can control the order of dimensions in the cube by dragging and dropping them in the Dimensions pane in the bottom left-hand corner of the Cube Structure tab of the Cube Editor; the following blog entry describes how to do this in more detail: http://tinyurl.com/gregsemiadd. However, this behavior has changed between versions in the past and may change again in the future. Semi-additive aggregation is extremely useful when you have a fact table that contains snapshot data. For example, if you had a fact table containing information on the number of items in stock in a warehouse, then it would never make sense to aggregate these measures over time: if you had ten widgets in stock on January 1, eleven in stock on January 2, eight on January 3 and so on, the value you would want to display for the whole of January would never be the sum of the number of items in stock on each day in January. The value you do display depends on your organization's business rules. Let's take a look at what each of the semi-additive measure values actually do: AverageOfChildren displays the average of all the values at the lowest level of granularity on the Time dimension. So, for example, if Date was the lowest level of granularity, when looking at a Year value, then Analysis Services would display the average value for all days in the year. FirstChild displays the value of the first time period at the lowest level of granularity, for example, the first day of the year. LastChild displays the value of the last time period at the lowest level of granularity, for example, the last day of the year. FirstNonEmpty displays the value of the first time period at the lowest level of granularity that is not empty, for example the first day of the year that has a value. LastNonEmpty displays the value of the last time period at the lowest level of granularity that is not empty, for example the last day of the year that has a value. This is the most commonly used semi-additive type; a good example of its use would be where the measure group contains data about stock levels in a warehouse, so when you aggregated along the Time dimension what you'd want to see is the amount of stock you had at the end of the current time period. The following screenshot of an Excel pivot table illustrates how each of these semi-additive aggregation types works: Note that the semi-additive measures only have an effect above the lowest level of granularity on a Time dimension. For dates like July 17th in the screenshot above, where there is no data for the Sum measure, the LastNonEmpty measure still returns null and not the value of the last non-empty date.
Read more
  • 0
  • 0
  • 15076

article-image-user-security-and-access-control-jboss-portals
Packt
15 Oct 2009
6 min read
Save for later

User Security and Access Control in JBoss portals

Packt
15 Oct 2009
6 min read
Authentication Authentication in JBoss portal builds on the JEE security provided by the JBoss server. The JEE specification defines the roles and constraints under which certain URLs and components are protected. However, this might not always be sufficient for building enterprise applications or portals. Application server providers such as JBoss supplement the authentication and authorization features provided by the JEE specification with additional features such as role-to-group mapping and session logout. Authentication in JBoss portal can be divided into configuration files and portal server configuration. The jboss-portal.sar/portal-server.war file is the portal deployment on the JBoss application server. Assuming that the portal server is like any JEE application deployed on an application server, all user authentication configurations go into the WEB-INF/web.xml and the WEB-INF/jboss-web.xml files. The WEB-INF/web.xml entry defines the authentication mode, with the default being form-based authentication. This file is also used to define the login and error pages, as defined by the JEE specification. The default security domain defined by the JBoss application server is java:/jaas/portal for JBoss portal. The security domain maps the JEE security constructs to the operational domain. This is defined in a proprietary file, WEB-INF/jboss-web.xml. The portal security domain authentication stack is defined in the jboss-portal.sar/conf/login-config.xml file, and is deployed along with the portal. Login-config.xml houses the JAAS modules for authentication. Custom modules can be written and added here to support special scenarios. The server provides a defined set of JAAS login modules that can be used for various scenarios. For example, the IdentityLoginModule is used for authentication based on local portal data, SynchronizingLdapLoginModule for authentication using LDAP, and DBIdentityLoginModule for authentication using a database. Within the jboss-portal.sar/portal-server.war application, all portal requests are routed through a single servlet called org.jboss.portal.server.servlet.PortalServlet. This servlet is defined twice, as follows, in the configuration file WEB-INF/web.xml to ensure that all possible request sources are covered: PortalServletWithPathMapping for path mappings PortalServletWithDefaultServletMapping for the default servlet mapping The servlet is mapped four times with variations to address a combination of secure SSL access and authenticated URLs, as follows: /*: Default access, and with no security constraint, allows access to everybody /sec/*: All requests to a secure protocol are routed through this path, ensuring SSL transport /auth/*: Authenticated access. Requires user to be authenticated before accessing the content under this tree /authsec/*: An authenticated and secure access The following snippet from web.xml shows the entries: <!-- Provide access to unauthenticated users --> <servlet-mapping> <servlet-name>PortalServletWithPathMapping</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <!-- Provide secure access to unauthenticated users --> <servlet-mapping> <servlet-name>PortalServletWithPathMapping</servlet-name> <url-pattern>/sec/*</url-pattern> </servlet-mapping> <!-- Provide access to authenticated users --> <servlet-mapping> <servlet-name>PortalServletWithPathMapping</servlet-name> <url-pattern>/auth/*</url-pattern> </servlet-mapping> <!-- Provide secure access to authenticated users --> <servlet-mapping> <servlet-name>PortalServletWithPathMapping</servlet-name> <url-pattern>/authsec/*</url-pattern> </servlet-mapping> The URL patterns can be changed based on personal preference. Authorization Authorization is the process of determining if an authenticated user has access to a particular resource. Similar to authentication, JBoss portal provides in-built support for authorization, through Java Authorization Contract for Containers(JACC). JACC is a JSR-115 specification for the authorization models of the Java2 and JEE enterprise platforms. In the next few sections, we will look at how JBoss portal facilitates authorization using JACC. However, before we go into the details of access controls and authorization configurations, let's quickly look at how roles are configured in JBoss Portal. User and role management A role is an authorization construct that denotes the group that a user of the portal belongs to. Typically, roles are used to determine the access rights and the extent of these rights for a given resource. We saw in an earlier section how to configured portal assets such as, portals, pages, and portlet instances, to restrict certain actions to specific roles. We used a role called SPECIAL_USER for our examples. However, we never really defined what this role means to JBoss portal. Let's use the JBoss portal server console to register this role with the server. Log in as admin, and then click on the Members tab. This takes us to the User Management and Role Management tabs. The User Management tab is used for creating new users. We will come back to this shortly, but for now, let's switch over to the Role Management tab and click on the Create role link on the bottom right of the page. We can now add our SPECIAL_USER role and provide a display name for it. Once we submit it, the role will be registered with the portal server. As we will see later, every attempt by an authenticated user to access a resource that has security constraints through a specific role will be matched by the portal before granting or denying access to the resource. Users can be added to a role by using the User Management tab. Each user has a role property assigned, and this can be edited to check all of the roles that we want the user to belong to. We can see that for the user User, we now have an option to add the user to the Special User role. The portal permission A permission object carries the relevant permission for a given entity. The org.jboss.portal.security.PortalPermission object is used to describe permission for the portal. Like all the other entity-specific permission classes, it extends the java.security.Permission class, and any permission checked in the portal should extend the PortalPermission as well. Two additional fields of significance are as follows: uri: A string that specifies the URI of the resource that is described by the permission collection: An object of class org.jboss.portal.security.PortalPermissionCollection, which is used when the permission acts as a container for other permissions The authorization provider The authorization provider is a generic interface of the type org.jboss.portal.security.spi.provider.AuthorizationDomain, and provides access to several services. public interface AuthorizationDomain{ String getType(); DomainConfigurator getConfigurator(); PermissionRepository getPermissionRepository(); PermissionFactory getPermissionFactory();} Let us look into these classes a bit more in detail: org.jboss.portal.security.spi.provider.DomainConfigurator provides configuration access to an authorization domain. The authorization schema consists of bindings between URIs, roles, and permissions. org.jboss.portal.security.spi.provider.PermissionRepository provides runtime access to the authorization domain. It is used to retrieve the permissions for a specific role and URI. It is used at runtime by the framework, to take security decisions. org.jboss.portal.security.spi.provider.PermissionFactory is a factory to instantiate permissions for the specific domain. It is used at runtime to create permission objects of the appropriate type by the security framework.
Read more
  • 0
  • 0
  • 2800
article-image-xpath-support-oracle-jdeveloper-xdk-11g
Packt
15 Oct 2009
11 min read
Save for later

XPath Support in Oracle JDeveloper - XDK 11g

Packt
15 Oct 2009
11 min read
With SAX and DOM APIs, node lists have to be iterated over to access a particular node. Another advantage of navigating an XML document with XPath is that an attribute node may be selected directly. With DOM and SAX APIs, an element node has to be selected before an element attribute can be selected. Here we will discuss XPath support in JDeveloper. What is XPath? XPath is a language for addressing an XML document's elements and attributes. As an example, say you receive an XML document that contains the details of a shipment and you want to retrieve the element/attribute values from the XML document. You don't just want to list the values of all the nodes, but also want to output the values of specific elements or attributes. In such a case, you would use XPath to retrieve the values of those elements and attributes. XPath constructs a hierarchical structure of an XML document, a tree of nodes, which is the XPath data model. The XPath data model consists of seven node types. The different types of nodes in the XPath data model are discussed in the following table: Node Type Description Root Node The root node is the root of the DOM tree. The document element (the root element) is a child of the root node. The root node also has the processing instructions and comments as child nodes. Element Node It represents an element in an XML document. The character data, elements, processing instruction, and comments within an element are the child nodes of the element node. Attribute Node It represents an attribute other than the valign="top"> Text Node The character data within an element is a text node. A text node has at least one character of data. A whitespace is also considered as a character of data.  By default, the ignorable whitespace after the end of an element and before the start of the following element is also a text node. The ignorable whitespace can be excluded from the DOM tree built by parsing an XML document. This can be done by setting the whitespace-preserving mode to false with the setPreserveWhitespace(boolean flag) method. Comment Node It represents a comment in an XML document, except the comments within the DOCTYPE declaration. Processing Instruction Node It represents a processing instruction in an XML document except the processing instruction within the DOCTYPE declaration. The XML declaration is not considered as a processing instruction node. Namespace Node It represents a namespace mapping, which consists of a . A namespace node consists of a namespace prefix (xsd in the example) and a namespace URI (http://www.w3.org/2001/XMLSchema in the example). Specific nodes including element, attribute, and text nodes may be accessed with XPath. XPath supports nodes in a namespace. Nodes in XPath are selected with an XPath expression. An expression is evaluated to yield an object of one of the following four types: node set, Boolean, number, or string. For an introduction on XPath refer to the W3C Recommendation for XPath (http://www.w3.org/TR/xpath). As a brief review, expression evaluation in XPath is performed with respect to a context node. The most commonly used type of expression in XPath is a location path . XPath defines two types of location paths: relative location paths and absolute location paths. A relative location path is defined with respect to a context node and consists of a sequence of one or more location steps separated by "/". A location step consists of an axis, a node test, and predicates. An example of a location step is: child::journal[position()=2] In the example, the child axis contains the child nodes of the context node. Node test is the journal node set, and predicate is the second node in the journal node set. An absolute location path is defined with respect to the root node, and starts with "/". The difference between a relative location path and an absolute location path is that a relative location path starts with a location step, and an absolute location path starts with "/". XPath in Oracle XDK 11g Oracle XML Developer's Kit 11g, which is included in JDeveloper, provides the DOMParser class to parse an XML document and construct a DOM structure of the XML document. An XMLDocument object represents the DOM structure of an XML document. An XMLDocument object may be retrieved from a DOMParser object after an XML document has been parsed. The XMLDocument class provides select methods to select nodes in an XML document with an XPath expression. In this article we shall parse an example XML document with the DOMParser class, obtain an XMLDocument object for the XML document, and select nodes from the document with the XMLDocument class select methods. The different select methods in theXMLDocument class are discussed in the following table: Method Name Description selectSingleNode(String XPathExpression) Selects a single node that matches an XPath expression. If more than one node matches the specified expression, the first node is selected. Use this method if you want to select the first node that matches an XPath expression. selectNodes(String XPathExpression) Selects a node list of nodes that match a specified XPath expression. Use this method if you want to select a collection of similar nodes. selectSingleNode(String XPathExpression, NSResolver resolver) Selects a single namespace node that matches a specified XPath expression. Use this method if the XML document has nodes in namespaces and you want to select the first node, which is in a namespace and matches an XPath expression. selectNodes(String XPathExpression, NSResolver resolver) Selects a node list of nodes that match a specified XPath expression. Use this method if you want to select a collection of similar nodes that are in a namespace. The example XML document that is parsed in this article has a namespace declaration for elements in the namespace with the prefix journal. For an introduction on namespaces in XML refer to the W3C Recommendation on Namespaces in XML 1.0 (http://www.w3.org/TR/REC-xml-names/). catalog.xml, the example XML document, is shown in the following listing: <?xml version="1.0" encoding="UTF-8"?><catalog title="Oracle Magazine" publisher="Oracle Publishing"><journal:journal journal_date="November-December 2008"> <journal:article journal_section="ORACLE DEVELOPER"> <title>Instant ODP.NET Deployment</title> <author>Mark A. Williams</author></journal:article><journal:article journal_section="COMMENT"> <title>Application Server Convergence</title> <author>David Baum</author> </journal:article></journal:journal><journal date="March-April 2008"> <article section="TECHNOLOGY"> <title>Oracle Database 11g Redux</title> <author>Tom Kyte</author> </article><article section="ORACLE DEVELOPER"> <title>Declarative Data Filtering</title> <author>Steve Muench</author> </article> </journal></catalog Setting the environment Create an application (called XPath, for example) and a project (called XPath) in JDeveloper. The XPath API will be demonstrated in a Java application. Therefore, create a Java class in the XPath project with File | New. In the New Gallery window select < >Categories | General and Items | Java Class. In the Create Java Class window, specify the class name (XPathParser, for example), the package name (xpath in the example application), and click on the OK button. To develop an application with XPath, add the required libraries to the project classpath. Select the project node in Application Navigator and select Tools | Project Properties. In the Project Properties window, select the Libraries and Classpath node. To add a library, select the Add Library button. Select the Oracle XML Parser v2 library. Click on the OK button in the Project Properties window. We also need to add an XML document that is to be parsed and navigated with XPath. To add an XML document, select File | New. In the New Gallery window, select Categories | General | XML and Items | XML Document. Click on the OK button. In the Create XML File window specify the file name catalog.xml in the File Name field, and click on the OK button. Copy the catalog.xml listing to the catalog.xml file in the Application Navigator. The directory structure of the XPath project is shown in the following illustration: XPath Search In this section, we shall select nodes from the example XML document, catalog.xml, with the XPath Search tool of JDeveloper 11g. The XPath Search tool consists of an Expression field for specifying an XPath expression. Specify an XPath expression and click on OK to select nodes matching the XPath expression. The XPath Search tool has the provision to search for nodes in a specific namespace. An XML namespace is a collection of element and attribute names that are identified by a URI reference. Namespaces are specified in an XML document using namespace declarations. A namespace declaration is an > To navigate catalog.xml with XPath, select catalog.xml in the Application Navigator and select Search | XPath Search. In the following subsections, we shall select example nodes using absolute location paths and relative location paths. Use a relative location path if the XML document is large and a specifi c node is required. Also, use a relative path if the node from which subnodes are to be selected and the relative location path are known. Use an absolute location path if the XML document is small, or if the relative location path is not known. The objective is to use minimum XPath navigation. Use the minimum number nodes to navigate in order to select the required node. Selecting nodes with absolute location paths Next, we shall demonstrate with various examples of selecting nodes using XPath. As an example, select all the title elements in catalog.xml. Specify the XPath expression for selecting the title elements in the Expression field of the Apply an XPath Expression on catalog.xml window. The XPath expression to select all title elements is /catalog/journal/article/title. Click on the OK button to select the title elements. The title elements get selected. Title elements from the journal:article elements in the journal namespace do not get selected because a namespace has not been applied to the XPath expression. As an other example, select the title element in the first article element using the XPath expression /catalog/journal/article[1]/title. We are not using namespaces yet. The XPath expression is specified in the Expression field. The title of the first article element gets selected as shown in the JDeveloper output: Attribute nodes may also be selected with XPath. Attributes are selected by using the "@" prefix. As an example, select the section attribute in the first article element in the journal element. The XPath expression for selecting the section attribute is /catalog/journal/article[1]/@section and is specified in the Expression field. Click on the OK button to select the section attribute. The attribute section gets outputted in JDeveloper. Selecting nodes with relative location paths In the previous examples, an absolute location is used to select nodes. Next, we shall demonstrate selecting an element with a relative location path. As an example, select the title of the first article element in the journal element. The relative location path for selecting the title element is child::catalog/journal/article[position()=1]/title. Specifying the axis as child and node test as catalog selects all the child nodes of the catalog node and is equivalent to an absolute location path that starts with /catalog. If the child nodes of the journal node were required to be selected, specify the node test as journal. Specify the XPath expression in the Expression field and click on the OK button. The title of the first article element in the journal element gets selected as shown here: Selecting namespace nodes XPath Search also has the provision to select elements and attributes in a namespace. To illustrate, select all the title elements in the journal element (that is, in the journal namespace) using the XPath expression /catalog/journal:journal/journal:article/title. First, add the namespaces of the elements and attributes to be selected in the Namespaces text area. Prefix and URI of namespaces are added with the Add button. Specify the prefix in the Prefix column, and the URI in the URI column. Multiple namespace mappings may be added. XPath expressions that select namespace nodes are similar to no-namespace expressions, except that the namespace prefixes are included in the expressions. Elements in the default namespace, which does not have a namespace prefix, are also considered to be in a namespace. Click on the OK button to select the nodes with XPath. The title elements in the journal element (in the journal namespace) get selected and outputted in JDeveloper. Attributes in a namespace may also be selected with XPath Search. As an example, select the section attributes in the journal namespace. Specify the XPath expression to select the section attributes in the Expression field and click on the OK button. Section attributes in the journal namespace get selected.
Read more
  • 0
  • 0
  • 5524

article-image-deployment-reports-birt
Packt
15 Oct 2009
4 min read
Save for later

Deployment of Reports with BIRT

Packt
15 Oct 2009
4 min read
Everything in this article uses utilities from the BIRT Runtime installation package, available from the BIRT homepage at http://www.eclipse.org/birt. BIRT Viewer The BIRT Viewer is a J2EE application that is designed to demonstrate how to implement the Report Engine API to execute reports in an online web application. For most basic uses—such as for small to medium size Intranet applications—this is an appropriate approach. The point to keep in mind about the BIRT Web Viewer is that it is an example application. It can be used as a baseline for more sophisticated web applications that will implement the BIRT Report Engine API. Installation of the BIRT Viewer is documented at a number of places. The Eclipse BIRT website has some great tutorials at: http://www.eclipse.org/birt/phoenix/deploy/viewerSetup.php http://wiki.eclipse.org/BIRT/FAQ/Deployment This is also documented on my website in a series of articles introducing people to BIRT: http://digiassn.blogspot.com/2005/10/birt-report-server-pt-2.html I won't go into the details about installing Apache Tomcat as this is covered in depth in other locations, but I will cover how to install the Viewer in a Tomcat environment. For the most part these instructions can be used in other J2EE containers, such as WebSphere. In some cases a WAR package is used instead. I prefer Tomcat because it is a widely used open-source J2EE environment. Under the BIRT Runtime package is a folder containing an example Web Viewer application. The Web Viewer is a useful application as you require basic report viewing capabilities, such as parameter passing, pagination, and export capabilities to formats such as Word, Excel, RTF, and CSV. For this example, I have Apache Tomcat 5.5 installed into a folder at C:apache-tomcat-5.5.25. To install the Web Viewer, I simply need to copy the WebViewerExample folder from the BIRT Runtime to the web application folder at C:apache-tomcat-5.5.25webapps. Accessing the BIRT Web Viewer is as simple as calling the WebViewerExample Context. When copying the WebViewerExample folder, you can rename this folder to anything you want. Obviously WebViewerExample is not a good name for an online web application. So in the following screenshot, I renamed the WebViewerExample folder to birtViewer, and am accessing the BIRT Web Viewer test report. Installing Reports into the Web Viewer Once the BIRT Viewer is set up, Deploying reports is as simple as copying the report design files, Libraries, or report documents into the application's Context, and calling it with the appropriate URL parameters. For example, we will install the reports from the Classic Cars – With Library folder into the BIRT Web Viewer at birtViewer. In order for these reports to work, all dependent Libraries need to be installed with the reports. In the case of the example application, we currently have the report folder set to the Root of the web application folder. Accessing Reports in the Web Viewer Accessing reports is as simple as passing the correct parameters to the Web Viewer. In the BIRT Web Viewer, there are seven servlets that you can call to run reports, which are as follows: frameset run preview download parameter document output Out of these, you will only need frameset and run as the other servlets are for Engine-related purposes, such as the preview for the Eclipse designer, the parameter Dialog, and the download of report documents. Out of the these two servlets, frameset is the one that is typically used for user interaction with reports, as it provides the pagination options, parameter Dialogs, table of contents viewing, and export and print Dialogs. The run servlet only provides report output. There are a few URL parameters for the BIRT Web Viewer, such as: __format : which is the output format, either HTML or PDF. __isnull: which sets a Report Parameter to null, parameter name as a value. __locale: which is the reports locale. __report: which is the report design file to run. __document: which is the report document file to open. Any remaining URL parameter will be treated as a Report Parameter. In the following image, I am running the Employee_Sales_Percentage.rptdesign file with the startDate and endDate parameters set.  
Read more
  • 0
  • 0
  • 6279
Modal Close icon
Modal Close icon