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-calendaring-plone-3-education
Packt
31 Dec 2009
6 min read
Save for later

Calendaring with Plone 3 for Education

Packt
31 Dec 2009
6 min read
(For more resources on Plone, see here.) The techniques in this article are applicable in many organizational schemes. We present one common arrangement as an example: a top-level folder where visitors can browse the highest-profile events on the site. Show events on a calendar Plone's out-of-the-box Events folder provides a basic way to find events: it displays them in a chronological list broken into pages of 20 each. While fine for simple cases, this is cumbersome for visitors who want to look at events for a certain future date. Part of our goal is to set up a monthly calendar to make this common case easy: Our first step toward the monthly calendar is to replace Plone's stock Events folder. Out of the box, it holds individual events along with a summarizing collection that acts as its front page. If you don't need a drill-down way of browsing your events by subject—for example, if you have so few that they all fit comfortably on a calendar like the above—you can leave the default Events folder in place. Otherwise, follow the instructions below to replace it with a standalone collection; this will interact better with Plone's navigation portlet, which we will use to implement the drilldown browsing. If you choose to stick with the stock Events folder, you may still wish to adjust the criteria of its inner collection as described in the following: First, delete the Events folder. Replace it with a new collection called "Events". Give it an Item Type criterion, and tell it to pull in everything of the type Event. The original Events collection had a Start Date criterion to keep past events off the page. We won't need that, since the calendar view we are about to apply keeps past events tucked away implicitly—and we do want the ability to see old events when we navigate to previous months. The original collection also had a State criterion that limited it to showing published events. If you need only to hide unpublished events from visitors, then you can dispense with this: the internal search routines used by the collection will naturally show only what the current user has permission to see. Preventing a common contributor errorOften, a less proficient contributor will add an event, see it on his or her own calendar, and move on, neglecting to publish it. Adding the State criterion can serve as a reminder, preventing the event from appearing until properly published. The downside is that it makes the calendar useless for intranets: Events that aren't publicly visible will never show up. But if you have no non-public events to list, consider recreating the State criterion. If you never want to show access-controlled events on the main calendar add a State criterion limiting the collection to published items. The Events collection is finished. Next, we apply a monthly calendar view to our data. Meet Plone4Artists Calendar Plone's built-in event listings are rather basic. We need to do special tricks with collections and default views just to sort them in chronological order. At best, this is several extra clicks, and, at worst, it can confuse your less technical content contributors. A third-party product called Plone4Artists Calendar makes this easy and gives us several other capabilities to boot. Plone4Artists Calendar is the current frontrunner in the Plone calendaring space. It provides... Daily, weekly, monthly, and a few other calendar-like views for folders and collections Rudimentary recurring event support Hooks for pulling events from other systems in realtime, with a bit of coding Don't let the name "Plone4Artists" put you off if you aren't an artist; though the Plone4Artists suite of products came out of a project to provide artist community web sites, there's nothing particularly artist-centric about them. In fact, there has been discussion about renaming them. The runner up: CalendarXThe other Plone calendar worth considering is CalendarX, whose most recent release at the time of this writing is 0.9.1. 0.9.0 was the first update to the product since since 2005 and represents a major refit. Its ancient data-modeling internals were replaced with a modern Archetypes implementation, and one no longer needed to venture into the ZMI to do simple configuration. Speaking of configuration, CalendarX exposes a lot of it: 6 tabs packed with options for tweaking calendar format, event display, widgets, and more. There are 57 options alone regarding its CSS cosmetics. If you need a specific look and aren't comfortable writing your own CSS or template code, CalendarX may be the ticket.However, be warned that CalendarX has a history of being sporadically maintained. It lacked Plone 3 compatibility for a long time, and compatibility work began only when a group of stranded Plone 2.5 users at Pennsylvania State University put a week of development work toward it. Its internals still hold a lot of legacy that may prove difficult to maintain as Plone evolves.Plone4Artists Calendar, on the other hand, is a simpler product—both inside and outside and with all the good and bad that entails—and the winds of further community effort are blowing in its direction. Its maintainable design and the willingness of developers to work on it make it the solution least likely to leave you stranded; this is why it is our recommendation in this article. Install Plone4Artists Calendar Before we can make use of its views, we need to install the product—actually, two products and several supporting packages. Weave these directives into the proper sections of your buildout.cfg... [buildout]...other directives...eggs = ...other eggs here... p4a.plonecalendar p4a.ploneevent[instance]...other directives...zcml = ...other ZCML listings here... # Plone4Artists Calendar doesn't support Plone 3.3's auto-ZCMLloading as of 2.0a2. p4a.plonecalendar-meta p4a.plonecalendar p4a.ploneevent[productdistros]recipe = plone.recipe.distrosurls =http://plone.org/products/calendaring/releases/0.4/calendaring-0-4-0.tgz ...run buildout, restart Zope/Plone, and install the Plone4ArtistsCalendar (p4a.plonecalendar) and Recurring Events (p4a.ploneevent) products in Site Setup → Add-on Products. Now that everything is installed, we apply a monthly calendar view to the Events collection: Navigate back to the Events collection, and choose Calendar from the new Sub-types menu. If it isn't already selected, choose Month view from the Display menu. Presto—we have a monthly calendar showing every event on our site.
Read more
  • 0
  • 0
  • 7614

article-image-searching-data-microsoft-dynamics-ax-2009-part-3
Packt
31 Dec 2009
5 min read
Save for later

Searching for Data in Microsoft Dynamics AX 2009: Part 3

Packt
31 Dec 2009
5 min read
Exists join An exists join does pretty much the same as the inner join, except one important thing; it does not fetch the records from the joined table. This means that the RentalTable variable cannot be used within the while loop in the following example, as it will never have any data: static void selectExistsJoin(Args _args){CarTable carTable;RentalTable rentalTable;;while select carTableexists join rentalTablewhere rentalTable.CarId == carTable.CarId{info(strfmt("CarId %1 has a matching record in rentalTable",CarTable.CarId));}} Executing this Job will result in the following output to the Infolog: NotExists join Obviously the notexists join is the opposite of the exists join. This means that it will return all records from the main table where there does not exist a record in the joined table as described by the where clause. This means that the following example will produce the opposite result from the previous example: static void selectNotExistsJoin(Args _args){CarTable carTable;RentalTable rentalTable;;while select carTablenotexists join rentalTablewhere rentalTable.CarId == carTable.CarId{info(strfmt("CarId %1 does not has a matching record inrentalTable", CarTable.CarId));}} Executing this job will result in the following output to the Infolog: Writing aggregate select statements In many cases, you would like to write select statements that return aggregate data like the sum or average of a field in a set of data. You can also use the count aggregate option to count the number of records in a table matching a where statement (if any). The minof and maxof options can be used in the same way to find the minimum or maximum value of a field in a record set that corresponds to the where statement. These examples show how the different aggregate options can be used: sum static void selectSumMileage(Args _args){CarTable carTable;;select sum(Mileage) from carTable;info(strfmt("The total mileage of all cars is %1",carTable.Mileage));} Executing this Job will result in the following output to the Infolog: avg static void selectAvgModelYear(Args _args){CarTable carTable;;select avg(ModelYear) from carTable;info(strfmt("The average ModelYear is %1",carTable.ModelYear));} Executing this Job will result in the following output to the Infolog: count static void selectCountRentals(Args _args){RentalTable rentalTable;;select count(recId) from rentalTable;info(strfmt("There are %1 rentals registerred in the system",rentalTable.RecId));} Executing this Job will result in the following output to the Infolog: minof and maxof static void selectCountRentalsPerCustomer(Args _args){RentalTable rentalTable;;// Normal while select to loop datainfo ("Using while select:");// The result of the count operation is put// into the recId field of the tableBuffer// since it is an integerfield.while select count(recId) from rentalTablegroup by rentalTable.CustAccount{info(strfmt(" Customer %1 has rented cars %2 times",rentalTable.CustAccount, rentalTable.RecId));}// Looping the rentalTable cusrsor using the next commandinfo ("Using next command:");select count(recId) from rentalTablegroup by rentalTable.CustAccount;while (rentalTable.RecId){info(strfmt(" Customer %1 has rented cars %2 times",rentalTable.CustAccount, rentalTable.RecId));next rentalTable;}}                                                                        Executing this Job will result in the following output to the Infolog: Group by In many cases, aggregate options are used together with the group by parameter in order to list the aggregate for each subpart of a table. In the next example we will find the number of rentals for each customer that has rented cars. I will also demonstrate how to use the next command together with the select statement instead of the while select statement to loop through the records in the result. You will most often see the while select statement being used in standard AX, but in case you see the next command, you will know it does the same as a while select statement. The following example shows how the group by aggregate option can be used: select carTable; // Is the same as select * from carTable Executing this Job will result in the following output to the Infolog: Optimizing the data retrieval There can be several different steps that you, as a developer, should take in order to optimize the process of fetching data from the database to the application. I will try to cover the most important things for you to keep in mind here. Using the correct data retrieval method One important issue, not only for optimization but also for usability, is to select the correct data retrieval method based on what you would like to achieve. Use queries when you want the users to be able to change the range of data to be retrieved and when the selection criteria are simple enough for the query to handle. If the selection criteria are complex, and there is no need for the users to be able to change the selection criteria, you should opt for a select statement. If you would like to be able to use the query definition multiple places, you should create a query in the AOT instead of writing it in X++ every time you need to use it. It can also be easier to get a visual overview of a query created in the AOT compared to a query written in X++. If the selection criteria is complex, there is no need for updating or deleting the data selected and if you would like to be able to use the same selection in many places in the application, then you should consider creating a view in the AOT instead of writing the select statement every time.
Read more
  • 0
  • 0
  • 2225

article-image-editing-datagrids-popup-windows-flex
Packt
31 Dec 2009
4 min read
Save for later

Editing DataGrids with Popup Windows in Flex

Packt
31 Dec 2009
4 min read
To start with we'll create a DataGrid which will contain a first name and a last name. We will add a Panel container to place our DataGrid into. Here is what our initial app looks like: <?xml version="1.0" encoding="utf-8"?> <mx:Application layout="absolute"> <mx:Panel title="Pop Up Window" > <mx:DataGrid width="100%" height="100%"> <mx:columns> <mx:DataGridColumn headerText="First Name"/> <mx:DataGridColumn headerText="Last Name"/> </mx:columns> </mx:DataGrid> </mx:Panel> </mx:Application> You'll notice the common Application tag along with the Panel. Immediately inside the Panel is our all important DataGrid. Note, if you are not familiar with the basics of Flex then stop here and head over to the Adobe site for an introduction. Although this tutorial is not complex, I wont be able to focus on the fundamentals. I've set the DataGrid width and height attibutes to 100%. This will force it to expand to the size and width of the panel. You can make this application full screen by setting the same attributes on the Panel tag. Inside our DataGrid tag is the columns tag. Here we can describe what each column of our DataGrid will contain. In this case, one column for first name and one column for the last name. Here is a first look at our app: Adding Data The ease of Flex has allowed us to create this simple user interface with little effort. Now we come to a point where we need to add data to the DataGrid. The easiest way to do this is to use the dataProvider attribute. We will add an ArrayCollection Object to the script portion of our application to hold all the names which will appear in our DataGrid. The DataGrid and the accompanying ArrayCollection will look something like this: <mx:DataGrid id="names" width="100%" height="100%" dataProvider="{namesDP}"> <mx:columns> <mx:DataGridColumn headerText="First Name" dataField="firstName"/> <mx:DataGridColumn headerText="Last Name" dataField="lastName"/> </mx:columns> </mx:DataGrid> [Bindable] public var namesDP:ArrayCollection = new ArrayCollection ([ {firstName:'Keith',lastName:'Lee'}, {firstName:'Ira',lastName:'Glass'}, {firstName:'Christopher',lastName:'Rossin'}, {firstName:'Mary',lastName:'Little'}, {firstName:'Charlie',lastName:'Wagner'}, {firstName:'Cali',lastName:'Gonia'}, {firstName:'Molly',lastName:'Ivans'}, {firstName:'Amber',lastName:'Johnson'}]); The dataProvider attribute binds the DataGrid to the nameDP ArrayCollection. The ArrayCollection constructor's argument is an array of objects. Each object has a firstName and lastName property. If you wanted to expand on this application, you can add more data to this Array. You should also notice that the DataGridColumn tags also have an addition. We've set the dataField equal to the property in the dataProvider. The dataField is the real key in populating the DataGrid. Here is what our populated DataGrid looks like: We've now created the foundation of our application. Activating the DoubleClick Event By default the DataGrid doubleclick event is turned off. This means when a user doubleclicks an entry nothing will happen. In order to tell the DataGrid to trigger the doublelcick event we need to set the doubleClick and doubleClickEnabled attributes of the DataGrid tag. It looks like this: <mx:DataGrid width="100%" height="100%" doubleClick="showPopUp(event)" doubleClickEnabled="true"> I've set the doubleClick attribute to a method called showPopUp. We've not written this method yet, but it will be responsible for displaying the PopUp window which will allow editing of the DataGrid data. For now, let's add the Script tag and an empty showPopUp method: <mx:Script> <![CDATA[ import mx.events.ItemClickEvent; public function showPopUp(event:MouseEvent):void{ // show the popup } ]]> </mx:Script> The Script tag is a child of the Application tag.
Read more
  • 0
  • 0
  • 2873

article-image-folding-home-ubuntu-cancer-research-made-easy
Packt
31 Dec 2009
7 min read
Save for later

Folding @ Home on Ubuntu: Cancer Research Made Easy

Packt
31 Dec 2009
7 min read
What is Folding @ Home? Folding @ Home is a project started by Stanford University in late 2000. The idea is that it allows for distributed medical research and leverages the computing power of the general public, instead of requiring the university to buy more and more computers. Instead of a single computer taking a million days to calculate a problem, distributing the research load can allow for the same problem to be solved in ten days by a fraction of the machines. Contributing to Folding @ Home on Ubuntu is very simple, and can be done in just a few short steps. There are packages in the main Ubuntu repositories that support installation, management and removal of the Folding @ Home clients. Before I get into these, I'd like to outline what Folding @ Home actually does. To understand how the system works we first need to understand a few key underlying principles. Perhaps the most important is to answer the question: What are proteins? The Folding @ Home website defines proteins as: Proteins are necklaces of amino acids --- long chain molecules. Proteins are the basis of how biology gets things done. As enzymes, they are the driving force behind all of the biochemical reactions which make biology work. As structural elements, they are the main constituent of our bones, muscles, hair, skin and blood vessels. As antibodies, they recognize invading elements and allow the immune system to get rid of the unwanted invaders. For these reasons, scientists have sequenced the human genome -- the blueprint for all of the proteins in biology -- but how can we understand what these proteins do and how they work? In a nutshell, proteins are a critical part of everything around us. From our bones, muscles and hair to our immune system and everyday health. In an attempt to improve our understanding of exactly how proteins work, the Folding @ Home project attempts to simulate the work of proteins in our bodies. This brings us to the next question. Why is it called folding? However, only knowing this sequence tells us little about what the protein does and how it does it. In order to carry out their function (eg as enzymes or antibodies), they must take on a particular shape, also known as a "fold." Thus, proteins are truly amazing machines: before they do their work, they assemble themselves! This self-assembly is called "folding." One of our project goals is to simulate protein folding in order to understand how proteins fold so quickly and reliably, and to learn about what happens when this process goes awry (when proteins misfold). Basically, contributing to this project can help simulate the folding of a protein and, hopefully, determine where and when proteins misfold. If this process of misfolding can be defined, perhaps it can be avoided. It is thought that diseases such as Alzheimer's, cystic fibrosis, Mad Cow and even many cancers are caused by misfolding proteins. Contributing to this project can help researches make progress towards remedying these diseases. I started contributing to the Folding @ Home project many years ago. Knowing that Alzheimer's disease is common in my family, it seemed like a very beneficial and relateble project to be working on. The best thing about it is that I can spend a few minutes setting up a client, and then I never have to think about it afterwards. The process of contributing is a "no-worry" process, one that allows me to contribute but doesn't get in my way. Origami : Folding @ Home Made Easy A few years after I started contributing I wrote a script that would improve and automate the process of installing the Folding @ Home client on my machines. This little script has since turned into a full blown program that has now been included into the Ubuntu (and other) repositories. This program is called origami. Installation The goal of Origami is to make installation, automation and management of Folding @ home clients as simple as possible. After installing the origami package it takes just one command to configure and install the research client. For those interested in contributing, here are a few basic steps. To install the package from the Ubuntu repositories, simple use: sudo aptitude install origami For those on other distributions, Origami is also available in tar format from: http://zelut.org/projects/origami/ as well as on Launchpad. The latest bazaar trunk can be checked out using: bzr branch lp:origami. If you've installed the package you're ready to go. If you downloaded the tar or checked out a branch from revision control you'll need to simply copy the executable into your path. sudo cp origami-*/origami /usr/bin/ Installation is then as simple as using the following command: sudo origami install Origami also supports a wide range of configuration options. The Folding @ Home system is setup to allow for user and team based contributions, so you can track your progress. You can also form or join teams and compete against other groups. If you'd like to contribute using a specific username or for a team, use the following installation syntax: sudo origami install -u USERNAME -t TEAMNUMBER For example, my username is 'Zelut' and I fold for TeamUbuntu, so I use: sudo origami install -u Zelut -t 45104 Origami also allows you to specify pre-defined hours that you'd like the client to run. Perhaps you only want it to run after business hours, you can add the cron option to the installer which will stop the client at 8:00 am and restart it again at 5:00 pm. sudo origami install -u USERNAME -t TEAMNUMBER -c 1 You can also define the type of processor you have. The default is to use the 32bit Folding @ Home client, but if you'd prefer to leverage your 64bit processor you can use the proc option to activate that: sudo origami install -u USERNAME -t TEAMNUMBER -p amd64 It is also possible to define proxy information as required. You would use the following: sudo origami install -u USERNAME -t TEAMNUMBER -P port -H hostname Replace 'port' with the port number and 'hostname' with your proxy server hostname or IP address. You can also define the size or work unit you would like to be assigned: sudo origami install -u USERNAME -t TEAMNUMBER -b (small|normal|big) Select either small, normal or big and you will only receive that size work units. Small units are finished faster but receive fewer points toward yourself or your team. These units are generally suited for slower processors. Normal is the default, and is a sane value for most installations. Big units take much longer to finish but have big point rewards when completed. If you have a fast, new processor you might consider doing big work units. Lastly, you can define a unique PASSKEY to your Folding @ Home work which will allow you to verify that all of the work contributed under your username is unique to your clients. This is purely optional for local installations, but required for network-based deployments which we'll discuss soon. To generate a PASSKEY for your username visit: http://fah-web.stanford.edu/cgi-bin/getpasskey.py Just to be clear, it is perfectly reasonable to combine a number of these options into one line. Let's say I wanted to install to my local machine, using my username 'Zelut' and TeamUbuntu '45104', but I also needed tho 64bit processor, big units and cron job. The command would be: sudo origami install -u Zelut -t 45104 -c 1 -p amd64 -b big The beautiful thing about Origami is that it is set-and-forget. Unless I remove the Folding @ Home client from my machine I never need to consider all of the installation options again. I simply know that the client is running in the background, and will automatically run on each boot.
Read more
  • 0
  • 1
  • 3685

article-image-searching-data-microsoft-dynamics-ax-2009-part-2
Packt
31 Dec 2009
5 min read
Save for later

Searching for Data in Microsoft Dynamics AX 2009: Part 2

Packt
31 Dec 2009
5 min read
Select statement One of the great features of Dynamics AX as a development tool is the possibility to write embedded SQL. This basically means that you can write select statements that are controlled by the compiler and get results back directly to table variables. The following list is taken from the SDK and shows the syntax for the select statement and the parameters allowed with the select statement: Desciption Syntax SelectStatement select Parameters Parameters [ [ FindOptions ] [ FieldList from ] ] TableBufferVariable [ IndexClause ] [ Options ] [ WhereClause ] [ JoinClause ] FindOptions crossCompany | reverse | firstFast | [ firstOnly | firstOnly10 | firstOnly100 | firstOnly1000 ] | forUpdate | noFetch | [forcePlaceholders | forceLiterals] | forceselectorder | forceNestedLoop | repeatableRead FieldList Field { , Field } | * Field Aggregate ( FieldIdentifier ) | FieldIdentifier Aggregate sum | avg | minof | maxof | count Options [ order by , group by , FieldIdentifier [ asc | desc ] { , FieldIdentifier [ asc | desc ] }] | [ IndexClause ] IndexClause index IndexName | index hint IndexName WhereClause where Expression JoinClause [exists | notexists | outer ] join Parameters Check out the SDK for a more in-depth explanation of all the different keywords. In the following examples, we will have a look at how to create different select statements depending on what data we would like to have available for the rest of the code. To have a better understanding of how the different select statements work and what data is returned, we will use the following data: CarTable The following table shows the test data for the CarTable: CarId ModelYear CarBrand Model Mileage 1 2007 BMW 320 2299 2 2007 Mercedes C220 2883 3 2008 Toyota Corolla 4032 4 2006 Vokswagen Golf 49902 5 2002 Jeep Grand Cherokee 65662 6 2003 BMW Z3 11120 7 2000 Volkswagen Golf 76322 RentalTable The following table shows the test data for the RentalTable: RentalId CustAccount FromDate ToDate CarId 1 1101 24.03.2009 25.03.2009 1 2 1103 23.03.2009 25.03.2009 3 3 1103 02.05.2009 11.05.2009 1 4 1102 10.05.2009 17.05.2009 5 5 1104 10.12.2009 20.12.2009 6 CustTable The following table shows the test data for the CustTable: Account Num Name CustGroup Blocked 1101 Forest Wholesales 10 No 1102 Sunset Wholesales 20 No 1103 Cave Wholesales 10 No 1104 Desert Wholesales 30 Yes Writing a simple select statement A select statement can be written specifically to return only one record or to return many records. If we expect the select statement to return multiple records and we would like to loop through these records, we simply embed the select statement within a while loop. The following examples will demonstrate how to write simple select statements that return different data from the same table. The first example will select all columns from all records in the CarTable as shown in the following Job: static void selectAllRecordsStatic(Args _args){CarTable carTable;int records;;info("------------------START-------------------");while select carTable{info("--------------NEW RECORD--------------");info (strfmt("CarId: %1", carTable.CarId));info (strfmt("CarBrand: %1", carTable.CarBrand));info (strfmt("Model: %1", carTable.Model));info (strfmt("ModelYear: %1", carTable.ModelYear));info (strfmt("Mileage: %1", carTable.Mileage));records++;}info("------------------END-------------------");info(strfmt("%1 records was selected", records));} Executing this Job will result in the following output to the Infolog. Note that only the first records are shown in the Infolog window. When executing it yourself, you can scroll down to see the other records at the end line. The Infolog screen is shown in the following screenshot: The next example actually does pretty much the same as the first example, but I have added some code to be able to dynamically write the fields in the table. It will also print all the systems fields for each record, but it can be a nice exercise for you to understand how you can use the Dict classes to create dynamic functionality, as shown in the following Job: static void selectAllRecordsDynamically(Args _args){CarTable carTable;DictField dictField;DictTable dictTable;int field;int fieldId;int records;str header, line;;// Create a new object of type DictTable based on the carTabledictTable = new DictTable(tablenum(carTable));// Loop through the fields on the table.// For each field, store the field-label in the header variable.for (field=1; field <= dictTable.fieldCnt(); field++){fieldId = dictTable.fieldCnt2Id(field);dictField = new DictField(tablenum(carTable), fieldId);header += strfmt("%1, ", dictField.label());}info(strupr(header)); // strupr changes the string to UPPERCASE// Loop through all the records in the carTablewhile select carTable{line = "";// For each record in the carTable, loop through all the//fields// and store the value of the field for this record in the//line variable.for (field=1; field <= dictTable.fieldCnt(); field++){fieldId = dictTable.fieldCnt2Id(field);dictField = new DictField(carTable.TableId, fieldId);// Instead of referencing to the fieldname, I reference to//field ID// to get the fields value.line += strfmt("%1, ", carTable.(fieldId));}info(line);records++;}info(strfmt("%1 records were selected", records));} Executing this Job will result in the following output to the Infolog: The next example will select all columns from the record in CarTable where the CarId equals 1. This means that we will only select one record and hence, we do not need the while loop: static void selectOneRecord(Args _args){CarTable carTable;;select firstonly carTablewhere carTable.CarId == "1";info (strfmt("Car Brand: %1", carTable.CarBrand));info (strfmt("Car Model: %1", carTable.Model));info (strfmt("Model Year: %1", carTable.ModelYear));info (strfmt("Mileage: %1", carTable.Mileage));} Executing this Job will result in the following output to the Infolog: The next example will select only the CarBrand and the Model columns from all records in the CarTable where the ModelYear is greater than 2005: static void selectWhereStatement(Args _args){CarTable carTable;;info(strupr("CarBrand, Model"));while select CarBrand, Model from carTablewhere carTable.ModelYear > 2005{info (strfmt("%1, %2 ", carTable.CarBrand, carTable.Model));}} Executing this Job will result in the following output to the Infolog: Executing this Job will result in the following output to the Infolog: Microsoft Dynamics AX 2009 Programming: Getting Started
Read more
  • 0
  • 0
  • 2080

article-image-configuring-jms-resources-glassfish-part-1
Packt
31 Dec 2009
10 min read
Save for later

Configuring JMS Resources in GlassFish: Part 1

Packt
31 Dec 2009
10 min read
JMS support on GlassFish Message-based solutions are playing an increasingly important role nowadays, as more and more systems need to be integrated together and need to communicate with each other in a loosely-coupled manner. In this section, we briefly introduce the core concepts of messaging system and the JMS standard, and then describe how GlassFish supports JMS resources. Message-based systems and JMS A simplified view of a typical message-based system is illustrated in the following figure. As shown in the figure, the communication pattern of a messaging-based system is different from the client-server paradigm, where application components communicate with each other directly. Instead, in a message-based system, the communication among application components (producers and consumers) is mediated by a message service provider. As a result of this, a message service provider is sometimes referred to as a Message Oriented Middleware (MOM). The producer creates a message that contains relevant data, and sends it to a destination resource maintained by the message service provider. The message is then routed to consumer components that are registered to the specific destination. Another distinct feature of a message-based system is that the message service provider effectively makes the communication between producers and consumers asynchronous. When a producer sends a message, consumers do not need to be available because the message service provider can persist the message until the consumer becomes available. In fact, the producer and consumer do not need to have any knowledge of each other, as long as the message is in a format that is agreed upon. This feature further decouples the producers and consumers. JMS defines a standard Java API for application components to create, send, receive, and process messages. It also provides a standard API that simplifies how application components interact with a JMS-compliant message service provider (JMS provider for short). It defines the connection factory and destinations of the JMS provider in the form of administered objects, which can be registered in a JNDI naming service. An application component can use the standard JNDI API to perform a lookup operation to retrieve these resources. This approach reduces the vendor-dependency when we build a JMS application. JMS defines the two messaging approaches as follows: Point-to-Point (PTP): A producer sends messages to a queue destination, which retains the messages until they are successfully routed to a consumer. Furthermore, each message is received by only one consumer. Publish/Subscribe (Pub/Sub): A producer sends messages to a topic destination. By default, the topic does not retain these messages. Instead, it immediately routes them to all the consumers registered for the topic. Due to this, if a message arrives at a topic when there is no active consumer, the message will be lost. To address this, JMS allows a consumer to be registered to the topic as durable subscriber. In this case, the JMS provider will retain the messages for this consumer until it becomes available. The JMS API became an integral part of the Java EE since version 1.3 as the standard to integrate with messaging systems. Subsequent Java EE revisions further enhanced the JMS API and messaging system integration in the following areas: Message-Driven Beans (MDB): An MDB is a container-managed component that can asynchronously consume messages sent to a JMS destination. Due to this, we can consider an MDB as an asynchronous message listener component. The application server's MDB container provides services for MDBs such as life cycle management, instance pooling and naming services. These services eliminate a lot of boiler-plate code necessary to create a message listener object. Due to this, when implementing an MDB, the developer only needs to focus on the logic about how to process messages delivered to the MDB. Furthermore, the MDB container's instance pooling service can significantly improve the throughput of processing messages routed to a specific MDB. Java Connector Architecture (JCA): Through JCA resource adapters, JMS providers can be easily integrated into different application servers. Once integrated, application components can treat them as standard JCA resources, and interact with the resources in a provider-independent manner. GlassFish support for JMS The GlassFish Server contains a built-in JMS service provider, the Open MQ (https://mq.dev.java.net). It also includes a generic JCA resource adapter that can be used to integrate with most JMS providers. GlassFish also provides a configurable MDB container implementation to host message driven beans. In this article, we discuss how GlassFish integrates with two different JMS providers—the Open MQ and Apache ActiveMQ (http://activemq.apache.org). We also discuss how we can configure the MDB container and MDB components to work with a JMS service provider. One of the most commonly asked questions is "Which JMS provider is better, or at least which open source JMS provider is better?". The answer to this question typically depends heavily on the experience of the individual or organization. Most reputable JMS implementations, including Open MQ and ActiveMQ are capable of processing large volumes of messages efficiently. Between Open MQ and ActiveMQ, my personal favorite choice is the former. The reason is not because Open MQ is bundled in GlassFish. It is actually because my experience with the Open MQ product dates back to the days of its commercial ancestor, the Sun ONE Message Queue. I have always appreciated its straightforward administration interface and thorough documentation. Furthermore, I have successfully created many production deployments by using the product. Make no mistake though; I have also witnessed organizations using ActiveMQ successfully in production. Also, ActiveMQ is under active development, and it is bundled in several very good open source products as the default JMS provider. Now, let's discuss how GlassFish works with the Open MQ product (https://mq.dev.java.net). Getting started with Open MQ An evolution of the Sun Java System Message Queue (formerly Sun ONE Message Queue), Open MQ is a very active open source sub-project of GlassFish. Open MQ implements a high-performance JMS provider. In addition to its high performance, and being fully JMS compliant, Open MQ provides many other features, such as message broker cluster support, SOAP/HTTP message support, C/C++ Client API support, and so on. Due to this, some people said Open MQ was the best kept secret within the Sun middleware software stack. The GlassFish Server is shipped with the Open MQ product. In addition, the GlassFish administration infrastructure provides some basic capabilities for configuring the Open MQ. The open source distribution of the GlassFish server you download from the GlassFish project site includes the "community edition" of Open MQ. This edition does not include some of the additional features such as C-API support. If you need to use these features, you can either download or install the Sun supported GlassFish Enterprise Server distribution, or download and install a full version of the Open MQ product. We should expect that in future versions of GlassFish, the bundled Open MQ will be a feature-complete distribution. By default, the bundled Open MQ is configured to have a small footprint without many advanced features. In this section, we will first get familiar with the Open MQ product, and later in this article we will show you how to configure the Open MQ to work with GlassFish and Java EE application components. First, let's examine the high-level architecture of GlassFish, and learn the meaning of some critical concepts along the way. The architecture of Open MQ The high-level architecture of Open MQ is illustrated in the following figure. The main components illustrated in this figure are explained as follows: The Broker can be considered as a complete instance of the message provider. A broker contains physical destinations (both queues and topics), and it is responsible for routing messages sent from producers to the appropriate destination, and delivering messages from destinations to registered consumers. The broker supports multiple connection mechanisms between application components and the broker, and it can also be configured with different performance and security features. In order to simplify and standardize the JMS programming model, JMS defines two types of administered objects—connection factories and destinations. A Connection Factory is an object that encapsulates all the vendor-specific information necessary for a client to establish a connection to the broker, and the destination object provides a logical reference to a physical destination. These two administered objects are registered in a JNDI-compliant object store, and a client can perform a standard JNDI lookup to retrieve these objects. Once these objects are retrieved, the client can produce and consume messages. A client can create these objects programmatically. For example, a client may want to use some vendor-specific features or APIs that cannot be encapsulated in a standard manner. However, this practice is highly discouraged. The directory structure of Open MQ The binary of the Open MQ software bundled with GlassFish is installed at$AS_INSTALL/imq. The high-level directory structure and essential files are described as follows: The bin directory contains the command line and GUI utilities for administering and controlling the MQ. The essential utilities include: imqadmin: The Open MQ GUI-based administration console. imqbrokerd: The broker management utility. imqcmd: The command-line administration utility of Open MQ. imqdbmgr: The utility to manage a JDBC-based message store. imqkeytool: The utility to generate self-signed SSL certifi cate for a broker. imqobjmgr: The utility to manage administered objects, including connection factory and destinations. imqusermgr: The utility to manage the flat file user repository for the Open MQ. The demo directory contains a variety of demo applications for Open MQ. The etc directory contains the Open MQ server-wide configuration file— imqenv.conf. This file effectively defines the environment variables for the Open MQ installation. For example, you should find the following line near the end of the file:IMQ_DEFAULT_VARHOME=/opt/glassfish/domains/domain1/imq This line specifi es that by default, all the brokers created within this Open MQ installation will be inside the /opt/glassfish/domains/domain1/imq directory. The include directory contains the C API header files for building C-based clients. The javadoc contains the Java API documentation for Open MQ. The lib directory contains the Java and C libraries for the Open MQ. The var directory is empty. In a standalone installation, this directory is the default root directory for all the brokers created. Once GlassFish is installed, a default OpenMQ broker, imqbroker is also created within the default domain in $AS_INSTALL/domains/domain1/imq/instances/imqbroker. The main content of this directory includes: The etc directory contains two files, the passwd is a password file for users configured for the broker, and the accesscontrol.properties file allows us to specify different types of access controls for different users. The fs370 directory is the flat file-based persistence store for messages and transactions. The log directory contains the rotated log files of running the broker. The props directory contains the config.properties file, which describes most of the properties configured for the broker. In the following section, we show you how to configure Open MQ.
Read more
  • 0
  • 0
  • 6268
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-searching-data-microsoft-dynamics-ax-2009-part-1
Packt
31 Dec 2009
10 min read
Save for later

Searching for Data in Microsoft Dynamics AX 2009: Part 1

Packt
31 Dec 2009
10 min read
Queries Queries are typically used to ask users about ranges and sorting, and then selecting data based on the feedback from the users. A query can consist of one or multiple data sources, and can be created both as static queries in the AOT or as dynamic queries using X++. Most commonly they are used when the ranges or values are not known until runtime. Static queries are defined in the AOT, whereas dynamic queries are defined in X++ code. Creating a static query using the AOT Follow these steps to create a static query in the AOT: Open the AOT, expand the Queries node, right-click on Queries, and select New Query. A new query is then created in the AOT. Right-click on the query, select Properties, and change the name to CarList (or in other cases, to something that describes what kind of data the query is returning). Open a new AOT window, expand the DataDictionary node, and then expand the Tables node. Drag the CarTable and drop it onto the Data Sources node of the new query. You can also drag maps or views to the data source of a query. You have now created the skeleton of the query. Let's now look at how to add sorting and ranges to the query. Adding a sort order to the query To add a sorting to the query, just drag the selected field from the Fields node under the data source and drop it under the Order By node. In our example, we'll use the Mileage field. You can then select to have it sort ascending or descending by changing the direction property on the sort field. When the query prompt is executed in a report, the user has the ability to change the sort order. Adding a range to the query You can also add ranges to the data source by dragging a field from the Fields node and dropping it onto the ranges. A range can be used to narrow down the result returned by the query, or it can be used as a fixed range that the user cannot change. This is done by adding a value to the value property of the range. Values in a range can be used like this: Range operator Description Example , Selects records where the range field matches any of the values listed BMW, VW, Volvo = Selects records where the range field is a matching value =VW .. Selects records where the range field is between the values specified including the values used. 1000..3000 < Selects records where the range field is less than the value specified <2000 > Selects records where the range field is greater than the value specified >2000 ! Selects records where the range field is not equal to the value specified !BMW ? Selects records where the ? can be any character Merc??es * Selects records where the range field matches the characters before or after the asterisk Merc* When the Status property is set to Open, the users can change the range value. If it's set to Lock, the users can see the range value before executing the query, but they are not allowed to change it. If the status property is set to Hide, the users won't even be allowed to see the range value. In our example, we add the ModelYear field from the data source CarTable_1: Joining data sources in a query In order to select data from more than one table, you can join the data sources in your query. Data sources can be joined in a couple of different ways depending on how you would like to link them. This is done by setting the JoinMode property to the different values shown in the following table: JoinMode Description InnerJoin Will return the records where the joined data sources have matching values in the joined fields. Ex: By using the CarTable as the primary data source and using RentalTable as the joined data source, the inner join will fetch all records from the CarTable where there is a corresponding record in the RentalTable. The corresponding records in RentalTable will also be fetched. OuterJoin Will return all the records from the joined table even if they don't match the joined field. Ex: Compared to the example using the InnerJoin, this will return all records from the CarTable, but also records from the RentalTable that does not have a match in the CarTable. ExistsJoin This is just like the InnerJoin, except the records from the joined data source are not returned. They are only used to filter the primary data source. Ex: In our example it will only return records in the CarTable where there is a match in the RentalTable. Records from the RentalTable will not be fetched. NoExistsJoin This is the opposite of ExistsJoin. It will select records from the primary data source when matching records in the joined data source does not exist. Ex: In our example it will return records from the CarTable that did not have any matching records in the RentalTable. (Cars that has never been rented) Follow these steps to add a new data source and join it with the first one: First, we will create a duplicate of the query that we have created so far, as we would like to use the original query in the Reporting Services report. To duplicate any AOT object, right-click on the object and select Duplicate. A duplicate is then created with the prefix CopyOf. Now rename the new query to RentalCarList. Also, change the range under the CarTable_1 data source to ModelYear instead of Model. This range will be used later in this article. Drag another table, map, or view, and drop it onto the Data Sources node below the first data source. In our example, we will add the RentalTable. Therefore, open a new AOT window and browse to Data Dictionary | Tables | RentalTable. Drag the RentalTable and drop it onto the Data Sources node under the CarTable data source in the query. Open the properties of the RentalTable data source in the query and change the Relations property to Yes. If you expand the Relations node under the RentalTable data source, you should now see that the CarTable data source is linked to the RentalTable data source by the CarId. Your AOT should look like this: Creating a dynamic query using X++ A query can also be built dynamically using X++ code. This can be the only way of creating the query, if you would like the query to work in one way in some cases and in another way in other cases. An example can be where you would like to join one table if one condition is true and another table if the condition is false. To do this, you need to understand how the query object model works. The most commonly used classes in the query object model are: Query: Contains the definition of the query. Can consist of one data source or several data sources if they are related. QueryRun: Class used to execute the query and loop through the result. QueryBuildDataSource: Links to one data source in the query. Can be linked to another QueryBuildDataSource object to join linked data sources. QueryBuildRange: Enables the end user to limit the result by adding a value in the specified query range. QueryBuildFieldList: List of all the fields in data source. OneQueryBuildFieldList object for each QueryBuildDataSource. By default the property Dynamic is set to true so that all fields are returned. QueryBuildLink: Links two data sources in a join. Is set on the child data source. The query definition is set up by creating and linking objects from the query object model together. The following example shows how this is done in order to create a similar query as we did in the previous section of this article when we created a query called RentalCarList in the AOT. static void queryRentalCarList(Args _args){Query query;QueryBuildDataSource queryBuildDataSource1,queryBuildDataSource2;QueryBuildRange queryBuildRange;QueryBuildLink queryBuildLink;;// Create a new query objectquery = new Query();// Add the first data source to the queryqueryBuildDataSource1 = query.addDataSource(tablenum(CarTable));// Add the range to this first data sourcequeryBuildRange = queryBuildDataSource1.addRange(fieldnum(CarTable, ModelYear));// Add the second datasource to the first data sourcequeryBuildDataSource2 =queryBuildDataSource1.addDataSource(tablenum(RentalTable));// Add the link from the child data source to the//parent datasourcequeryBuildLink = queryBuildDataSource2.addLink(fieldnum(CarTable,CarId),fieldnum(RentalTable, CarId));} Using a query Ok, so now we have the query definition. But that doesn't help us much unless we are able to execute the query, right? This example uses the previous example and just adds the QueryRun object and loops through the result by using the next() method on the QueryRun object. static void queryRunRentalCarList(Args _args){Query query;QueryBuildDataSource queryBuildDataSource1,queryBuildDataSource2;QueryBuildRange queryBuildRange;QueryBuildLink queryBuildLink;QueryRun queryRun;CarTable carTable;RentalTable rentalTable;;// Create a new query objectquery = new Query();// Add the first data source to the queryqueryBuildDataSource1 = query.addDataSource(tablenum(CarTable));// Add the range to this first data sourcequeryBuildRange = queryBuildDataSource1.addRange(fieldnum(CarTable, ModelYear));// Set the rangequeryBuildRange.value("2008..");// Add the second datasource to the first data sourcequeryBuildDataSource2 =queryBuildDataSource1.addDataSource(tablenum(RentalTable));// Add the link from the child data source to the parent data//sourcequeryBuildLink = queryBuildDataSource2.addLink(fieldnum(CarTable,CarId),fieldnum(RentalTable, CarId));// Create a new QueryRun object based on the query definitionqueryRun = new QueryRun(query);// Loop through all the records returned by the querywhile (queryRun.next()){// Get the table data by using the get() methodcarTable = queryRun.get(tablenum(CarTable));rentalTable = queryRun.get(tablenum(RentalTable));info (strfmt("CarId %1, RentalId %2", carTable.CarId,rentalTable.RentalId));}} The following result is obtained after running the query: The exact same result will show up if we execute the query that was defined in the AOT in the previous section of this article. The code would then look like this: static void queryRunRentalCarListAOT(Args _args){Query query;QueryBuildDataSource queryBuildDataSource;QueryBuildRange queryBuildRange;QueryRun queryRun;CarTable carTable;RentalTable rentalTable;;// Create a new query object based on the Query in the AOT called//RentalCarListquery = new Query(querystr(RentalCarList));// Find the datasource for the CarTablequeryBuildDataSource = query.dataSourceTable(tablenum(CarTable));// Find the range that we added to the query in the AOTqueryBuildRange =queryBuildDataSource.findRange(fieldnum(CarTable, ModelYear));// Set the value of the rangequeryBuildRange.value("2008..");// Create a new QueryRun object based on the query definitionqueryRun = new QueryRun(query);// Loop through all the records returned by the querywhile (queryRun.next()){// Get the table data by using the get() methodcarTable = queryRun.get(tablenum(CarTable));rentalTable = queryRun.get(tablenum(RentalTable));info (strfmt("CarId %1, RentalId %2", carTable.CarId,rentalTable.RentalId));}} Views Views in AX are objects that are used to retrieve data from the database that is stored in the memory on the layer in which the view is instantiated. The views are actually stored as database views on the SQL server. This means that there are potentially great performance benefits of using views compared to using an equivalent query. This depends of course on the complexity of the query, but in general the performance benefits of using a view compared to a query will increase along with the complexity of the query. Views can be used throughout AX in all places where tables can be used. This includes forms, queries, reports, and X++ code. Views in AX can never be used to write data, only to read data from the database. This differs from the SQL implementation that has write-back possibilities for views.
Read more
  • 0
  • 0
  • 7287

article-image-getting-started-spring-mvc-developing-mvc-components
Packt
31 Dec 2009
5 min read
Save for later

Getting Started With Spring MVC - Developing the MVC components

Packt
31 Dec 2009
5 min read
In the world of networked applications, thin clients (also known as web applications) are more in demand than thick clients. Due to this demand, every language is providing frameworks that try to make web-application development simpler. The simplicity is not provided just through setting up the basic application structure or generating boiler plate code. These frameworks are trying to provide simplicity through plug-ability of the frameworks i.e. the components of different frameworks could be brought together without much difficulty. Among such frameworks, Spring Framework is one of the most used. With its support to multiple Data Access frameworks/libraries and light-weight IoC container makes it suitable for scenarios where one would like mix-and-match multiple frameworks, a different one for each layer. This aspect of Spring Framework becomes more suitable for development of web-applications where the UI does not need to know with which framework it is dealing for business process or data access. The component of the Spring Framework stack that caters to the web UI is Spring MVC. In this discussion, we will focus on the basics of Spring MVC. First section will deal with the terms and terminologies related with Spring MVC and MVC. The second section will detail the steps for developing components of a web-application using Spring MVC. That is the agenda for this discussion. Spring MVC Spring MVC, as the name suggests, is a framework based on Model (M), View (V), Controller (C) pattern. Currently there are more than seven well known web-application frameworks that implement MVC pattern. Then what are the features of Spring MVC that sets it apart from other frameworks? The two main features are: Pluggable View technology Injection of services into controllers The former provides a way to use different UI frameworks instead of Spring MVC’s UI library and the latter removes the need to develop a new way to access functionality of business layer. Pluggable View technologyVarious View technologies are available in the market (including Tiles, Velocity, etc) with which Spring MVC can quite easily be integrated. In other words, JSP is not the only template engine supported. The pluggable feature is not limited to the templating technologies. By using common configuration functionality, other frameworks such as JSF can be integrated with Spring MVC applications. Thus, it is possible to mix-and-match different View technologies by using Spring MVC. Injection of Services into ControllersThis feature comes into picture when the Spring Framework is used to implement the business layer. Using the IoC capabilities of Spring Framework, the business layer services and/or objects can be injected into the Controller without explicitly setting up the call to the service or mirroring the business layer objects in controller. This helps in reduction of code duplication between Web UI/process layer and business process layer. The next important aspect of Spring MVC is its components. They are: Model (M) View (V) Controller (C) Model deals with the data that the application has to present, View contains the logic to present the data and Controller takes care of the flow of navigation and application logic. Following are the details. ModelModel is an object that holds the data to be displayed. It can be any Java object – from simple POJO to any type of Collection object. It can also be a combination of both – an instance of POJO to hold the detailed data and a collection object to hold all the instances of the POJO which, in reality, is most commonly used Model in Spring MVC. Also, the framework has its own way to hold the data. It holds the data using the Model object that is an instance of org.springframework.ui.ModelMap. Internally, whichever collection class object is used, the framework maps it to the ModelMap class. ViewIn MVC, it is the View that presents the data to the user. Spring MVC, just as many other JEE frameworks, uses a combination of JSP and tag libraries to implement View. Apart from using JSP, many kinds of View technologies like Tiles, Velocity, and Jasper Reports can be plugged into the Framework. The main class behind this plug ability is the org.springframework.web.servlet.View. The View class achieves the plug-in functionality by presenting the View as Logical View instead of actual/physical View. Physical view corresponds to the page developed using any of the templating technologies. The Logical View corresponds to the name of the View to be used. The name is then mapped to the actual View in the configuration file. One important point to remember about how Spring MVC uses Logical View is that Logical View and Model are treated as one entity named Model And View represented by org.springframework.web.servlet.ModelAndView class. ControllerThe flow of application and navigation is directed by the controller. It also processes the user input and transforms it into the Model. In Spring MVC, controllers are developed either by extending the out-of-the-box Controller classes or implementing the Controller interface. Following comes under the former category SimpleFormController AbstractController AbstractCommandController CancellableFormController AbstractCommandController MultiActionController ParameterizableViewController ServletForwardingController ServletWrappingController UrlFilenameViewController Of these most commonly used are AbstractController, AbstractCommandController, SimpleFormController and CancellableFormController. That wraps up this section. Let us move onto the next section – steps for developing an application using Spring MVC.
Read more
  • 0
  • 0
  • 2726

article-image-including-google-maps-your-posts-using-apache-roller-40
Packt
31 Dec 2009
5 min read
Save for later

Including Google Maps in your Posts Using Apache Roller 4.0

Packt
31 Dec 2009
5 min read
Google Maps, YouTube, and SlideShare There are a lot of Internet and web services which you can use along with your blog to make your content more interesting for your viewers. With a good digital camera and video production software, you can make your own videos and presentations quickly and easily, and embed them in your posts with just a few clicks! For example, with Google Maps, you can add photos of your business to a custom map, and post it in your blog to attract customers. There are a lot of possibilities, and it all depends on your creativity! Including Google Maps in your posts Using Google Maps in your blog is a good way of promoting your business because you can show your visitors your exact location. Or you can blog about your favorite places and show them as if you were there, using your own photos. Time for action – using Google Maps There are a lot of things you can do with Google Maps, one of them is including maps of your favorite places in your blog, as we'll see in a moment: Open your web browser and go to Google Maps (http://maps.google.com). Type Eiffel Tower in the search textbox, and click on the Search Maps button or press Enter. Your web browser window will split in two areas, as shown in the following screenshot: Click on the Eiffel Tower link at the bottom-left part of the screen to see the Eiffel Tower's exact position in the map at the right panel:  Now click on the Satellite button to see a satellite image of the Eiffel Tower:      Drag the Eiffel Tower upwards using your mouse, to center it on the map area: Click on the Zoom here link inside the Eiffel Tower caption to see a closer image: If you look closely at the previous screenshot, you'll notice three links above the map: Print, Send, and Link. Click on Link to open a small window: Right-click on the Paste HTML to embed in website field to select the HTML code, and then click on the Copy option from the pop-up menu: Open a new web browser window and log into your Roller weblog. In the New Entry page, type The Eiffel Tower inside the Title field, and Eiffel Tower Google Maps inside the Tags field. Then click on the Toggle HTML Source button in the Rich Text editor toolbar, type This is an Eiffel Tower satellite image, courtesy of Google Maps:<br> inside the Content Field, press Enter, and paste the code you copied from the Google Maps web page: Scroll down the New Entry page and click on the Post to Weblog button. Then click on the Permalink field's URL, to see your Google Maps image posted in your blog. Click on the Zoom here link once to see a close-up of the Eiffel Tower, as shown in the following screenshot: What just happened? Now you can add Google Maps functionality inside your blog! Isn't that great? You just need to copy and paste the HTML code that the Google Maps produce automatically for you. If you want a bigger or smaller map, you can click on the Customize and preview embedded map link to customize the HTML code that you're going to paste into your blog: Then you just copy the HTML code produced by Google Maps and paste it into your blog post: If you have a Google Maps account, you can create customized maps and show them to your visitors, add photos and videos of places you've visited, and even write reviews about your favorite restaurants and hotels. Have a go hero – explore Google Maps Now that you've seen how to embed Google Maps in your weblog, it would be a great idea to create your own Google Maps account, and start exploring all the things that you can do—inserting photos and videos about places you've visited in your own custom maps, adding reviews of restaurants and other businesses in your locality, and so on. You can explore other users' maps, too. Once you get the hang of it, you'll be traveling around the world and meeting new people from your own PC. Including YouTube videos in your posts YouTube is one of the most popular video sharing websites in the world. You can include your favorite videos in your blog, or make your own videos and show them to your visitors. However, before you start complaining that we have already seen how to insert videos on your weblog, let me tell you that the big difference between uploading a video to your own blog server and uploading a video to a YouTube server is bandwidth. When someone plays back a video from your weblog, the blog server transfers the video data to your visitor's web browser, so that he/she can begin to see it, even before the video downloads completely. This is known as video streaming. Now, imagine you have 1,000 visitors, and each one of them is viewing the same video from your weblog! There would be a big amount of data flowing from your weblog to each visitor's web browser! That amount of data flowing from one PC to another is called bandwidth. You would need a very broad connection to be capable of transmitting your video to all those visitors. That's where YouTube comes into play. They have lots of bandwidth available for you and the other millions of users who share videos daily! So, if you plan to include a lot of videos in your weblog, it would be a great idea to get a YouTube account and start uploading them. In the following exercise, I'll show you how to include a YouTube video in your post, without having to upload it to your weblog.
Read more
  • 0
  • 0
  • 6090

article-image-creating-web-application-jboss-5
Packt
31 Dec 2009
7 min read
Save for later

Creating a Web Application on JBoss AS 5

Packt
31 Dec 2009
7 min read
Wonder what was the first message sent through Internet? At 22:30 hours on October 29, 1969, a message was transmitted using ARPANET (the predecessor of the global Internet) on a host-to-host connection. It was meant to transmit "login". However, it transmitted just "lo" and crashed. Developing web layout The basic component of any Java web application is the servlet. Born in the middle of the 90s, servlets quickly gained success against their competitors, the CGI scripts. This was because of some innovative features, especially the ability to execute requests concurrently, without the overhead of creating a new process for each request. However, a few things were missing, for example, the servlet API did not address any APIs specifically for creating the client GUI. This resulted in multiple ways of creating the presentation tier, generally with tag libraries that differed from job to job and from individual developers. The second thing that was missing in the servlet specification was a clear distinction between the presentation tier and the backend. A plethora of web frameworks tried to fill this gap; particularly the Struts framework effectively realized a clean separation of the model (application logic that interacts with a database) from the view (HTML pages presented to the client) and the controller (instance that passes information between view and model). However, the limitation of these frameworks was that even if they realized a complete modular abstraction, they still failed as they always exposed theHttpServletRequest and HttpServletSessionobjects to their action(s). Their actions, in turn, needed to accept the interface contracts such as ActionForm, ActionMapping, and so on. The JavaServer Faces that emerged on the stage a few years later pursued a different approach. Unlike request-driven Model–View–Controller (MVC) web frameworks, JSF chose a component-based approach that ties the user interface component to a well-defined request processing lifecycle. This greatly simplifies the development of web applications. The JSF specification allows you to have presentation components be POJOs. This creates a cleaner separation from the servlet layer and makes it easier to do testing by not requiring the POJOs to be dependent on the servlet classes. In the following sections, we will describe how to create a web layout for our application store using the JSF technology. For an exhaustive explanation of the JSF framework, we suggest you to surf the JSF homepage at http://java.sun.com/javaee/javaserverfaces/. Installing JSF on JBoss AS JBoss AS already ships with the JSF libraries, so the good news is that you don't need to download or install them in the application server. There are different implementations of the JSF libraries. Earlier JBoss releases adopted the Apache MyFaces library. JBoss AS 4.2 and 5.x ship with the Common Development and Distribution License (CDDL) implementation (now called "Project Mojarra") of the JSF 1.2 specification that is available from the java.net open source community. Switching to another JSF implementation is anyway possible. All you have to do is package your JSF libraries with your web application and configure your web.xml to ignore the JBoss built-in implementation: <context-param><param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name><param-value>true</param-value></context-param> We will start by creating a new JSF project. From the File menu, select New | Other | JBoss Tools Web | JSF | JSF Web project. The JSF applet wizard will display, requesting the Project Name, the JSF Environment, and the default starting Template. Choose AppStoreWeb as the project name, and check that the JSF Environment used is JSF 1.2. You can leave all other options to the defaults and click Finish. Eclipse will now suggest that you switch to the Web Projects view that logically assembles all JSF components. (It seems that the current release of the plugin doesn't understand your choice, so you have to manually click on the Web Projects tab.) The key configuration file of a JSF application is faces-config.xml contained in the Configuration folder. Here you declare all navigation rules of the application and the JSF managed beans. Managed beans are simple POJOs that provide the logic for initializing and controlling JSF components, and for managing data across page requests, user sessions, or the application as a whole. Adding JSF functionalities also requires adding some information to your web.xml file so that all requests ending with a certain suffix are intercepted by the Faces Servlet. Let's have a look at the web.xml configuration file: <?xml version="1.0"?><web-app version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><display-name>AppStoreWeb</display-name><context-param><param-name>javax.faces.STATE_SAVING_METHOD</param-name><param-value>server</param-value></context-param><context-param> [1]<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name><param-value>true</param-value></context-param><listener><listener-class>com.sun.faces.config.ConfigureListener</listener-class></listener><!-- Faces Servlet --><servlet><servlet-name>Faces Servlet</servlet-name><servlet-class>javax.faces.webapp.FacesServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><!-- Faces Servlet Mapping --><servlet-mapping><servlet-name>Faces Servlet</servlet-name><url-pattern>*.jsf</url-pattern></servlet-mapping><login-config><auth-method>BASIC</auth-method></login-config></web-app> The context-param pointed out here [1] is not added by default when you create a JSF application. However, it needs to be added, else you'll stumble into an annoying ViewExpiredException when your session expires (JSF 1.2). Setting up navigation rules In the first step, we will define the navigation rules for our AppStore. A minimalist approach would require a homepage that displays the orders, along with two additional pages for inserting new customers and new orders respectively. Let's add the following navigation rule to the faces-config.xml: <faces-config><navigation-rule><from-view-id>/home.jsp</from-view-id> [1]<navigation-case><from-outcome>newCustomer</from-outcome> [2]<to-view-id>/newCustomer.jsp</to-view-id></navigation-case><navigation-case><from-outcome>newOrder</from-outcome> [3]<to-view-id>/newOrder.jsp</to-view-id></navigation-case></navigation-rule><navigation-rule><from-view-id></from-view-id> [4]<navigation-case><from-outcome>home</from-outcome><to-view-id>/home.jsp</to-view-id></navigation-case></navigation-rule></faces-config> In a navigation rule, you can have one from-view-id that is the (optional) starting page, and one or more landing pages that are tagged as to-view-id. The from-outcome determines the navigation flow. Think about this parameter as a Struts forward, that is, instead of embedding the landing page in the JSP/servlet, you'll simply declare a virtual path in your JSF beans. Therefore, our starting page will be home.jsp [1] that has two possible links—the newCustomer.jsp form [2] and the newOrder.jsp form [3]. At the bottom, there is a navigation rule that is valid across all pages [4]. Every page requesting the home outcome will be redirected to the homepage of the application. The above JSP will be created in a minute, so don't worry if Eclipse validator complains about the missing pages. This configuration can also be examined from the Diagram tab of your faces-config.xml: The next piece of code that we will add to the confi guration is the JSF managed bean declaration. You need to declare each bean here that will be referenced by JSF pages. Add the following code snippet at the top of your faces-config.xml (just before navigation rules): <managed-bean><managed-bean-name>manager</managed-bean-name> [1]<managed-bean-class>com.packpub.web.StoreManagerJSFBean</managed-bean-class> [2]<managed-bean-scope>request</managed-bean-scope> [3]</managed-bean> The <managed-bean-name> [1] element will be used by your JSF page to reference your beans. The <managed-bean-class> [2] is obviously the corresponding class. The managed beans can then be stored within the request, session, or application scopes, depending on the value of the <managed-bean-scope> element [3].
Read more
  • 0
  • 0
  • 2729
article-image-integrating-spring-framework-hibernate-orm-framework-part-1
Packt
31 Dec 2009
6 min read
Save for later

Integrating Spring Framework with Hibernate ORM Framework: Part 1

Packt
31 Dec 2009
6 min read
Spring is a general-purpose framework that plays different roles in many areas of application architecture. One of these areas is persistence. Spring does not provide its own persistence framework. Instead, it provides an abstraction layer over JDBC, and a variety of O/R mapping frameworks, such as iBATIS SQL Maps, Hibernate, JDO, Apache OJB, and Oracle TopLink. This abstraction allows consistent, manageable data-access implementation. Spring's abstraction layer abstracts the application from the connection factory, the transaction API, and the exception hierarchies used by the underlying persistence technology. Application code always uses the Spring API to work with connection factories, utilizes Spring strategies for transaction management, and involves Spring's generic exception hierarchy to handle underlying exceptions. Spring sits between the application classes and the O/R mapping tool, undertakes transactions, and manages connection objects. It translates the underlying persistence exceptions thrown by Hibernate to meaningful, unchecked exceptions of type DataAccessException. Moreover, Spring provides IoC and AOP, which can be used in the persistence layer. Spring undertakes Hibernate's transactions and provides a more powerful, comprehensive approach to transaction management. The Data Access Object pattern Although you can obtain a Session object and connect to Hibernate anywhere in the application, it's recommended that all interactions with Hibernate be done only through distinct classes. Regarding this, there is a JEE design pattern, called the DAO pattern. According to the DAO pattern, all persistent operations should be performed via specific classes, technically called DAO classes. These classes are used exclusively for communicating with the data tier. The purpose of this pattern is to separate persistence-related code from the application's business logic, which makes for more manageable and maintainable code, letting you change the persistence strategy flexibly, without changing the business rules or workflow logic. The DAO pattern states that we should define a DAO interface corresponding to each DAO class. This DAO interface outlines the structure of a DAO class, defines all of the persistence operations that the business layer needs, and (in Spring-based applications) allows us to apply IoC to decouple the business layer from the DAO class. Service Facade Pattern In implementation of data access tier, the Service Facade Pattern is always used in addition to the DAO pattern. This pattern indicates using an intermediate object, called service object, between all business tier objects and DAO objects. The service object assembles the DAO methods to be managed as a unit of work. Note that only one service class is created for all DAOs that are implemented in each use case. The service class uses instances of DAO interfaces to interact with them. These instances are instantiated from the concrete DAO classes by the IoC container at runtime. Therefore, the service object is unaware of the actual DAO implementation details. Regardless of the persistence strategy your application uses (even if it uses direct JDBC), applying the DAO and Service Facade patterns to decouple application tiers is highly recommended. Data tier implementation with Hibernate Let's now see how the discussed patterns are applied to the application that directly uses Hibernate. The following code shows a sample DAO interface: package com.packtpub.springhibernate.ch13;import java.util.Collection;public interface StudentDao { public Student getStudent(long id); public Collection getAllStudents(); public Collection getGraduatedStudents(); public Collection findStudents(String lastName); public void saveStudent(Student std); public void removeStudent(Student std);} The following code shows a DAO class that implements this DAO interface: package com.packtpub.springhibernate.ch13;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.HibernateException;import org.hibernate.Query;import java.util.Collection;public class HibernateStudentDao implements StudentDao { SessionFactory sessionFactory; public Student getStudent(long id) { Student student = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); student = (Student) session.get(Student.class, new Long(id)); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return student; } public Collection getAllStudents(){ Collection allStudents = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); Query query = session.createQuery( "from Student std order by std.lastName, std.firstName"); allStudents = query.list(); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return allStudents; } public Collection getGraduatedStudents(){ Collection graduatedStudents = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); Query query = session.createQuery( "from Student std where std.status=1"); graduatedStudents = query.list(); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return graduatedStudents; } public Collection findStudents(String lastName) { Collection students = null; Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); Query query = session.createQuery( "from Student std where std.lastName like ?"); query.setString(1, lastName + "%"); students = query.list(); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } return students; } public void saveStudent(Student std) { Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); session.saveOrUpdate(std); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } } public void removeStudent(Student std) { Session session = HibernateHelper.getSession(); Transaction tx = null; try { tx = session.beginTransaction(); session.delete(std); tx.commit(); tx = null; } catch (HibernateException e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; }} As you can see, all implemented methods do routines. All obtain a Session object at first, get a Transaction object, perform a persistence operation, commit the transaction, rollback the transaction if exception occurs, and finally close the Session object. Each method contains much boilerplate code that is very similar to the other methods. Although applying the DAO pattern to the persistence code leads to more manageable and maintainable code, the DAO classes still include much boilerplate code. Each DAO method must obtain a Session instance, start a transaction, perform the persistence operation, and commit the transaction. Additionally, each DAO method should include its own duplicated exception-handling implementation. These are exactly the problems that motivate us to use Spring with Hibernate. Template Pattern: To clean the code and provide more manageable code, Spring utilizes a pattern called Template Pattern. By this pattern, a template object wraps all of the boilerplate repetitive code. Then, this object delegates the persistence calls as a part of functionality in the template. In the Hibernate case, HibernateTemplate extracts all of the boilerplate code, such as obtaining a Session, performing transaction, and handing exceptions.
Read more
  • 0
  • 0
  • 4062

article-image-five-years-ubuntu
Packt
31 Dec 2009
3 min read
Save for later

Five Years of Ubuntu

Packt
31 Dec 2009
3 min read
Community If there is any one word that could sum up Ubuntu, it would be Community.  Even the definition of the word "Ubuntu" makes reference to community, and how the betterment of the individual and community are interconnected. Nearly everyone I've met through Ubuntu in the last five years cites the community as the single major reason for their use. In many aspects, Ubuntu is technically equal to its competitors, but nowhere else will you find the same level of community support. Nowhere else will you find the same level of friendship and positive atmosphere. Over the last five years I have tested many alternate Linux distributions and I have yet to find any other community that is as accepting, or that goes out of their way to invite you into the group. The Ubuntu community has so many people actively engaged in trying to provide a positive environment, it is truly amazing. If you find yourself at an Ubuntu event, don't be surprised if you actually see hugs! And watch out, it is contagious! The source of this positive community atmosphere is the guidance of the Ubuntu Code of Conduct. From the beginning, Ubuntu has had a Code of Conduct, and active contributing community members are expected to understand and sign the document. By outlining in clear terms what is expected of a community member, and keeping it forefront in members minds, Ubuntu is able to foster an atmosphere of mutual respect. This one simple document is what sets Ubuntu apart from every other online community. Sure you can find a community of contributors to any project, but nowhere else will you find the same respect and welcoming atmosphere that you'll find in Ubuntu. Simplicity Ubuntu introduced a level of simplicity to the Linux environment that hasn't been seen before. What has historically been a hobbyist operating system has been tuned and refined to the point that truly anyone can install and use it. Before Ubuntu, a user would need to be familiar with partitioning and package selections (at minimum!) in order to install a machine. With Ubuntu a machine can be installed with a very sane set of default tools without any technical decision making from the user. With tools such as Wubi, now included on Ubuntu installation disks, a user is able to install Ubuntu alongside an existing Windows installation and have the two peacefully coexist. Giving the user the ability to try-before-you-buy, and leave current installations and data intact have also drastically improved the userbase and adoption rate. Ubuntu was also the first to promote a single CD installation. Where most other Linux distributions were offering DVD based installations, Ubuntu packaged a core selection onto a single CD and offered those for download. They even offered to send free CDs through the mail to anyone that requested them! It doesn't get much simpler than than! The truly amazing thing about this simplicity is that, despite being limited to a single 700MB CD, Ubuntu comes with a plethora of software. The base installation provides a comprehensive desktop environment, including a full office suite, web browser, mail client, audio and video tools and more! This emphasis on delivering a highly refined, usable environment from the start is a very important aspect of Ubuntu.
Read more
  • 0
  • 0
  • 4905

article-image-starting-tomcat-6-part-2
Packt
31 Dec 2009
8 min read
Save for later

Starting Up Tomcat 6: Part 2

Packt
31 Dec 2009
8 min read
Bootstrapping the embedded container As we saw earlier, Bootstrap is simply a convenience class that is used to run the Embedded class, or rather to run Catalina, which subclasses Embedded. The Catalina class is intended to add the ability to process a server.xml file to its parent class. It even exposes a main() method, so you can invoke it directly with appropriate command-line arguments. Bootstrap uses its newly constructed serverLoader to load the Catalina class, which is then instantiated. It delegates the loading process to this Catalina instance's load() method. This method updates the catalina.base and catalina.home system properties to absolute references, verifies that the working directory is set appropriately, and initializes the naming system, which is Tomcat's implementation of the JNDI API. For now, all we need to note is that it indicates that JNDI is enabled by setting the catalina.useNaming system property to true, and prefixing the Context.URL_PKG_PREFIXES system property with the package org.apache.naming using a colon delimiter. The Context.URL_PKG_PREFIXES property indicates a list of fully qualified package prefixes for URL context factories. Setting org.apache.naming as the first entry makes it the first URL context factory implementation that will be located. For the java:comp/env Environment Naming Context (ENC), the actual class name for the URL context factory implementation is generated as org.apache.naming.java.javaURLContextFactory. If the Context.INITIAL_CONTEXT_FACTORY is currently not set for this environment, then this is set as the default INITIAL_CONTEXT_FACTORY to be used. Bootstrapping the Tomcat component hierarchy The configuration for a Tomcat instance is found in the confserver.xml file. This file is now processed, converting each element found into a Java object. The net result at the end of this processing is a Java object tree that mirrors this configuration file. This conversion process is facilitated by the use of the Apache Commons Digester project (http://commons.apache.org/digester/), an open source Commons project that allows you to harness the power of a SAX parser while at the same time avoiding the complexity that comes with event driven parsing. Commons Digester The Digester project was originally devised as a way of unmarshalling the struts-config.xml configuration file for Struts, but was moved out to a Commons project due to its general purpose usefulness. The basic principle behind the Digester is very simple. It takes an XML document and a RuleSet document as inputs, and generates a graph of Java objects that represents the structure that is defined in the XML instance document. There are three key concepts that come into play when using the Digester—a pattern, a rule, and an object stack. The pattern As the digester parses the input XML instance document, it keeps track of the elements it visits. Each element is identified by its parent's name followed by a forward slash ('/') and then by its name. For instance, in the example document below, the root element is represented by the pattern rolodex. Two <contact> elements are represented by the pattern rolodex/contact, the <company> elements are represented by the pattern rolodex/contact/company, and so on. <rolodex type=paperSales><contact id="1"><firstname>Damodar</firstname><lastname>Chetty</lastname><company>Software Engineering Solutions, Inc.</company></contact><contact id="2"><firstname>John</firstname><lastname>Smith</lastname><company>Ingenuitix, Inc.</company></contact></rolodex> The rule A rule specifies the action(s) that the Digester should take when a particular pattern is encountered. The common rules you will encounter are: Creational actions (create an instance of a given class to represent this XML element) Property setting actions (call setters on the Java object representing this XML element, passing in the value of either a child element or an attribute) Method invocation actions (call the specified method on the Java object representing this element, passing in the specified parameters) Object linking actions (set an object reference by calling a setter on one object while passing in the other as an argument) The object stack As objects are created, using the creational actions discussed above, Digester pushes them to the top of its internal stack. All actions typically affect the object at the top of the stack. A creational action will automatically pop the element on the top of the stack when the end tag for the pattern is detected. Using the Digester The typical sequence of actions is to create an object using a creational action, set its properties using a property setting action, and once the object is fully formed, to pop it off the top of the stack by linking it to its parent, which is usually just below it on the stack. Once the child has been popped off, the parent is once again at the top of the stack. This repeats as additional children objects are created, initialized, linked, and popped. Once all the children are processed and the parent object is fully initialized, the parent itself is popped off the stack, and we are done. You instantiate an org.apache.commons.digester.Digester by invoking the createDigester() method of org.apache.commons.digester.xmlrules.DigesterLoader and passing it the URL for the file containing the patterns and rules. Patterns and rules can also be specified programmatically by calling methods directly on the digester instance. However, defining them in a separate XML RuleSet instance document is much more modular, as it extracts rule configuration out of program code, making the code more readable and maintainable. Then, you invoke the parse() method of a Digester instance and pass it the actual XML instance document. The digester uses its configured rules to convert elements in the instance document into Java objects. The server.xml Digester The Catalina instance creates a Digester to process the server.xml file. Every element in this file is converted into an instance of the appropriate class, its properties are set based on configuration information in this file, and connections between the objects are set up, until what you are left with is a functioning framework of classes. This ability to configure the structure of cooperating classes using a declarative approach makes it easy to customize a Tomcat installation with very little effort. The createStartDigester() method in Catalina does the work of instantiating a new Digester and registering patterns and rules with it. The Catalina instance is then pushed to the top of the Digester stack, making it the root ancestor for all the elements parsed from the server.xml document. The rules can be described as follows: Pattern Rule Server Creational action: Instantiates an org.apache.catalina.core.StandardServer Set properties action: Copies attribute values over to the topmost object of the stack using mutator methods that are named similarly to the attribute Object linking action: Invokes setServer()to set this newly minted Server instance on the Catalina instance found on the stack. Server/ GlobalNamingResources Creational action: Instantiate an org.apache.catalina.deploy.NamingResources Set properties action: Copies attribute values from this element over to the topmost object on the stack Object linking action: Sets this newly instantiated object on the StandardServer instance at the top of the stack, by invoking its setGlobalNamingResources(). Server/Listener Creational action: Instantiate the class specified by the fully qualified class name provided as an attribute. Set properties action: Copy attributes from this element. Object linking action: Sets this instance on the StandardServer instance at the top of the stack, by invoking its addLifecycleListener() method with this new instance. Server/Service Creational action: Instantiates an org.apache.catalina.core.StandardService. Set properties action: Copy attributes from this element Object linking action: Invokes addService()on the StandardServer instance at the top of the stack passing in this newly minted instance Server/Service/Listener Creational action: Instantiate the class specified by the fully qualified class name provided as the className attribute Set properties action: Copy attributes from this element Object linking action: Invokes addLifecycleListener() on the StandardService instance at the top of the stack, passing in this listener instance Server/Service/Executor   Creational action: Instantiate the class org.apache.catalina.core.StandardThreadExecutor Set properties action: Copy attributes for this element Object linking action: Invokes addExecutor() with this instance, on the StandardService instance at the top of the stack Server/Service/Connector   Creational action: Instantiate the class org.apache.catalina.startup.ConnectorCreateRule Set properties action: Copy all attributes for this element except for the executor property Object linking action: Invokes addConnector(), passing in this instance, on the StandardService instance at the top of the stack Server/Service/Connector/Listener   Creational action: Instantiate the class specified by the fully qualified class name provided as the className attribute Set properties action: Copy attributes from this element Object linking action: Invokes addLifecycleListener(), passing in this instance, on the Connector instance at the top of the stack Server/Service/Engine   Set the Engine instance's parent class loader to the serverLoader
Read more
  • 0
  • 0
  • 1531
article-image-installing-openvpn-linux-and-unix-systems-part-1
Packt
31 Dec 2009
10 min read
Save for later

Installing OpenVPN on Linux and Unix Systems: Part 1

Packt
31 Dec 2009
10 min read
Prerequisites All Linux/Unix systems must meet the following requirements to install OpenVPN successfully: Your system must provide support for the Universal TUN/TAP driver. The kernels newer than version 2.4 of almost all modern Linux distributions provide support for TUN/TAP devices. Only if you are using an old distribution or if you have built your own kernel, will you have to add this support to your configuration. This project's web site can be found at http://vtun.sourceforge.net/tun/. OpenSSL libraries have to be installed on your system. I have never encountered any modern Linux/Unix system that does not meet this requirement. However, if you want to compile OpenVPN from source code, the SSL development package may be necessary. The web site is http://www.openssl.org/. The Lempel-Ziv-Oberhumer (LZO) Compression library has to be installed. Again, most modern Linux/Unix systems provide these packages, so there shouldn't be any problem. LZO is a real-time compression library that is used by OpenVPN to compress data before sending. Packages can be found on http://openvpn.net/download.html, and the web site of this project is http://www.oberhumer.com/opensource/lzo/. Most Linux/Unix systems' installation tools are able to resolve these so-called dependencies on their own, but it might be helpful to know where to get the required software. Most commercial Linux systems, like SuSE, provide installation tools, like Yet another Setup Tool (YaST), and contain up-to-date versions of OpenVPN on their installation media (CD or DVD). Furthermore, systems based on RPM software can also install and manage OpenVPN software at the command line. Linux systems, like Debian, use sophisticated package management tools that can install software that is provided by repositories on web servers. No local media is needed, the package management will resolve potential dependencies by itself, and install the newest and safest possible version of OpenVPN. FreeBSD and other BSD-style systems use their package management tools such as pkg_add or the ports system. Like all open source projects, OpenVPN source code is available for download. These compressed tar.gz or tar.bz2 archives can be downloaded from http://openvpn.net/download.html and unpacked to a local directory. This source code has to be configured and translated (compiled) for your operating system. You can also install unstable, developer, or older versions of OpenVPN from http://openvpn.net/download.html. This may be interesting if you want to test new features of forthcoming versions. Daily (unstable!) OpenVPN source code extracts can be obtained from http://sourceforge.net/cvs/?group_id=48978. Here you find the Concurrent Versions System (CVS) repository, where all OpenVPN developers post their changes to the project files. Installing OpenVPN on SuSE Linux Installing OpenVPN on SuSE Linux is almost as easy as installing under Windows or Mac OS X. Linux users may consider it even easier. On SuSE Linux almost all administrative tasks can be carried out using the administration interface YaST. OpenVPN can be installed completely using this. The people distributing SuSE have always tried to include up-to-date software in their distribution. Thus, the installation media of OpenSuSE 11 already contains version 2.0.9 of OpenVPN, and both the Enterprise editions SLES 10 and the forthcoming SLES 11 that offer five years of support. Updates include up-to-date versions of OpenVPN. Both OpenSuSE and SLES use YaST for installing software. Using YaST to install software Start YaST. Under both GNOME and the K Desktop Environment (KDE—the standard desktop under SuSE Linux), you will find YaST in the main menu under System | YaST, or as an icon on the Desktop. If you are logged in as a normal user, you will be prompted to enter your root password and confirm the same. The YaST control center is started. This administration interface consists of many different modules, which are represented by symbols in the right half of the window and grouped by the labels on the left. After starting YaST, click on the symbol labeled Software Management in the right column to start the software management interface of YaST. The software management tool in YaST is very powerful. Under SuSE, data about the installed and installable software is kept in a database, which can be searched very easily. Select the entry Search in the drop-down list Filter: and enter openvpn in the Search field. YaST will find at least one entry that matches your search value openvpn. Depending on the (online) installation sources that you have configured, various add-ons and tools for OpenVPN will be found. If you chose to add the community repositories like I did on this system, then OpenSuSE will list more than 10 hits. Select the entry openvpn by checking the box besides the entry in the first column. If you want to obtain information about the OpenVPN package, have a look at the lower half of the right side—here you will find the software Description, Technical Data, Dependencies, and more information about the package that you have selected. Click on the Accept button to start the OpenVPN installation. If you installed from a local medium, then put your CD or DVD in your local drive now. YaST will retrieve the OpenVPN files from your installation media. If you have configured your system to use one of the web/FTP servers of SuSE for installation, then this might take a while. The files are unpacked and installed on your system, and YaST updates the configuration. This is managed by the script SuSEconfig and other scripts that are called by it. SuSEconfig and YaST were once very infamous for deleting local configuration created by the local administrator or omitting relevant changes. This problem only occurred when updating and re-installing software that was previously installed. However, the latest SuSE versions have proven very reliable, and the system configuration tools never delete configuration files that you have added manually. Instead, the standard configuration files installed with the new software package may be renamed to <file>.rpmnew or similar, and your configuration is loaded. During installation, SuSEconfig calls several helper scripts and updates your configuration, and informs you of the progress in a separate window. After successful software installation, you are prompted if you want to install more packages or exit the installation. Click on the Finish button. The Novell/OpenSuSE teams have added a very handy tool called zypper to their package management. From version 10.1 onwards, you can simply install software from a root console by typing zypper in openvpn. Of course this only works if you know the exact name of the package that you want to install. If not, then you will have to search for it, for example, by using zypper search vpn. Installing OpenVPN on Red Hat Fedora using yum If you are using Red Hat Fedora, the Yellow dog Updater, Modified (yum) is probably the easiest way to install software. It can be found on http://linux.duke.edu/projects/yum/, and provides many interesting features, such as automatic updates, solving dependency problems, and managing installation of software packages. Even though OpenVPN installation on Fedora can only be done on the command line, it still is a very easy task. The installation makes use of the commands wget, rpm, and yum. wget: A command-line download manager suitable for ftp or http downloads. rpm: The Red Hat Package Manager is a software management system used by distributions like SuSE or Red Hat. It keeps track of changes and can solve dependencies between programs. yum: This provides a simple installation program for RPM-based software. To use yum, you have to adapt its configuration file as follows: Log in as administrator (root). Change to Fedora's configuration directory /etc. Save the old, probably original, configurations file yum.conf by renaming or moving it. You can use commands such as mv yum.conf yum.conf_fedora_org to accomplish this. The web site http://www.fedorafaq.org/ provides a suitable configuration file for yum. Download the file http://www.fedorafaq.org/samples/yum.conf using wget. The command-line syntax is: wget http://www.fedorafaq.org/samples/yum.conf At the same web site a sophisticated yum configuration is available for downloading. Install this as well: rpm -Uvh http://www.fedorafaq.org/yum The following excerpt shows the output of these five steps on the system: [root@fedora ~]# cd /etc [root@fedora etc]# mv yum.conf yum.conf.org [root@fedora etc]# wget http://www.fedorafaq.org/samples/yum.conf --11:33:25-- http://www.fedorafaq.org/samples/yum.conf => `yum.conf' Resolving www.fedorafaq.org... 70.84.209.18 Connecting to www.fedorafaq.org[70.84.209.18]:80... connected. HTTP request sent, awaiting response... 200 OK Length: 595 [text/plain] 100%[========================================================== ================================================>] 595 --.- -K/s 11:33:25 (405.20 KB/s) - `yum.conf' saved [595/595] [root@fedora etc]# rpm -Uvh http://www.fedorafaq.org/yum Retrieving http://www.fedorafaq.org/yum Preparing... ######################################### ## [100%] 1:yum-fedorafaq ######################################### ## [100%] [root@fedora etc]# The rest of the OpenVPN installation is very simple. Just enter yum install openvpn in your root shell. Now yum will start and give you a lot of output. We will have a short look at the things yum does. [root@fedora ~]#yum install openvpn Setting up Install Process Setting up repositories livna 100% |=========================| 951 B 00:00 updates-released 100% |=========================| 951 B 00:00 base 100% |=========================| 1.1 kB 00:00 extras 100% |=========================| 1.1 kB 00:00 Reading repository metadata in from local files primary.xml.gz 100% |=========================| 127 kB 00:00 livna : ################################################## 380/380 Added 380 new packages, deleted 0 old in 1.36 seconds primary.xml.gz 100% |=========================| 371 kB 00:00 updates-re: ################################################## 1053/1053 Added 0 new packages, deleted 13 old in 0.93 seconds yum has set up the installation process and integrated online repositories for the installation of software. This feature is the reason why Fedora does not need a URL source for installing OpenVPN. The repository metadata contains information about location, availability, and dependencies between packages. Resolving the dependencies is the next step. Parsing package install arguments Resolving Dependencies --> Populating transaction set with selected packages. Please wait. ---> Downloading header for openvpn to pack into transaction set. openvpn-2.0.9-1.fc5.i386. 100% |=========================| 18 kB 00:00 ---> Package openvpn.i386 0:2.0.9-1.fc5 set to be updated --> Running transaction check --> Processing Dependency: liblzo.so.1 for package: openvpn --> Restarting Dependency Resolution with new changes. --> Populating transaction set with selected packages. Please wait. ---> Downloading header for lzo to pack into transaction set. lzo-1.08-4.i386.rpm 100% |=========================| 3.2 kB 00:00 ---> Package lzo.i386 0:1.08-4 set to be updated --> Running transaction check Dependencies Resolved OpenVPN needs the LZO library for installation, and yum is about to resolve this dependency. As a next step, yum tests whether this library has unresolved dependencies. If this is not the case, we are presented with an overview of the packages to be installed. Confirm by entering y and press the Enter key. yum will start downloading the required packages. If the RPM process that yum is using to install the software packages encounters a missing encryption key, then confirm the import of this key from http://www.fedoraproject.org by entering y and pressing the Enter key. This GPG key is used to control the authenticity of the packages selected for installation. Key imported successfully Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing: lzo ######################### [1/2] Installing: openvpn ######################### [2/2] Installed: openvpn.i386 0:2.0.9-1.fc5 Dependency Installed: lzo.i386 0:1.08-4 Complete! [root@fedora etc]# That's all! yum has been downloaded, checked, and has installed OpenVPN and the LZO libraries.
Read more
  • 0
  • 0
  • 9773

article-image-installing-openvpn-linux-and-unix-systems-part-2
Packt
31 Dec 2009
7 min read
Save for later

Installing OpenVPN on Linux and Unix Systems: Part 2

Packt
31 Dec 2009
7 min read
Installing OpenVPN on Debian and Ubuntu Probably the easiest distribution on which to install OpenVPN is Debian and its derivates like Ubuntu. Just type apt-get install openvpn, answer two questions, and OpenVPN is installed and ready to be used. The Debian package management system is capable of solving all the issues that might occur during the installation. If your system is configured correctly, then the automatic installation will cover the following steps: The installation helper apt-get will find the software on the installation servers. The helper will then download the chosen package and unpack it to your local system. An interactive configuration script is executed, which configures your system and the newly installed software for later use with the parameters that you enter. The following code extract is the standard output of apt-get install openvpn on a Debian system. This output may vary depending on your previous software selection, and in many cases the LZO compression library will have to be installed. On some systems apt will install OpenSSL libraries, but in most cases, apt-get is able to solve all problems for you. debian01:~# apt-get install openvpnReading Package Lists... DoneBuilding Dependency Tree... DoneThe following NEW packages will be installed:openvpn0 upgraded, 1 newly installed, 0 to remove and 7 not upgraded.Need to get 293kB of archives.After unpacking 762kB of additional disk space will be used.Get:1 http://ftp.uni-erlangen.de testing/main openvpn 2.0.9 [293kB]Fetched 298kB in 1s (247kB/s)Preconfiguring packages ...Selecting previously deselected package openvpn.(Reading database ... 9727 files and directories currently installed.)Unpacking openvpn (from .../openvpn_2.0-9_i386.deb) ...Setting up openvpn (2.0-9) ...Restarting virtual private network daemon:.debian01:~# During this process, you will be prompted to answer the following two questions: You have to allow apt to create a TUN/TAP device for use by OpenVPN software. If you select No, your tunnels will not be created and your tunnel software won't work. The second question raises a security issue. OpenVPN software should be stopped during an update, so you have to select YES and hit return. You have to stop the old tunnel software when an update is running. All tunneling will be stopped, and your users will not be able to connect to your system during this time. From then on, all tunnels are created by the new OpenVPN software, including patches and bug fixes. This is the safe way to go. However, if you choose No, you risk that the old software and libraries are still running, even after the installation of new OpenVPN software. Bug fixes and patches of the new version may not apply to existing tunnels until they are started again. You may run into serious inconsistencies in your system, if you have several tunnels and they are running different versions of your software. Thus, it is safer to have a short time when users will not be able to connect. Installing Debian packages Software packages for Debian systems are provided in the so-called .deb file format. DEB files are usually stored in online repositories on FTP or web servers, and every Debian system holds a list of repositories that can be used for installation. You will find this list in /etc/apt/sources.list. The setup program base-config provides a menu-based configuration interface for apt. If you want to add source repositories to your Debian installation, type base-config and change to the menu configure apt. Select the country you live in and the repository of your choice. Select Ok. Now all the software packages of this server can automatically be installed on your system, simply by typing apt-get install <package>. A Debian package contains the software and information about it, such as name, version, description, contents, prerequisites, dependencies, and configuration scripts that are to be started after installation. Debian systems offer some very powerful programs with which you can control software installation very specifically. Listing all programs and options would go far beyond the scope of this article, but here is a short overview of some handy package management commands. Command Function apt-get remove <package> Removes the selected package from your system apt-get update Updates the list of packages available on the repositories listed in /etc/apt/sources.list apt-get upgrade Installs the latest available versions of all your installed software apt-get dist-upgrade Installs the latest available software related to your configuration dpkg-reconfigure Restarts/Starts the configuration script inside the package, which will bring up the menu-based dialogs in the same way as after installation apt-cache show <package> Prints detailed information about the software package dpkg -l <package> Prints information on the installed software package dpkg -L <package> Lists all files installed by the software package dpkg -i <file> Installs a local (.deb) file to your system dpkg -S <file> Prints information about the software package owning <file> apt-cache search <string> Searches apt database for packages containing <string> in their name and description These programs should solve all possible questions, issues, and problems concerning the installation of software on Debian systems. Just try these commands with the freshly installed OpenVPN package on your system. Type the command apt-cache show openvpn to receive information about the installed package. Using Aptitude to search and install packages Although the Debian command-line tools are very powerful, there are more programs that help you to retrieve and install software. Probably the most common software for this purpose is Aptitude. Type aptitude in a command line in order to start the menu-based installation interface. If Aptitude is not installed on your system, type apt-get install aptitude. If you prefer aptitude, you can use it at the command line in the same way as apt-get. Aptitude consists of a menu at the top of the screen, a list of packages, and a window showing details on the software selected in the package list. If you have console mouse support, you can click on menu entries. Click on the menu entry Search, or hit the F10 key and navigate through the Search menu. Select the entry Find. You will be prompted with a search mask. Enter openvpn. While you are typing, Aptitude is steadily updating the main window. Click on OK and have a look at the output. Aptitude will find the OpenVPN version that you had installed previously, and the entries in the menus Actions and Package help you to select and install software. Depending on the selection of repositories that you have added to your sources.list during installation, Aptitude can also help you to choose different versions of OpenVPN. OpenVPN—the files installed on Debian The following table gives an overview of the files that were installed by the Debian package management system. Full path and file Installed by OpenVPN Function /etc/openvpn Directory containing configuration files /etc/network/if-up.d/openvpn /etc/network/if-down.d /etc/network/if-down.d/openvpn Start/stop openvpn when the network goes up/down /etc/init.d/openvpn Start/stop script for services /sbin/openvpn The binary /usr/share/doc/openvpn Documentation files /usr/share/man/man8/openvpn.8.gz Manual page /usr/share/doc/openvpn/examples/ sample-config-files Example configuration files /usr/share/doc/openvpn/examples/ sample-keys Example keys /usr/share/doc/openvpn/examples/ easy-rsa easy-rsa-a collection of scripts useful for creating tunnels /usr/share/doc/openvpn/ changelog.Debian.gz /usr/share/doc/openvpn/changelog.gz   Version history /usr/share/openvpn/verify-cn verify-cn function (revoke command) /usr/lib/openvpn/ openvpn-auth-pam.so /usr/lib/openvpn/ openvpn-down-root.so Libraries for PAM-Authentication and chroot mode  
Read more
  • 0
  • 0
  • 3080
Modal Close icon
Modal Close icon