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

How-To Tutorials

7018 Articles
article-image-activating-buddypress-default-theme-and-setting-and-configuring-buddypress
Packt
30 Jul 2010
4 min read
Save for later

Activating the BuddyPress Default Theme and Setting up and Configuring BuddyPress

Packt
30 Jul 2010
4 min read
(For more resources on WordPress, see here.) After installing and activating BuddyPress, an alert will appear at the top of your screen to tell you that the functionality offered by BuddyPress isn't available on your website just yet. For these features to be made available to your members, you will need to install a BuddyPress-compatible theme.   Activating this theme is a two step process. First, navigate to Appearance | Themes and then click Activate for the BuddyPress Default theme. Next, click on SuperAdmin | Themes. Tick the radio button labeled Yes for the BuddyPress Default theme and then click Apply Changes. Now the BuddyPress Default theme will be in use on your site and available for usage by your users. Setting up and configuring BuddyPress After activating the plugin, you might have noticed that a new BuddyPress menu appeared. Click on BuddyPress | General Settings to access the BuddyPress Settings screen. BuddyPress Settings There are only two settings on this screen that you need to concern yourself with; the rest can be left at their defaults settings. The first option that you need to alter is located at the top of the screen and is labeled Base profile group name. As you can see, this is currently set to Base. This text appears in a couple of places. First, when your users go to My Account | Profile | Edit Profile, they will see Editing 'Base' Profile Group.   The second place that this text can be found is on the BuddyPress Profile Field Setup screen where it's used as the name of the default field group.   In both instances, something less enigmatic would be beneficial. Think of a descriptive label that would be useful in both situations and then enter it into the Base profile group name textbox.   You will find the other setting that you need to configure located at the bottom of your screen, so scroll down until you see the Default User Avatar. In this area, select the type of avatar that you would like to display for users without a custom avatar and then click Save Settings. Component Setup Now, click on BuddyPress | Component Setup to be taken to the BuddyPress Component Setup screen. By default, all of the components found on this screen are enabled. How you choose to configure the majority of these settings will depend upon your preferences and the features that you would like to make available on your website. It should be noted, however, that both the bbPress Forums and Groups components should remain enabled if you plan on integrating bbPress into your community portal. Also, the Extended Profiles component should be left set to Enabled, so that your members can have more detailed profiles attached to their accounts. Profile Field Setup Skip the Forums Setup screen for now, and instead click on Profile Field Setup. On this screen, there are three actions that you can take. You can add additional field groups, add new fields, and then choose the location for each of these fields within their group. At present, your installation of BuddyPress has one default field placed within one default field group which now bears the name that it was given when you changed it from Base on the BuddyPress Settings screen. Any fields located in this default field group will appear on the signup screen under the heading of Profile Details.   This field group also appears on the screen that your users see when they go to edit their profile.   Any additional field groups that you add will only be visible to users when they wish to edit their profile. As things stand, your users will have a profile that consists of nothing more than their name. Since that doesn't make for much of a profile you need to add some additional field groups and fields. With the addition of these new groups and fields, it will be possible for your members to build a robust profile page.
Read more
  • 0
  • 0
  • 2137

article-image-setting-glassfish-jms-and-working-message-queues
Packt
30 Jul 2010
4 min read
Save for later

Setting up GlassFish for JMS and Working with Message Queues

Packt
30 Jul 2010
4 min read
(For more resources on Java, see here.) Setting up GlassFish for JMS Before we start writing code to take advantage of the JMS API, we need to configure some GlassFish resources. Specifically, we need to set up a JMS connection factory, a message queue, and a message topic. Setting up a JMS connection factory The easiest way to set up a JMS connection factory is via GlassFish's web console. The web console can be accessed by starting our domain, by entering the following command in the command line: asadmin start-domain domain1 Then point the browser to http://localhost:4848 and log in: A connection factory can be added by expanding the Resources node in the tree at the left-hand side of the web console, expanding the JMS Resources node and clicking on the Connection Factories node, then clicking on the New... button in the main area of the web console. For our purposes, we can take most of the defaults. The only thing we need to do is enter a Pool Name and pick a Resource Type for our connection factory. It is always a good idea to use a Pool Name starting with "jms/" when picking a name for JMS resources. This way JMS resources can be easily identified when browsing a JNDI tree. In the text field labeled Pool Name, enter jms/GlassFishBookConnectionFactory. Our code examples later in this article will use this JNDI name to obtain a reference to this connection factory. The Resource Type drop-down menu has three options: javax.jms.TopicConnectionFactory - used to create a connection factory that creates JMS topics for JMS clients using the pub/sub messaging domain javax.jms.QueueConnectionFactory - used to create a connection factory that creates JMS queues for JMS clients using the PTP messaging domain javax.jms.ConnectionFactory - used to create a connection factory that creates either JMS topics or JMS queues For our example, we will select javax.jms.ConnectionFactory. This way we can use the same connection factory for all our examples, those using the PTP messaging domain and those using the pub/sub messaging domain. After entering the Pool Name for our connection factory, selecting a connection factory type, and optionally entering a description for our connection factory, we must click on the OK button for the changes to take effect. We should then see our newly created connection factory listed in the main area of the GlassFish web console. Setting up a JMS message queue A JMS message queue can be added by expanding the Resources node in the tree at the left-hand side of the web console, expanding the JMS Resources node and clicking on the Destination Resources node, then clicking on the New... button in the main area of the web console. In our example, the JNDI name of the message queue is jms/GlassFishBookQueue. The resource type for message queues must be javax.jms.Queue. Additionally, a Physical Destination Name must be entered. In this example, we use GlassFishBookQueue as the value for this field. After clicking on the New... button, entering the appropriate information for our message queue, and clicking on the OK button, we should see the newly created queue: Setting up a JMS message topic Setting up a JMS message topic in GlassFish is very similar to setting up a message queue. In the GlassFish web console, expand the Resources node in the tree at the left hand side, then expand the JMS Resouces node and click on the Destination Resources node, then click on the New... button in the main area of the web console. Our examples will use a JNDI Name of jms/GlassFishBookTopic. As this is a message topic, Resource Type must be javax.jms.Topic. The Description field is optional. The Physical Destination Name property is required. For our example, we will use GlassFishBookTopic as the value for this property. After clicking on the OK button, we can see our newly created message topic: Now that we have set up a connection factory, a message queue, and a message topic, we are ready to start writing code using the JMS API.
Read more
  • 0
  • 0
  • 10948

article-image-building-job-board-website-using-jobpress
Packt
30 Jul 2010
9 min read
Save for later

Building a Job Board Website using JobPress

Packt
30 Jul 2010
9 min read
(For more resources on WordPress, see here.) With so many types of jobs out there, the possibilities for niche job boards are almost endless. Drawing in traffic shouldn't prove to be too difficult either because, after being populated with niche-specific job listings, your job board will be filled with a wide variety of targeted keywords. Once these job seekers arrive at your niche job board they should transition into repeat traffic since they will be able to easily peruse job listings that are appropriate to the skills that they posses. That will remove much of the hassle that job seekers suffer as they seek employment. FoxNews and Smashing Magazine are two users of the JobPress theme who have zeroed in on a niche for their job boards. FoxNews only covers positions available within their own company while Smashing Magazine provides job listings primarily targeted toward those seeking design and programming-related jobs. So, as you can see, opting to focus on a niche will put you and your job board in good company.         The previous screenshots of the FoxNews and Smashing Magazine job boards will give you some idea of just what you can do with this theme. As you can see, JobPress can be integrated into the design of an existing website so that the two blend together nicely. In this article, you will learn how to: Build a dedicated job board website Make the JobPress sidebar widget-ready Run JobPress alongside an existing web site Once this project is complete, you will have succeeded in creating a site that's similar to the one shown in the following screenshot: Introducing JobPress JobPress, which can be found at http://www.dailywp.com/jobpress-wordpresstheme/, took the inspiration for its features from several of the job boards already in existence on the Internet. As you would expect, the theme offers those building a job board site the ability to edit and customize various features using a theme-related settings screen. This one screen houses all of the settings specific to this theme, so the customization of JobPress and its features can be completed in record time. If you're looking to earn a profit from your job board, then you have two options. You can either include advertisements in their various forms or you can charge a fee in order to post a job listing. If you would like to go with the latter option, then you can simply enter your PayPal information into the appropriate settings area and JobPress and PayPal will take care of the rest. JobPress also includes a feature whereby payment is verified between PayPal and JobPress, so that you can always be sure that the job listings that appear on your website have, in fact, been paid for. JobPress makes the job hunt easier for your visitors by allowing them to use the FREELANCE, FULL TIME, and PART TIME tags to sort listings. These sort options are available on both the front page and within categories to make locating a suitable job as easy as possible. If job seekers want to search for a specific job, instead of browsing, then they can do that too by using the search box provided by JobPress. JobPress also includes a feature that will alert job seekers when a listing has been online for more than 30 days. That way they will be able to see which listings are fresh and which ones are likely to have already been filled by another applicant. Running a job board isn't just about pleasing the job seekers who come to your site looking for listings. It's also about catering to the desires of those who will be placing ads. After all, without them your job board won't contain any job listings which means that there will be nothing there to draw in visitors. The developer behind JobPress took that into consideration when designing this theme by making the job listing submission process virtually hassle-free. Setting up and configuring JobPress After uploading and activating the JobPress theme, a new JobPress Settings link will appear. From this screen, all of your JobPress settings can be configured. So, to begin customizing JobPress to your liking, click on JobPress Settings. The Publishing & Payment Settings area is the first section that you will need to concentrate on during this configuration process. The Auto Publish? setting allows you to publish job listings automatically or manually. This setting is currently set to On, but you may switch it to Off if you prefer to have more control over the ads that appear on your website. The Paid Submission? setting is currently enabled. If you would like to charge a fee for placing a job listing, then this setting shouldn't be changed. Otherwise, change it to Disable to offer job listing placements for free. If you've decided to offer job listing placements for free, then proceed to the Custom Information settings area. If, you've instead opted to charge for the placement of job listings, then you will need to configure the remaining settings found in the Publishing & Payment Settings area. First, enter the email address associated with your PayPal account into the PayPal Mail textbox. In the Submission Price textbox, enter the amount that you would like to charge for standard ad placements. The last setting in this area is the Currency drop-down menu. Here you need to choose the currency associated with your area of the world. The Custom Information section of this settings screen is next and Renew Jobs is the first option that you will see. This feature is currently set to Enabled which means that job posters will be able to renew their listings if they would like to do so. This setting can be left at its default or you can, instead, set it to Disable if you would rather not provide a renewal option. It's best, however, for ease of use, if this setting remains enabled. The Apply Online option is also set to Enabled and it's probably best if this is left as is so that your job board offers the highest level of convenience to job seekers. With this setting in place visitors to your job board will be able to apply online for the jobs that they're interested in. The Sociable setting is also currently enabled, which is ideal since this will provide your visitors with a way to share a job listing that they see on your site with someone who might be interested in applying. Featured Job is next and, like all of the proceeding settings, it's also enabled. If you want to provide job posters with the option of upgrading from a standard listing to one that's featured, then this setting should remain enabled. If, however, you would rather not offer featured job listings on your website, then change this setting to Disable. If you opted to leave this setting enabled, then enter the price that you plan to charge for featured job listings into the Submission Featured Job Price textbox. Now, in the Items Per Page textbox, enter the number of job listings that you would like to appear on a single page. In the Success Message text area you will find a pre-written message that's displayed on the confirmation page when a job listing is submitted. It's best if you rewrite this message to correct grammar issues and to add any additional information that you would like to provide. Success Mail is next and this setting contains a few different options that must be addressed. First, you must choose whether you would like to leave this feature set to Enabled or, instead, set it to Disable. If you would like to use this feature, then you will first need to heed the advice included below the drop-down menu which advises you to contact your web host before enabling this setting. When you contact your web host you will need to ask them to if the mail() function is activated because the Success Mail feature won't work if that function isn't enabled. If the mail() function isn't enabled, then you should next ask your web host to activate it on your account. If they're unable to do so, then you will have no choice other than to set Success Mail to Disable. If you would like to use this feature, then you will first need to heed the advice included below the drop-down menu which advises you to contact your web host before enabling this setting. When you contact your web host you will need to ask them to if the mail() function is activated because the Success Mail feature won't work if that function isn't enabled. If the mail() function isn't enabled, then you should next ask your web host to activate it on your account. If they're unable to do so, then you will have no choice other than to set Success Mail to Disable. If it was possible for your web host to enable the mail() function, and you set Success Mail to Enabled, you must next deal with the Subject textbox. The default text provided in this textbox is certainly sufficient, but you might want to add the name of your job board to the subject line. That way recipients will be able to easily identify that the message that they're receiving isn't spam. The message within the Content text area is fine as is, but you may certainly rewrite it if you like. If you do decide to create your own message, then be sure to include the tags provided by JobPress for usage in this area so that this unique information can be populated before the message is sent. The From textbox that follows should be left at its default. Now, click Save to finalize your changes. Companies submitting job listings to your site will have the ability to include their company logo along with their submission. This feature won't function properly, unless you change the permissions on the upload folder, which can be found inside the wp-content directory. So, navigate to the upload folder and then CHMOD it to 777.
Read more
  • 0
  • 0
  • 2188

article-image-microsoft-visual-studio-2010-improving-class-quality-cohesion
Packt
29 Jul 2010
12 min read
Save for later

Microsoft Visual Studio 2010: Improving Class Quality with Cohesion

Packt
29 Jul 2010
12 min read
(For more resources on Microsoft products, see here.) Larry Constantine is attributed with the creation of systematic measurement of software quality. In the mid-to-late seventies, Larry Constantine (and Ed Yourdon) attributed several things to the quality of software code. Under the umbrella of structured design, among those attributes of quality software code were cohesion and coupling. At the time they associated quality with generality, flexibility, and reliability. In this article series, we're going to concentrate on generality and flexibility and how cohesion and coupling can be applied to increase code quality. Larry Constantine:http://en.wikipedia.org/wiki/Larry_Constantine Cohesion applies to many different disciplines. Cohesion in physics relates to the force that keeps molecules integrated and united and that makes the molecule what it is. A highly cohesive molecule is one that tends to remain autonomous and not adhere to or blend with other molecules. In geology, cohesion is the strength of substances to resist being broken apart. In linguistics, it's the degree to which text is related. Text whose content relates to the same subject is cohesive. Cohesion in software is very similar to cohesion elsewhere. A cohesive block of code is a block of code that relates well together and has the ability to remain together as a unit. Object-oriented programming brings distinct cohesive abilities. All programming languages have certain cohesive abilities, such as their ability to group code in modules, source files, functions, and so on. A programming language's ability to define physical boundaries enables cohesiveness. A module, for example, defines a specific boundary for which some content is retained and other content is repelled. Code from one module can use code from another module, but only in specific and defined ways—usually independent of language syntax. All code within a module has innate cohesion: their relation amongst themselves as being contained within the module. Any rule, principle, guideline, or practice needs to be implemented thoughtfully. This text isn't a manual on how you must perform your refactoring; it's a description of several types of refactorings and their impetus. By the same token, this text doesn't set out to prove the benefits of any particular rule, principle, guideline, or practice. "Mileage may vary" and incorrect usage will often negate most, if not all, benefits. I'll leave it as an exercise for the reader to find the research that "proves" the benefits of any particular rule, principle, guideline, or practice. This text assumes the generally accepted benefits of various principles and practices, including cohesion, as an indicator of quality. If you decide that the benefits aren't outweighing the costs, it's up to you to decide not to implement that principle. Class cohesion Object-orientation brings extra cohesive abilities to the programmer. The programmer has the ability to relate code together within a class. Other code can use the code within a class, but only through its defined boundaries (the class's methods and properties). In object-oriented design, cohesion is generally much more than simply code contained within a class. Object-oriented cohesiveness goes beyond the physical relation of code within a class and deals with the relation of meaning of the code within a class. Object-oriented language syntax allows the programmer to freely relate code to other code through a class definition, but this doesn't mean that code is cohesive. For example, let's revisit our Invoice class so far. /// <summary>/// Invoice class to encapsulate invoice line items/// and drawing/// </summary>public class Invoice{ private IInvoiceGrandTotalStrategy invoiceGrandTotalStrategy; public Invoice(IEnumerable<InvoiceLineItem> invoiceLineItems, IInvoiceGrandTotalStrategy invoiceGrandTotalStrategy) { InvoiceLineItems = new List<InvoiceLineItem>(invoiceLineItems); this.invoiceGrandTotalStrategy = invoiceGrandTotalStrategy; } private List<InvoiceLineItem> InvoiceLineItems { get; set; } public void GenerateReadableInvoice(Graphics graphics) { graphics.DrawString(HeaderText, HeaderFont, HeaderBrush, HeaderLocation); float invoiceSubTotal = 0; PointF currentLineItemLocation = LineItemLocation; foreach (InvoiceLineItem invoiceLineItem in InvoiceLineItems) { float lineItemSubTotal = CalculateLineItemSubTotal(invoiceLineItem); graphics.DrawString(invoiceLineItem.Description, InvoiceBodyFont, InvoiceBodyBrush, currentLineItemLocation); currentLineItemLocation.Y += InvoiceBodyFont.GetHeight(graphics); invoiceSubTotal += lineItemSubTotal; } float invoiceTotalTax = CalculateInvoiceTotalTax(invoiceSubTotal); float invoiceGrandTotal = invoiceGrandTotalStrategy.CalculateGrandTotal( invoiceSubTotal, invoiceTotalTax); CalculateInvoiceGrandTotal(invoiceSubTotal, invoiceTotalTax); graphics.DrawString(String.Format( "Invoice SubTotal: {0}", invoiceGrandTotal - invoiceTotalTax), InvoiceBodyFont, InvoiceBodyBrush, InvoiceSubTotalLocation); graphics.DrawString(String.Format("Total Tax: {0}", invoiceTotalTax), InvoiceBodyFont, InvoiceBodyBrush, InvoiceTaxLocation); graphics.DrawString(String.Format( "Invoice Grand Total: {0}", invoiceGrandTotal), InvoiceBodyFont, InvoiceBodyBrush, InvoiceGrandTotalLocation); graphics.DrawString(FooterText, FooterFont, FooterBrush, FooterLocation); } public static float CalculateInvoiceGrandTotal( float invoiceSubTotal, float invoiceTotalTax) { float invoiceGrandTotal = invoiceTotalTax + invoiceSubTotal; return invoiceGrandTotal; } public float CalculateInvoiceTotalTax( float invoiceSubTotal) { float invoiceTotalTax = (float)((Decimal)invoiceSubTotal * (Decimal)TaxRate); return invoiceTotalTax; } public static float CalculateLineItemSubTotal( InvoiceLineItem invoiceLineItem) { float lineItemSubTotal = (float)((decimal)(invoiceLineItem.Price - invoiceLineItem.Discount) * (decimal)invoiceLineItem.Quantity); return lineItemSubTotal; } public string HeaderText { get; set; } public Font HeaderFont { get; set; } public Brush HeaderBrush { get; set; } public RectangleF HeaderLocation { get; set; } public string FooterText { get; set; } public Font FooterFont { get; set; } public Brush FooterBrush { get; set; } public RectangleF FooterLocation { get; set; } public float TaxRate { get; set; } public Font InvoiceBodyFont { get; set; } public Brush InvoiceBodyBrush { get; set; } public Point LineItemLocation { get; set; } public RectangleF InvoiceSubTotalLocation { get; set; } public RectangleF InvoiceTaxLocation { get; set; } public RectangleF InvoiceGrandTotalLocation { get; set; }} We have an operational Invoice class. It does some things, and they work. But, our Invoice class isn't very cohesive. The Invoice class has distinct groups of fields. Some are for the state of an invoice and some are for generating a readable invoice. Methods that deal with the behavior and attributes of an invoice don't use the fields that deal with generating a readable invoice. Our Invoice class is implementing two distinct tasks: managing invoice state and generating a readable invoice. The data required to generate a readable invoice (over and above the data shown on an invoice) isn't used by Invoice when not generating a readable invoice. Our Invoice class can be said to have multiple responsibilities: the responsibility of managing state and the responsibility of generating a readable invoice. What makes an invoice an invoice may be fairly stable; we may occasionally need to add, remove, or change fields that store data contained in an invoice. But, the act of displaying a readable invoice may be less stable: it may change quite frequently. Worse still, the act of displaying a readable invoice may depend on the platform it is running on. The Single Responsibility Principle In terms of focusing refactoring efforts towards cohesiveness of a class, the Single Responsibility Principle (SRP) gives us guidance on what a particular class should or should not do. The Single Responsibility Principle states that "there should never be more than one reason for a class to change". In the case of our invoice class there's a couple of reasons why we'd need to change the class: The way an invoice is displayed needs to change. The data that is contained in an invoice needs to change. The stability of each responsibility shouldn't need to depend on the other. That is, any change to the Invoice class affects stability of the whole class. If I often need to change the way an invoice renders a displayable invoice, all of Invoice is instable—including its responsibility to the data an invoice contains. The Single Responsibility Principle's focus is fairly narrow: class responsibility. A novice may simply accept that scope and use it only to focus cohesion efforts at the class level. The fact is that the Single Responsibility Principle is applicable at almost all levels of software design, including method, namespace, module/assembly, and process; that is, a method could implement too much responsibility, the types within an assembly or namespace could have unrelated responsibilities, and the responsibilities of a given process might not be focused effectively. Simply saying "single responsibility" or detailing that something has too many responsibilities is simple. But the actual act of defining what a responsibility is can be very subjective and subtle. Refactoring towards Single Responsibility can take some time and some work to get right. Let's see how we can improve quality through better cohesion and the principle of single responsibility. Refactoring classes with low-cohesion Clearly single responsibility (and the heading of this section) suggests that we should refactor Invoiceinto multiple classes. But, how do we do that given our current scenario? The designer of this class has obviously thought that the functionality of Invoice included rendering a readable invoice, so how do we make a clean separation? Fortunately, the lack of cohesiveness gives us our separation points. What makes an invoice an invoice doesn't include those fields that deal solely with rendering a readable invoice. Fields like HeaderFont, HeaderBrush, HeaderText, HeaderLocation, FooterFont, FooterBrush, FooterText, FooterLocation, InvoiceBodyFont, InvoiceBodyBrush, LineItemLocation, InvoiceBustTotalLocation, InvoiceTaxLocation, and InvoiceGrandTotalLocation all deal with just the rendering responsibility. The Invoice class is modeling a real-world invoice. When you hold an invoice in your hand or view it on the screen, it's already rendered. In the real-world we'd never think that a responsibility of rendering an invoice would be a responsibility of the invoice itself. We know we want to retain our original Invoice class and we want to move the rendering responsibility to a new class. This new class will encapsulate the responsibility of rendering an invoice. Since this new class will take an Invoice object and help another class produce something useful, we can consider this an invoice rendering service. In order to refactor our existing Invoice class to a new Invoice rendering service, we start with a new InvoiceRenderingService class and move the HeaderFont, HeaderBrush, HeaderText, HeaderLocation, FooterFont, FooterBrush, FooterText, FooterLocation, InvoiceBodyFont, InvoiceBodyBrush, LineItemLocation, InvoiceBustTotalLocation, InvoiceTaxLocation, and InvoiceGrandTotalLocation fields to the InvoiceRenderingService. Next, we move the GenerateReadableInvoice method to the InvoiceRenderingService. At this point, we basically have a functional class, but since the InvoiceRenderingService method was on the Invoice classes, the other properties that the GenerateReadableInvoice uses need an Invoice object reference—effectively changing it from "this" to a parameter to the GenerateReadableInvoice method. Since the original Invoice class was never expected to be used externally like this, we need to add a CalculateGrandTotal method that delegates to the invoiceGrandTotalStrategy object. The result is something like the following: /// <summary>/// Encapsulates a service to render an invoice/// to a Graphics device./// </summary>public class InvoiceRenderingService{public void GenerateReadableInvoice(Invoice invoice, Graphics graphics){ graphics.DrawString(HeaderText, HeaderFont, HeaderBrush, HeaderLocation); float invoiceSubTotal = 0; PointF currentLineItemLocation = LineItemLocation; foreach (InvoiceLineItem invoiceLineItem in invoice.InvoiceLineItems) { float lineItemSubTotal = Invoice.CalculateLineItemSubTotal( invoiceLineItem); graphics.DrawString(invoiceLineItem.Description, InvoiceBodyFont, InvoiceBodyBrush, currentLineItemLocation); currentLineItemLocation.Y += InvoiceBodyFont.GetHeight(graphics); invoiceSubTotal += lineItemSubTotal; } float invoiceTotalTax = invoice.CalculateInvoiceTotalTax( invoiceSubTotal); float invoiceGrandTotal = invoice.CalculateGrandTotal( invoiceSubTotal, invoiceTotalTax); Invoice.CalculateInvoiceGrandTotal(invoiceSubTotal, invoiceTotalTax); graphics.DrawString(String.Format( "Invoice SubTotal: {0}", invoiceGrandTotal - invoiceTotalTax), InvoiceBodyFont, InvoiceBodyBrush, InvoiceSubTotalLocation); graphics.DrawString(String.Format("Total Tax: {0}", invoiceTotalTax), InvoiceBodyFont, InvoiceBodyBrush, InvoiceTaxLocation); graphics.DrawString(String.Format( "Invoice Grand Total: {0}", invoiceGrandTotal), InvoiceBodyFont, InvoiceBodyBrush, InvoiceGrandTotalLocation); graphics.DrawString(FooterText, FooterFont, FooterBrush, FooterLocation); } public string HeaderText { get; set; } public Font HeaderFont { get; set; } public Brush HeaderBrush { get; set; } public RectangleF HeaderLocation { get; set; } public string FooterText { get; set; } public Font FooterFont { get; set; } public Brush FooterBrush { get; set; } public RectangleF FooterLocation { get; set; } public Font InvoiceBodyFont { get; set; } public Brush InvoiceBodyBrush { get; set; } public Point LineItemLocation { get; set; } public RectangleF InvoiceSubTotalLocation { get; set; } public RectangleF InvoiceTaxLocation { get; set; } public RectangleF InvoiceGrandTotalLocation { get; set; }} Alternatively, the whole use of invoiceGrandTotalStrategy can be moved into the InvoiceRenderingService—which is a better design decision. Detecting classes with low-cohesion So, we've seen a fairly simple example of making a not-so-cohesive class into two more-cohesive classes; but, one of the tricky parts of refactoring away classes with low cohesion is finding them. How do we find classes with low-cohesion? Fortunately, many people have put time and effort over the years into defining what it means for a class to be cohesive. There have been various metrics researched and created over the years to define cohesion in classes. The most popular metric is Lack of Cohesion of Methods (LCOM) . Lack of Cohesion of Methods measures the degree to which all methods use all fields. The more segregated field usage is amongst methods of a class, the higher the Lack of Cohesion of Methods metric of the class will be. Lack of Cohesion of Methods is a measure of the entire class, so it won't point out where the class is not cohesive or indicate where the responsibilities can be separated. Lack of Cohesion of Methods is a measurement of the degree to which fields are used by all methods of a class. Perfection as defined by Lack of Cohesion of Methods is that every method uses every field in the class. Clearly not every class will do this (and arguably this will hardly ever happen); so, Lack of Cohesion of Methods is a metric, as most metrics are, that requires analysis and thought before attempting to act upon its value. LCOM is a value between 0 and 1, inclusive. A measure of 0 means every method uses every field. The higher the value, the less cohesive the class; the lower the value, the more cohesive the class. A typical acceptable range is 0 to 0.8. But, there's no hard-and-fast definition of specific value that represents cohesive; just because, for example, a class has an LCOM value of 0.9, that doesn't mean it can or should be broken up into multiple classes. Lack of Cohesion of Methods values should be used as a method of prioritizing cohesion refactoring work by focusing on classes with higher LCOM values before other classes (with lower LCOM values). In the case of our Invoice class, it's apparent that its LCOM value does mean it can be split into multiple classes as we detailed in the previous section.
Read more
  • 0
  • 0
  • 1526

article-image-ensuring-quality-unit-testing-microsoft-visual-studio-2010
Packt
29 Jul 2010
12 min read
Save for later

Ensuring Quality for Unit Testing with Microsoft Visual Studio 2010

Packt
29 Jul 2010
12 min read
(For more resources on Microsoft products, see here.) Change is not always good Any change to existing code means it has the potential to change the external behavior of the system. When we refactor code, we explicitly intend not to change the external behavior of system. But how do we perform our refactorings while being reasonably comfortable that we haven't changed external behavior? The first step to validating that external behavior hasn't been affected is to define the criteria by which we can validate that the external behavior hasn't changed. Automated testing Every developer does unit testing. Some developers write a bit of test code, maybe an independent project that uses the code to verify it in some way then promptly forgets about the project. Or even worse, they throw away that project. For the purposes of this text, when I use the term "testing", I mean "automated testing". Test automation is the practice of using a testing framework to facilitate and execute tests. A test automation framework promotes the automatic execution of multiple tests. Generally these frameworks include some sort of Graphical User Interface that helps manage tests and their execution. Passing tests are "Green" and failing tests are "Red", which is where the "Red, Green, Refactor" mantra comes from. Unit tests If we're refactoring, there's a chance that what we want to refactor isn't currently under test. This means that if we do perform refactoring on the code, we'll have to manually test the system through the established user interfaces to verify that the code works. Realistically, this doesn't verify the code; this verifies that the external behavior hasn't changed. There could very well be a hidden problem in the code that won't manifest itself until the external behavior has been modified—distancing detection of the defect from when it was created. Our goal is to not affect external behavior when refactoring, so verification through the graphical user interface doesn't fully verify our changes and is time consuming and more prone to human error. What we really want to do is unit test the code. The term "unit test" has become overloaded over the years. MSDN describes unit testing as taking: ... the smallest piece of testable software in the application, [isolating] from the remainder of the code, and [determining] whether it behaves exactly as [expected]. This smallest piece of software is generally at the method level—unit testing is effectively about ensuring each method behaves as expected. Originally, it meant to test an individual unit of code. "Unit test" has evolved to mean any sort of code-based automated test, tests that developers write and execute within the development process. With various available frameworks, the process of testing the graphical user interface can also be automated in a code-based test, but we won't focus on that. It's not unusual for some software projects to have hundreds and thousands of individual unit tests. Given the granularity of some of the tests, it's also not unusual for the lines of code in the unit tests to outnumber the actual production code. This is expected. At the lowest level, we want to perform true "unit-testing", we want to test individual units of code, independently, to verify that unit of code functions as expected—especially in the presence of refactoring. To independently test these units of code we often have to separate them from their dependant code. For example, if I want to verify the business logic to uniquely generate an entity ID, there's no real need for me to access the database to verify that code. That code to generate a unique ID may depend on a collection of IDs to fully verify the algorithm to generate a unique ID—but that collection of IDs, for the purposes of verification, doesn't need to come from a database. So, we want to separate out use of some dependencies like the database from some of our tests. Techniques for loosely-coupled design like Dependency Inversion and Dependency Injection allow for a composable design. This composable design aids in the flexibility and agility of our software system, but it also aids in unit testing. Other testing Useful and thorough information about all types of testing could easily reach enough information to take up several tomes. We're focusing on the developer task of refactoring, so we're limiting our coverage of testing to absolute essential developer testing: unit testing. The fact that we're focusing on unit tests with regard to refactoring doesn't mean that other types of testing is neither useful nor needed. The fact that developers are performing unit tests doesn't preclude that they also need to perform a certain level of integration testing and the QA personnel are performing other levels of integration testing, user interface testing, user acceptance testing, system testing, and so on. Integration testing is combining distinct modules in the system to verify that they interoperate exactly as expected. User interface testing is testing that the user interface is behaving exactly as expected. User acceptance testing is verifying that specific user requirements are being met—which could involve unit testing, integration testing, user interface testing, verifying non-functional requirements, and so on. Mocking Mocking is a general term that usually refers the substitution of Test Doubles for dependencies within a system under test that aren't the focus of the test. "Mocking" generally encompasses all types of test doubles, not just Mock test doubles. Test Double is any object that takes the place of a production object for testing purposes.Mock is a type of Test Double that stands in for a production object whose behavior or attributes are directly used within the code under test and within the verification. Test Doubles allow an automated test to gather the criteria by which the code is verified. Test Doubles allow isolation of the code under test. There are several different types of Test Doubles: Mock, Dummy, Stub, Fake, and Spy. Dummy is a type of Test Double that is only passed around within the test but not directly used by the test. "null" is an example of a dummy—use of "null" satisfies the code, but may not be necessary for verification. Stub is a type of Test Double that provides inputs to the test and may accept inputs from the test but does not use them. The inputs a Stub provides to the test are generally "canned". Fake is a type of Test Double that is used to substitute a production component for a test component. A Fake generally provides an alternate implementation of that production component that isn't suitable for production but useful for verification. Fakes are generally used for components with heavy integration dependencies that would otherwise make the test slow or heavily reliant on configuration. Spy is a type of Test Double that effectively records the actions performed on it. The recorded actions can then be used for verification. This is often used in behavioral-based—rather than state-based—testing. Test doubles can be created manually, or they can be created automatically through the use of mocking frameworks. Frameworks like Rhino Mocks provide the ability to automatically create test doubles. Mocking framework generally rely on a loosely-coupled design so that the generated test doubles can be substituted for other objects based upon an interface. Let's look at an example of writing a unit test in involving mocking. If we return to one of our decoupling examples—InvoiceRepository—we can now test the internals of InvoiceRepository without testing our Data Access Layer (DAL). We would start by creating a test for the InvoiceRepository.Load method: [TestClass()]public class InvoiceRepositoryTest{[TestMethod()]public void LoadTest(){ DateTime expectedDate = DateTime.Now; IDataAccess dataAccess = new InvoiceRepositoryDataAccessStub(expectedDate); InvoiceRepository target = new InvoiceRepository(dataAccess); Guid invoiceId = Guid.NewGuid(); Invoice actualInvoice = target.Load(invoiceId); Assert.AreEqual(expectedDate, actualInvoice.Date); Assert.AreEqual(invoiceId, actualInvoice.Id); Assert.AreEqual("Test", actualInvoice.Title); Assert.AreEqual(InvoiceStatus.Posted, actualInvoice.Status); Assert.AreEqual(1, actualInvoice.LineItems.Count()); InvoiceLineItem actualLineItem = actualInvoice.LineItems.First(); Assert.AreEqual("Description", actualLineItem.Description); Assert.AreEqual(1F, actualLineItem.Discount); Assert.AreEqual(2F, actualLineItem.Price); Assert.AreEqual(3F, actualLineItem.Quantity);}} Here, we're creating an instance of our repository passing it a Stub IDataAccess class. We then invoke the Load method and verify the various attributes of the resulting Invoice object. We, of course, don't have a class named InvoiceRepositoryDataAccesStub, so we'll have to create one. This class, for the purposes of this test, will look like this. class InvoiceRepositoryDataAccesStub : IDataAccess{ private DateTime constantDate; public InvoiceRepositoryDataAccesStub(DateTime date){ constantDate = date;} public System.Data.DataSet LoadInvoice(Guid invoiceId){ DataSet invoiceDataSet = new DataSet("Invoice"); DataTable invoiceTable = invoiceDataSet.Tables.Add("Invoices"); DataColumn column = new DataColumn("Id", typeof(Guid)); invoiceTable.Columns.Add(column); column = new DataColumn("Date", typeof(DateTime)); invoiceTable.Columns.Add(column); column = new DataColumn("Title", typeof(String)); invoiceTable.Columns.Add(column); column = new DataColumn("Status", typeof(int)); invoiceTable.Columns.Add(column); DataRow invoiceRow = invoiceTable.NewRow(); invoiceRow["Id"] = invoiceId; invoiceRow["Date"] = constantDate; invoiceRow["Status"] = InvoiceStatus.Posted; invoiceRow["Title"] = "Test"; invoiceTable.Rows.Add(invoiceRow); return invoiceDataSet;}public System.Data.DataSet LoadInvoiceLineItems(Guid invoiceId){ DataSet lineItemDataSet = new DataSet("LineItem"); DataTable lineItemTable = lineItemDataSet.Tables.Add("LineItems"); DataColumn column =new DataColumn("InvoiceId", typeof(Guid)); lineItemTable.Columns.Add(column); column = new DataColumn("Price", typeof(Decimal)); lineItemTable.Columns.Add(column); column = new DataColumn("Quantity", typeof(int)); lineItemTable.Columns.Add(column); column = new DataColumn("Discount", typeof(double)); lineItemTable.Columns.Add(column); column = new DataColumn("Description", typeof(String)); lineItemTable.Columns.Add(column); column = new DataColumn("TaxRate1", typeof(String)); lineItemTable.Columns.Add(column); column = new DataColumn("TaxRate2", typeof(String)); lineItemTable.Columns.Add(column); DataRow lineItemRow = lineItemDataSet.Tables["LineItems"].NewRow(); lineItemRow["InvoiceId"] = invoiceId; lineItemRow["Discount"] = 1F; lineItemRow["Price"] = 2F; lineItemRow["Quantity"] = 3; lineItemRow["Description"] = "Description"; lineItemTable.Rows.Add(lineItemRow); return lineItemDataSet;}public void SaveInvoice(System.Data.DataSet dataSet){ throw new NotImplementedException();}} Here, we're manually creating DataSet object and populating rows with canned data that we're specifically checking for in the validation code within the test. It's worth noting that we haven't implemented SaveInvoice in this class. This is mostly because we haven't implemented this in the production code yet; but, in the case of testing Load, an exception would be thrown should it call SaveInvoice— adding more depth to the validation of the Load method, since it shouldn't be using SaveInvoice to load data. In the InvoiceRepositoryTest.LoadTest method, we're specifically using the InvoiceRepositoryDataAccessStub. InvoiceRepositoryDataAccessStub is a Stub of and IDataAccess specifically for use with InvoiceRepository. If you recall, a Stub is a Test Double that substitutes for a production component but inputs canned data into the system under test. In our test, we're just checking for that canned data to verify that the InvoiceRepository called our InvoiceRepositoryDataAccessStub instance in the correct way. Priorities In a project with little or no unit tests, it can be overwhelming to begin refactoring the code. There can be the tendency to want to first establish unit tests for the entire code base before refactoring starts. This, of course, is linear thinking. An established code base has been verified to a certain extent. If it's been deployed, the code effectively "works". Attempting to unit test every line of code isn't going to change that fact. It's when we start to change code that we want to verify that our change doesn't have an unwanted side-effect. To this effect, we want to prioritize unit-testing to avoid having unit-testing become the sole focus of the team. I find that the unit-testing priorities when starting out with unit-testing are the same as when a system has had unit tests for some time. The focus should be that any new code should have as much unit-testing code coverage as realistically possible and any code that needs to be refactored should have code coverage as high as realistically possible. The priority here is to ensure that any new code is tested and verified, and accept the fact that existing code has been verified in its own way. If we're not planning on immediately changing certain parts of code, they don't need unit-tests and should be of lower priority. Code coverage Something that often goes hand-in-hand with unit testing is Code Coverage. The goal of code coverage is to get as close to 100% coverage as reasonably possible. Code Coverage is the measure of the percentage of code that is executed (covered) by automated tests. Code coverage is a metric generally used in teams that are performing unit tests on a good portion of their code. Just starting out with unit testing, code coverage is effectively anecdotal. It doesn't tell you much more than you are doing some unit tests. One trap to get into as teams start approaching majority code coverage is to strive for 100% code coverage. This is both problematic and counterproductive. There is some code that is difficult to test and even harder to verify. The work involved to test this code is simply to increase code coverage percentages. I prefer to view the code coverage delta over time. In other words, I concentrate on how the code coverage percentage changes (or doesn't). I want to ensure that it's not going down. If the code coverage percentage is really low (say 25%) then I may want to see it increasing, but not at the risk of supplanting other work.
Read more
  • 0
  • 0
  • 1505

article-image-making-better-form-using-javascript
Packt
29 Jul 2010
12 min read
Save for later

Making a Better Form using JavaScript

Packt
29 Jul 2010
12 min read
(For more resources on Joomla!, see here.) But enough chat for now, work is awaiting us! Send the form using jQuery AJAX This is not going to be as hard as it may first seem, thanks to the powerful jQuery features. What steps do we need to take to achieve AJAX form sending? First, open our default_tmpl.phpfile. Here we are going to add an ID to our button, and change it a bit, from this: <input type="submit" name="send" value="Send" class="sc_button"/> to this: <input type="button" name="send" value="Send" class="sc_button"id="send_button"/> Apart from adding the ID, we change its type from submit to button. And with this our form is prepared. We need a new file, a js one this time, to keep things organized. So we are going to create a js folder, and place a littlecontact.js file in it, and we will have the following path: modules/mod_littlecontact/js/littlecontact.js As always, we will also include this file in the mod_littlecontact.xml file, like this: <filename>js/littlecontact.js</filename> Before adding our code to the littlecontact.js file, we are going to add it to the header section of our site. We will do this in the mod_littlecontact.php file, as follows: require_once(dirname(__FILE__).DS.'helper.php');$document =& JFactory::getDocument();$document->addScript(JURI::root(true).'modules'.DS.' mod_littlecontact'.DS.'js'.DS.'littlecontact.js');JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/'); I've highlighted the changes we need to make; first we get an instance to the global document object. Then we use the addScript method to add our script file to the header section.   We use JURI::root(true) to create a correct path. So now in our header, if we check the source code, we will see:   <script type="text/javascript" src="/modules/mod_littlecontact/js/littlecontact.js"></script> If instead of using JURI::root(true), we would have used JURI::root() our source code would look like the following: <script type="text/javascript" src="http://wayofthewebninja.com/ modules/mod_littlecontact/js/littlecontact.js"></script> You can find more information about the JURI::root method at: http://docs.joomla.org/JURI/root We are now ready to start working on our littlecontact.js file: jQuery(document).ready(function($){ $('#send_button').click(function() { $.post("index.php", $("#sc_form").serialize()); });}); It is a little piece of code, let's take a look at it. First we use the ready function, so all of our code is executed when the DOM is ready: jQuery(document).ready(function($){ Then we add the click method to the #send_button button. This method will have a function inside with some more code. This time we are using the post method: $.post("index.php", $("#sc_form").serialize()); The post method will send a request to a page, defined in the first parameter, using the HTTP post request method. In the second parameter we can find the data we are sending to the page. We could pass an array with some data, but instead we are using the serialize method on our form, with ID sc_form. The serialize method will read our form, and prepare a string for sending the data. And that's all; our form will be sent, without our visitors even noticing. Go ahead and try it! Also, you could take a look to the following two pages: http://api.jquery.com/jQuery.post/ http://api.jquery.com/serialize/ Here you can find some good information about these two functions. After you have taken a look at these pages, come back here, and we will continue. Well, sending the form without page reloading is OK, we will save our visitors some time. But we need our visitors to notice that something is happening and most important, that the message has been sent. We will now work on these two things. First of all we are going to place a message, so our readers will know that the form is being sent. This is going to be quite easy too. First we are going to add some markup to our default_tmpl.php, as follows: <?phpdefined('_JEXEC') or die('Direct Access to this location is not allowed.');?><div id="littlecontact"> . . . <div id="sending_message" class="hidden_div"> <br/><br/><br/> <h1>Your message is being sent, <br/>wait a bit.</h1> </div> <div id="message_sent" class="hidden_div"> <br/><br/><br/> <h1>Your message has been sent. <br/>Thanks for contacting us.</h1> <br/><br/><br/> <a href="index.php" class="message_link" id="message_back">Back to the form</a> </div></div> We have added two DIVs here: sending_message and message_sent. These two will help us show some messages to our visitors. With the messages prepared, we need some CSS styles, and we will define these in our module's styles.css file: #littlecontact{ position: relative;}#sending_message, #message_sent{ height: 235px; width: 284px; position: absolute; z-index: 100; background-color: #5B5751; top: 0; text-align: center;}.hidden_div{ visibility: hidden; display: none;}.show_div{ visibility: visible; display: block;}a.message_link:link, a.message_link:visited{ color: #ffffff; text-decoration: none;}a.message_link:hover{ text-decoration: underline;} Don't worry about writing all this code; you can find it in the code bundle, so copy it from there. Going back to the code, these are just simple CSS styles, and some of the most important ones are the hidden_div and show_div classes. These will be used to show or hide the messages. Ready to go to the JavaScript code? We will now return to our littlecontact.js file and modify it a bit: jQuery(document).ready(function($){ $('#send_button').click(function() { $.post("index.php", $("#sc_form").serialize(), show_ok()); $("#sending_message").removeClass("hidden_div"); }); $("#message_back").click(function(e){ e.preventDefault(); $("#message_sent").addClass("hidden_div"); $("#sending_message").addClass("hidden_div"); }); function show_ok(){ $("#sending_message").addClass("hidden_div"); $("#message_sent").removeClass("hidden_div"); $("input:text").val(''); $("textarea").val(''); }}); Seems a lot? Don't worry, we will take a step-by-step look at it. If we look at our previously added click function, we can see a new line, as follows: $("#sending_message").removeClass("hidden_div"); This will search for our sending_message DIV, and remove the hidden_div class. This way the DIV will be visible, and we will see a screen similar to the following screenshot: A nice message tells our visitors that the e-mail is being sent just at the moment. But we don't do only that. If we take a closer look at our previous post method, we will see some changes, as follows: $.post("index.php", $("#sc_form").serialize(), show_ok()); A new third parameter! This is a callback function, which will be executed when the request succeeds and our e-mail has been sent. But what is inside this show_ok function? Its contents are as follows: function show_ok(){ $("#sending_message").addClass("hidden_div"); $("#message_sent").removeClass("hidden_div"); $("input:text").val(''); $("textarea").val(''); } First we add the hidden_div class to the sending_message, so this sending message is not seen any more. But instead we remove the hidden_div class of our message_sent DIV, so our visitors will see this new message: But we are also emptying our inputs, text inputs, and textarea fields: $("input:text").val(''); $("textarea").val(''); So when visitors return to the form they are presented with a fresh one, just in case they have forgotten something and want to send a new e-mail. Hey who knows! Our last step is to enable a back link, so that the readers can return to the form: $("#message_back").click(function(e){ e.preventDefault(); $("#message_sent").addClass("hidden_div"); $("#sending_message").addClass("hidden_div"); }); First we target the link using its ID, and then we bind a click function to it. The next step is to prevent the default event for the link. This is why the link won't behave as a link, and won't try to load a page. This is why we are not going to load or reload a page, instead we will continue with our code, hiding both DIVs, so the form is visible again. That's it! It has not been that hard, has it? Now, it would be a great moment to take a look at the code bundle, see the code, read it, and try it by yourself. Or alternatively, keep reading a bit more if you want! Tips and tricks Look at the site http://www.ajaxload.info/. There you will be able to generate some loader GIF images. These will act as the typical clock mouse, telling the users that something is happening. Maybe you would like to use that instead of only using text. Give it a try! Validating form fields using jQuery—why validate? Ah! validating forms, so entertaining. It's just the kind of task everyone always wants to do. Well, maybe a bit less than others. But it's something that needs to be done. Why? Just to ensure that we are receiving the proper data, or even that we are receiving data. Ideally we would use JavaScript validation on the client side, and PHP validation on the server side. Server-side validation is essential, so a user turning off JavaScript still gets his/her contents validated. JavaScript validation will save us the effort of having to send all the data to the server, and then come back with the errors. We are going to use a bit of JavaScript to try to validate our form. This process is going to be quite simple too, as our form is very small. We will be doing all of our work in our littlecontact.js file. Remember our $('#send_button').click function? It looked like this: $('#send_button').click(function() { $.post("index.php", $("#sc_form").serialize(), show_ok()); $("#sending_message").removeClass("hidden_div"); }); Now with some modifications, it will be more or less as follows: $('#send_button').click(function() { //First we do some validation, //just to know that we have some data alerts = ''; if($("input[name=your_name]").val() == ''){ alerts += "we need your namen"; } if($("textarea[name=your_question]").val().length < 5){ alerts += "We need a message of at least 5 characters lengthn"; } if(alerts != ''){ alert(alerts); }else{ $.post("index.php", $("#sc_form").serialize(), show_ok()); $("#sending_message").removeClass("hidden_div"); } }); First, we define a new variable, to put all the messages in: alerts = ''; Then we check our form fields (first the input text): if($("input[name=your_name]").val() == '') As you can see, with jQuery we can select the input with a name equal to your_name and check if its value is empty. The textarea check is very similar: if($("textarea[name=your_question]").val().length < 5 But we are also checking if the length of the value is greater than five. After each one of these validations, if failed, we add a message to the alerts variable. Later, we will check if that variable is not empty. If it's not empty, it would mean that some of the checks have failed, and then we show the alerts to our visitors: alert(alerts); This will raise a typical alert message, much like the following screenshot: Informative, but not really nice. But thinking about it, we already have the jQuery UI library available, thanks to our SC jQuery Joomla! plugin. Why not use that plugin to show a better message? Let's do it. First we need to make some changes in the default_tmpl.php file: <div id="alerts" title="Errors found in the form" style="display: none;"></div> We have added a new DIV, with an ID equal to alerts, and with an informative title. Now that our markup is ready, some changes are also necessary in our littlecontact.js JavaScript file. For example, we are going to change our alert messages from the following: alerts += "- We need your namen";...alerts += "- We need a message of at least 5 characters lengthn"; To the following: alerts += "- We need your name<br/>";...alerts += "- We need a message of at least 5 chapters length<br/>"; Why are we doing this? It is because we will show HTML in our dialog, instead of just text. How are we going to show the dialog? Quite easily, by changing the following line: alert(alerts); To this: $("#alerts").html(alerts).dialog(); What are we doing here? First, we select our newly created DIV, with ID alerts, and then we use the html method, passing the variable alerts as its parameter. This will fill our DIV with the content of the alerts variable. Nested in it we will find the dialog method. This is a jQuery UI method that will create a dialog box, as we can see in the following screenshot: Better than our previous alert message, isn't it? Also notice that this dialog is matching the style of all our jQuery UI elements, like the login dialog and the tabs module. If we were to change the style in the SC jQuery Joomla! plugin, the style of the dialog will also change. If you want to know more about the jQuery UI dialog method, check the following page: http://jqueryui.com/demos/dialog/ Summary In this article we saw how to make a better form using JavaScript, send the form using jQuery AJAX, validate form fields using jQuery, and learn why it is important to validate. Well that's it for now. This is just a small example; now don't you think it would be great to give it a try? Further resources on this subject: Removing Unnecessary jQuery Loads [article] The Basics of Joomla! Module Creation and Creating a "Send us a question" Module [article]
Read more
  • 0
  • 0
  • 2150
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-microsoft-visual-studio-2010-improving-class-quality-coupling
Packt
29 Jul 2010
6 min read
Save for later

Microsoft Visual Studio 2010: Improving Class Quality with Coupling

Packt
29 Jul 2010
6 min read
(For more resources on Microsoft products, see here.) Coupling is the degree to which two things are related. Coupling and cohesion go hand in hand. Something that is highly-cohesive generally has low coupling. Coupling is a form of dependency. There are many different types of coupling when we're talking about software design and development. The effort here isn't to make a decoupled design, it's to change the coupling. At some level, one piece of code is coupled to every other piece of code in the system—there is rarely any change you can make to change that. Some code is more highly-coupled to other code and uses the other code directly. Some code is more loosely-coupled and uses other code indirectly. Efforts at refactoring towards a more loosely-coupled design are about the degree to which coupling has been made indirect. Code can be coupled to other code by a shared data format (external coupling). Code can be coupled to other code by the fact that it results in the execution of other code (control coupling). Code can be coupled to other code by the fact that it results in executing other code by way of an abstract interface ( message coupling). Code can be coupled to other code by the fact that they share data, usually in the form of parameters (data coupling ). Code can be coupled to other code by the fact that it has a subclass relationship ( subclass coupling). Code can also be coupled to other code by that fact that it directly references a type's public interface (content coupling ). The direction and degree to which a type is coupled can also help focus our refactoring efforts. Afferent coupling is the degree to which a type is depended upon (inward coupling). Efferent coupling is the degree to which a type depends on other types (outward coupling ). High afferent coupling can indicate that a type has too many responsibilities. It's trying to be everything to everyone and thus being used by everyone. High efferent coupling could indicate a type is very dependant. This becomes an issue when the types the class depends upon are in many different assemblies, suggesting a cohesion issue at the assembly layer. Highly-coupled software is generally accepted to exhibit certain traits, and it can be hard to change. It's like pulling on the thread of a sweater; there are so many dependencies it's impossible to predict how much code will need to be modified in order to make a seemingly simple change. Highly-coupled code is also very rigid. It's hard to move or hard not to duplicate it outside its current context. It carries a lot of baggage (dependencies) with it that need to move with it as a unit. It's one thing to move the code you want to move, it's exponentially harder to move all its dependencies. While good object-oriented design often promotes high cohesion, loosely coupled design and structure can easily fall to the wayside. Refactoring subclass coupling Refactoring subclass coupling involves removing the inheritance relationship between two classes. Refactoring content coupling Content coupling is one class directly referencing another. There are several tactics for refactoring away this coupling. Depending on the situation, one tactic may be more applicable than another. One tactic is to use interface-based design and remove the coupling to the content of the class and replace it with coupling to an interface that the other class now implements. Another tactic is to replace method calls into the other class with delegate invocations. A final tactic is to use events instead of direct method calls. For any particular refactoring, a combination of these tactics may be the best solution. You may find that despite a one-to-one coupling between two classes, it's more appropriate to use a combination of tactics to refactor away the content coupling. Interface-based design If you're already coupled to a particular class, replacing use of that class with an interface and having the other class implement that interface is the easiest way to change the coupling between two classes. This reduces coupling from content coupling to a more loosely coupled message coupling. If the requirements of the other class are very complex or a series of members must come from a single source, using interfaces is often the best solution. Having to hook up several delegates or several events becomes tedious and error prone when a single reference to an object that implements a particular interface is so simple. Imagine if implementing a Windows Form wasn't as simple as deriving from Form and having to register a number of delegates or events. If you find that implementers of the interface would find default or base implementation for them to be useful, implementing that interface may best be done with an abstract class. Our Invoice class is a good example of something that can be more loosely coupled through interface-based design. It currently implements the calculation of grand totals through interface-based design and the strategy pattern. This could have easily been implemented through direct use of a particular class. For example: /// <summary>/// Service to enapsulate calculation of/// grand totals./// </summary>public class InvoiceGrandTotalService{ public float CalculateGrandTotal(float invoiceSubTotal, float invoiceTotalTax) { return invoiceSubTotal + invoiceTotalTax; }}/// <summary>/// Invoice class that uses/// <seealso cref="InvoiceGrandTotalService"/>/// </summary>public class Invoice{ InvoiceGrandTotalService invoiceGrandTotalService = new InvoiceGrandTotalService(); public List<InvoiceLineItem> InvoiceLineItems { get; set; } public Invoice(IEnumerable<InvoiceLineItem> invoiceLineItems) { InvoiceLineItems = new List<InvoiceLineItem>(invoiceLineItems); } public float CalculateGrandTotal(float invoiceSubTotal, float invoiceTotalTax) { return invoiceGrandTotalService.CalculateGrandTotal( invoiceSubTotal, invoiceTotalTax); } //...} In this example, we've created the InvoiceGrandTotalService class that contains the CalculateGrandTotal method. We then instantiate this class in the Invoice class and make reference to it in the CalculateGrandTotal method. We've given away the surprise with this refactoring. We're obviously going to replace direct use of the class with an interface. Since we essentially need a reference to an object right from the start, and to effectively loosen the coupling, we begin refactoring by accepting a reference to an IInvoiceGrandTotalStrategy object in the constructor. We then change our InvoiceGrandTotalService field to an IInvoiceGrandTotalStrategy field and initialize it in the constructor. We finish our refactoring by replacing references from invoiceGrandTotalServcie to invoiceGrandTotalStrategy. The resulting refactoring will look similar to the following: /// <summary>/// Invoice class that uses/// <seealso cref="IInvoiceGrandTotalStrategy"/>/// </summary>public class Invoice{ private IInvoiceGrandTotalStrategy invoiceGrandTotalStrategy; public List<InvoiceLineItem> InvoiceLineItems { get; set; } public Invoice(IEnumerable<InvoiceLineItem> invoiceLineItems, IInvoiceGrandTotalStrategy invoiceGrandTotalStrategy) { InvoiceLineItems = new List<InvoiceLineItem>(invoiceLineItems); this.invoiceGrandTotalStrategy = invoiceGrandTotalStrategy; } public float CalculateGrandTotal(float invoiceSubTotal, float invoiceTotalTax) { return invoiceGrandTotalStrategy.CalculateGrandTotal( invoiceSubTotal, invoiceTotalTax); } //...} If you find that the relationship between the two classes is the invocation of one or two methods that return or update data, you may find that delegates are the best way of refactoring.
Read more
  • 0
  • 0
  • 1636

article-image-basics-joomla-module-creation-and-creating-send-us-question-module
Packt
29 Jul 2010
9 min read
Save for later

The Basics of Joomla! Module Creation and Creating a "Send us a question" Module

Packt
29 Jul 2010
9 min read
(For more resources on Joomla!, see here.) Building a basic Joomla! module is not that difficult. In fact it's quite easy. Just stay with me, and we will divide the task into some easy-to-follow steps. First of all, we need to create a folder for our module, for example, mod_littlecontact. This folder is where we will place all the files necessary for our module. For example, one of the files we are going to need is the mod_littlecontact.php file, which is named exactly the same as the folder, but with a .php extension. Let's see what we need to put in it: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');?><h1>Just a simple contact form!</h1> We will look at just the basics. First, defined('_JEXEC') checks whether the file has been included by Joomla! instead of being called directly. If it has been included by Joomla!, the _JEXEC constant would have been defined. With this PHP file created we need to create another file, an XML one this time. We will call it mod_littlecontact.xml; notice that, again, the name is the same as the folder one. Just create the file, and after that we will place the following contents in it: <?xml version="1.0" encoding="utf-8"?><install type="module" version="1.5.0"> <name>Little Contact Form</name> <author>Jose Argudo Blanco</author> <creationDate>2010</creationDate> <copyright>All rights reserved by Jose Argudo Blanco.</copyright> <license>GPL 2.0</license> <authorEmail>jose@joseargudo.com</authorEmail> <authorUrl>www.joseargudo.com</authorUrl> <version>1.0.0</version> <description>A simple contact form</description> <files> <filename module="mod_littlecontact"> mod_littlecontact.php</filename> </files></install> Most of the contents of this XML file are quite easy to follow and very self-explanatory. In the files section, we have included all the files necessary for our module. Notice that we do not include the XML file itself. With these two files created, we can give a try to this simple module. Copying this folder into our Joomla! modules folder won't work, as Joomla! requires us to install the extension through the Extensions | Install/Uninstall menu. So, what do we need to do? Just compress these two files into a ZIP file by using any tool of your liking. At the end we will need to have a mod_littlecontact.zip file with the following two files inside: mod_littlecontact.php mod_littlecontact.xml Installing our module is done exactly as with any other modules. Go to the administrator screen of our site, then go to the Extensions | Install/Uninstall menu, search and select the file, and then click on Upload File & Install button. If all goes OK, and it really should, we will be able to find our module listed in Extensions | Module Manager, as seen in the following screenshot: We can click in the module name, just as we would do with any of the others. If we enter the administration panel of the module we will see a screen very much like the other modules, as Joomla! standardizes this screen. Just take a look at the Details zone, which will look like the next screenshot: He re we can select the parameters we want, and enable the module. This time we will place it in the module_7 position of our template. Also note that the description is the one that we place in the module XML file: <description>A simple contact form</description> After we have enabled the module, we will be able to see it in the frontend, in the module position we have selected: There's not too much for now, but it's working! Now we will enhance it and convert it into a contact form. Note that now that we have installed our module, a new folder will have been created into our Joomla! installation. We can find this folder in the modules folder, it will be called mod_littlecontact. So now we have this structure on our Joomla! Site: modules/ mod_littlecontact/ mod_littlecontact.php mod_littlecontact.xml As the module is already installed, we can modify these files, and we will be able to see the changes without needing to reinstall it. We have just accomplished our first step; the basics are there, and now we can concentrate on making our modifications. Creating a "Send us a question" module One of the first things we are going to create is an empty index.html file; this will be used so that no one can take a look at the folder structure for the module. For example, imagine that our site is installed in http://wayofthewebninja.com. If we go to http://wayofthewebninja.com/modules/mod_littlecontact/ we will see something like the next image: If we try to click on mod_littlecontact.php, we will see the following phrase: Direct Access to this location is not allowed. That's because the code we added to our file is as follows: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');?> Of course, we don't want people to be able to see which files we are using for our module. For this place, we used the empty index.html file mentioned in the modules/mod_littlecontact folder. This way, if anyone tries to go to http://wayofthewebninja.com/modules/mod_ littlecontact/, they will see only an empty screen. Good, now note that when we add any file, we need to reflect it on the mod_littlecontact.xml file in the files section: <files> <filename module="mod_littlecontact">mod_littlecontact.php</filename> <filename>index.html</filename></files> This way, when we pack the file for install, the installation process will take this file into account, otherwise it will be left out. Once we have done this, we are going to create another file, a CSS one this time, so we can put our styles in it. For this we are going to first create a new folder, also called css. It will be placed in modules/mod_littlecontact/. Inside that folder we will create a file called styles.css; this file also needs to be declared in the XML: <filename>css/styles.css</filename> In this modules/mod_littlecontact/css/styles.css file we are going to place the following code: #littlecontact h1{ font-size: 18px; border-bottom: 1px solid #ffffff;} But then, if we are to apply these styles, we need to load this CSS file. How are we going to do this? Open the modules/mod_littlecontact/mod_littlecontact.php file and modify it as follows: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/');?><div id="littlecontact"> <h1>Just a simple contact form!</h1></div> There's not much change here; we have enveloped our previous content in a DIV, with the littlecontact ID, so that we can target our styles. This is the easy part, but there's also an important one, shown as follows: JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/'); We are using the JHTML::stylesheet method to create a link, in our header section, to our CSS file. In fact, if we check the source code on our frontend, we will see: <link rel="stylesheet" href="/modules/mod_littlecontact/css/styles.css" type="text/css" /> This way our stylesheet will be loaded, and our module will look like the next screenshot: As we can see, our styles have been applied. The JHTML::stylesheet method is quite easy to use, the first parameter being the file and the second one being the path to the file. Now we are going to prepare our simple form. Again we will modify our mod_littlecontact.php file, and now it will look more like the following: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/');?><div id="littlecontact"> <h1>Just a simple contact form!</h1> <form action="index.php" method="post" id="sc_form"> <label>Your name:</label><br/> <input type="text" name="your_name" value="" size="40" class="sc_input"/><br/><br/> <label>Your question:</label><br/> <textarea name="your_question" class="sc_input" rows="5" cols="30"></textarea><br/><br/> <input type="submit" name="send" value="Send" class="sc_button" /> </form></div> This is a common HTML form. We need some styling here, just to make it look good. Let's make the following minimal changes to our styles.css file: #littlecontact h1{ font-size: 18px; border-bottom: 1px solid #ffffff; margin-bottom: 15px;}.sc_input{ border: 1px solid #3A362F;}.sc_button{ background-color: #3A362F; border: 0; color: #ffffff; padding: 5px;} Most styles are new, and modifications to previous h1 styling have been marked. With this minimal change our module looks a bit better. You can see it in the following screenshot:
Read more
  • 0
  • 0
  • 3440

article-image-new-features-jpa-20
Packt
28 Jul 2010
9 min read
Save for later

New Features in JPA 2.0

Packt
28 Jul 2010
9 min read
(For more resources on Java, see here.) Version 2.0 of the JPA specification introduces some new features to make working with JPA even easier. In the following sections, we discuss some of these new features: Criteria API One of the main additions to JPA in the 2.0 specification is the introduction of the Criteria API. The Criteria API is meant as a complement to the Java Persistence Query Language (JPQL). Although JPQL is very flexible, it has some problems that make working with it more difficult than necessary. For starters, JPQL queries are stored as strings and the compiler has no way of validating JPQL syntax. Additionally, JPQL is not type safe. We could write a JPQL query in which our where clause could have a string value for a numeric property and our code would compile and deploy just fine. To get around the JPQL limitations described in the previous paragraph, the Criteria API was introduced to JPA in version 2.0 of the specification. The Criteria API allows us to write JPA queries programmatically, without having to rely on JPQL. The following code example illustrates how to use the Criteria API in our Java EE 6 applications: package net.ensode.glassfishbook.criteriaapi;import java.io.IOException;import java.io.PrintWriter;import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.PersistenceUnit;import javax.persistence.TypedQuery;import ja vax.persistence.criteria.CriteriaBuilder;import javax.persistence.criteria.CriteriaQuery;import javax.persistence.criteria.Path;import javax.persistence.criteria.Predicate;import javax.persistence.criteria.Root;import javax.persistence.metamodel.EntityType;import javax.persistence.metamodel.Metamodel;import javax.persistence.metamodel.SingularAttribute;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet(urlPatterns = {"/criteriaapi"})public class CriteriaApiDemoServlet extends HttpServlet{ @PersistenceUnit(unitName = "customerPersistenceUnit") private EntityManagerFactory entityManagerFactory; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter printWriter = response.getWriter(); List<UsState> matchingStatesList; EntityManager entityManager = entityManagerFactory.createEntityManager(); CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<UsState> criteriaQuery = criteriaBuilder.createQuery(UsState.class); Root<UsState> root = criteriaQuery.from(UsState.class); Metamodel metamodel = entityManagerFactory.getMetamodel(); EntityType<UsState> usStateEntityType = metamodel.entity(UsState.class); SingularAttribute<UsState, String> usStateAttribute = usStateEntityType.getDeclaredSingularAttribute("usStateNm", String.class); Path<String> path = root.get(usStateAttribute); Predicate predicate = criteriaBuilder.like(path, "New%"); criteriaQuery = criteriaQuery.where(predicate); TypedQuery typedQuery = entityManager.createQuery(criteriaQuery); matchingStatesList = typedQuery.getResultList(); response.setContentType("text/html"); printWriter.println("The following states match the criteria:<br/>"); for (UsState state : matchingStatesList) { printWriter.println(state.getUsStateNm() + "<br/>"); } }} This example takes advantage of the Criteria APIc. When writing code using the Criteria API, the first thing we need to do is to obtain an instance of a class implementing the javax.persistence.criteria. CriteriaBuilder interface. As we can see in the previous example, we need to obtain said instance by invoking the getCriteriaBuilder() method on our EntityManager. From our CriteriaBuilder implementation, we need to obtain an instance of a class implementing the javax.persistence.criteria.CriteriaQuery interface. We do this by invoking the createQuery() method in our CriteriaBuilder implementation. Notice that CriteriaQuery is generically typed. The generic type argument dictates the type of result that our CriteriaQuery implementation will return upon execution. By taking advantage of generics in this way, the Criteria API allows us to write type safe code. Once we have obtained a CriteriaQuery implementation, from it we can obtain an instance of a class implementing the javax.persistence.criteria.Root interface. The Root implementation dictates what JPA entity we will be querying from. It is analogous to the FROM query in JPQL (and SQL). The next two lines in our example take advantage of another new addition to the JPA specification—the Metamodel API. In order to take advantage of the Metamodel API, we need to obtain an implementation of the javax.persistence. metamodel.Metamodel interface by invoking the getMetamodel() method on our EntityManagerFactory. From our Metamodel implementation, we can obtain a generically typed instance of the javax.persistence.metamodel.EntityType interface. The generic type argument indicates the JPA entity our EntityType implementation corresponds to. EntityType allows us to browse the persistent attributes of our JPA entities at runtime. This is exactly what we do in the next line in our example. In our case, we are getting an instance of SingularAttribute, which maps to a simple, singular attribute in our JPA entity. EntityType has methods to obtain attributes that map to collections, sets, lists, and maps. Obtaining these types of attributes is very similar to obtaining a SingularAttribute, therefore we won't be covering those directly. Refer to the Java EE 6 API documentation at http://java.sun.com/javaee/6/ docs/api/ for more information. As we can see in our example, SingularAttribute contains two generic type arguments. The first argument dictates the JPA entity we are working with and the second one indicates the type of attribute. We obtain our SingularAttribute by invoking the getDeclaredSingularAttribute() method on our EntityType implementation and passing the attribute name (as declared in our JPA entity) as a String. Once we have obtained our SingularAttribute implementation, we need to obtain an import javax.persistence.criteria.Path implementation by invoking the get() method in our Root instance and passing our SingularAttribute as a parameter. In our example, we will get a list of all the "new" states in the United States (that is, all states whose names start with "New"). Of course, this is the job of a "like" condition. We can do this with the Criteria API by invoking the like() method on our CriteriaBuilder implementation. The like() method takes our Path implementation as its first parameter and the value to search for as its second parameter. CriteriaBuilder has a number of methods that are analogous to SQL and JPQL clauses such as equals(), greaterThan(), lessThan(), and(), or(), and so on and so forth (for the complete list, refer to the Java EE 6 documentation at http://java.sun.com/javaee/6/docs/api/). These methods can be combined to create complex queries via the Criteria API. The like() method in CriteriaBuilder returns an implementation of the javax.persistence.criteria.Predicate interface, which we need to pass to the where() method in our CriteriaQuery implementation. This method returns a new instance of CriteriaBuilder which we assign to our criteriaBuilder variable. At this point, we are ready to build our query. When working with the Criteria API, we deal with the javax.persistence.TypedQuery interface, which can be thought of as a type-safe version of the Query interface we use with JPQL. We obtain an instance of TypedQuery by invoking the createQuery() method in EntityManager and passing our CriteriaQuery implementation as a parameter. To obtain our query results as a list, we simply invoke getResultList() on our TypedQuery implementation. It is worth reiterating that the Criteria API is type safe. Therefore, attempting to assign the results of getResultList() to a list of the wrong type would result in a compilation error. After building, packaging, and deploying our code, then pointing the browser to our servlet's URL, we should see all the "New" states displayed in the browser. Bean Validation support Another new feature introduced in JPA 2.0 is support for JSR 303, Bean Validation. Bean Validation support allows us to annotate our JPA entities with Bean Validation annotations. These annotations allow us to easily validate user input and perform data sanitation. Taking advantage of Bean Validation is very simple, all we need to do is annotate our JPA entity fields or getter methods with any of the validation annotations defined in the javax.validation.constraints package. Once our fields are annotated as appropriate, the EntityManager will prevent non-validating data from being persisted. The following code example is a modified version of the Customer JPA entity. It has been modifed to take advantage of Bean Validation in some of its fields. package net.ensode.glassfishbook.jpa.beanvalidation;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.Table;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;@Entity@Table(name = "CUSTOMERS")public class Customer implements Serializable{ @Id @Column(name = "CUSTOMER_ID") private Long customerId; @Column(name = "FIRST_NAME") @NotNull @Size(min=2, max=20) private String firstName; @Column(name = "LAST_NAME") @NotNull @Size(min=2, max=20) private String lastName; private String email; public Long getCustomerId() { return customerId; } public void setCustomerId(Long customerId) { this.customerId = customerId; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; }} In this example, we used the @NotNull annotation to prevent the firstName and lastName of our entity from being persisted with null values. We also used the @Size annotation to restrict the minimum and maximum length of these fields. This is all we need to do to take advantage of Bean Validation in JPA. If our code attempts to persist or update an instance of our entity that does not pass the declared validation, an exception of type javax.validation.ConstraintViolationException will be thrown and the entity will not be persisted. As we can see, Bean Validation pretty much automates data validation, freeing us from having to manually write validation code. In addition to the two annotations discussed in the previous example, the javax.validation.constraints package contains several additional annotations that we can use to automate validation on our JPA entities. Refer to the Java EE 6 API documentation at http://java.sun.com/javaee/6/docs/api/ for the complete list. Summary In this article, we discussed some new JPA 2.0 features such as the Criteria API that allows us to build JPA queries programmatically, the Metamodel API that allows us to take advantage of Java's type safety when working with JPA, and Bean Validation that allows us to easily validate input by simply annotating our JPA entity fields. Further resources on this subject: Interacting with Databases through the Java Persistence API [article] Setting up GlassFish for JMS and Working with Message Queues [article]
Read more
  • 0
  • 0
  • 3403

article-image-flash-10-multiplayer-game-game-interface-design
Packt
28 Jul 2010
10 min read
Save for later

Flash 10 Multiplayer Game: Game Interface Design

Packt
28 Jul 2010
10 min read
(For more resources on Flash and Games, see here.) Overview of Pulse library components The Pulse package includes two components Pulse.swc and PulseUI.swc.The Pulse.swc offers the API required for you to build a multiplayer game. While PulseUI offers the game screen management, both aid in the rapid development of your game. The Pulse.swc is required in order to communicate with the server and with other clients. The usage of PulseUI, on the other hand, is optional. It is recommended to use the PulseUI since it allows you to focus only on the game implementation and leaves the standard feature set of a multiplayer game to be taken care of by the PulseUI package. Once you have the implementation of your game done and working well, you can then replace the PulseUI package with something of your own that is more suited to your game. The following is a block diagram that shows the dependencies among different components: The Pulse API design The interaction of the game client with the server and other clients happens primarily via two classes that expose the Pulse features: GameClient GameClientCallback The GameClient is primarily used to send request to the server while creating a room, joining a room, or sending a message to other players such as chat or game state updates during game play. The GameClientCallback is an AS3 interface class for which one of the classes within the GameClient must implement. All notifications from the server are processed by the Pulse layer and corresponding notifications are called on the implementation of the callback class—for example, when a create room request was successful or when a chat message was received, etc. Creating the Hello World sample Let us now explore the Hello World sample that is included in the Pulse package. The Hello World sample and the rest of the samples rely heavily on the game screen management framework package, PulseUI, which is also included in the Pulse package along with the source code. In this article, we will focus on the code contained in the Hello World sample and how the sample makes use of the PulseUI. In order to explore the Hello World sample, we first need to create a project in Flash Builder—all the required source files already exists in the sample folders. The Hello World sample does the following: create a room or join an existing game room, then add, remove, or modify a game state—the changes done on one client instance are then reflected on all other clients that are in the same room. Think it is too much for a Hello World sample? It is not! These are just the basic functionalities for any multiplayer game. Moreover, we don't need to write the code for every bit of functionality because we heavily rely on Pulse SDK to do all the dirty work. Setting up the project Fire up the Flash Builder 4 IDE and let us start by creating an ActionScript project called Hello World: From the main menu, navigate to File | New | ActionScript Project. You will see the following screenshot. Enter a project name HelloWorld or any other name of your choice. Since we already have the entire source required for Hello World from the Pulse package, click on Next to specify that the source folder is already on the disk. This will bring up the following screen where we choose the Hello World src folder as shown. Note that the screenshot shows that Pulse was installed under F:Gamantra. This path may be different on your computer. Once we have chosen the source folder, we still need to choose the main source folder and main application file. Unfortunately, in order to do this, we need to navigate a bug in Flash Builder 4. You need to click on the Back button and then again on the Next button, bringing us back to where we were. We now click on the Browse button, as shown in the screenshot, and choose the [source path] src and click on OK. Next we choose the main application file—this determines the main class file that the execution will start with. We need to tell the Flash Builder to use the Pulse libraries for this project. In the Flash world, the library files come with an extension .swc, which stands for shockwave component. Once you make it available to your project, you can start using the classes and functions that are exposed from within the library. In order to do so, choose the Library Path tab view and click on the Add SWC… button; navigate to the lib folder within the Pulse installation folder and choose Pulse.swc and once again do the same procedure for PulseUI.swc. Click on the Finish button. As a final step, before attempting to run the sample, we also need to set the stage size to 800 (width) by 600 (height). The PulseUI requires the stage size to be exactly this size. We may also set the background color of our choice as shown in the following screenshot: After this step, Flash Builder 4 should be able to crunch all the code in folders and report no problems. This will also create the swf files under the project folder within the workspace ready for you to take it for a spin. At this point, you may also use the debugger to step through the code. But make sure the Pulse server is running so that you may login and explore all the screens. The Hello World specification The Hello World client will be able to create a new HelloGameState and share it with other players, and any player may change the x and y and have that change reflected in every player's screen. Here is the final screen that we will end up with: The screenshot is that of the game screen. The circles are a visual representation of the game states, the position of the circle comes from the corresponding game states x and y values and so does the color from the color property. We will have two buttons: one to add new game states and another to remove them. To add a new circle (a game state), we click on the Add button. To remove an existing game state, we click on any of the circles and click on the Remove button. The selected circle appears to be raised like the one on the far right-hand side of the screenshot. We may also modify an existing game state by moving the circles by clicking and dragging them to a different position—doing that on one client, we can observe the change in every other player's screen as well. The schema file For any Pulse-based game development, we first start out with an XML-formatted schema file. Let's now explore the schema file for the Hello World sample. The game developer must create a schema file that specifies all the needed game states, avatars, and game room objects. After you have created the schema file, we then use a Pulse modeler tool to create the class files based on the schema to be used within the game. So first let's examine the schema file for the Hello World project: <ObjectSchema> <import> <client import="pulse.gsrc.client.*" /> </import> <class name="HelloGameState" parent="GameState" classId="601" > <public> <property index="0" name="x" count="1" type="int"/> <property index="1" name="y" count="1" type="int"/> <property index="2" name="color" count="1" type="int"/> </public> </class></ObjectSchema> Navigate to the project folder where you have created the project and create a file called GameSchema.xml with the above content. We will not go through the details of the XML file in greater detail since it is out of the scope of this article. For the Hello World sample, we will define a game state object that we can use to share game states among all the players within a game room. We will name the class as HelloGameState, but you are welcome to call it by any name or something that makes sense to your game. You may also define as many game state classes as you like. For the HelloGameState in the schema file, each game state instance will define three properties, namely, x, y, and color. Code generator In order to create the AS3 class files from the schema file, you need to run the batch file called PulseCodeGen.bat found in the $bin folder. It takes the following three parameters: Path to schema file Namespace Output directory In order to make our life easier, let us create a batch file that will call the PulseCodeGen and pass all the required parameters. The reason for creating the batch file is that you have to code generate every time you modify the schema file. As you progress through your game implementation, it is normal to add a new class or modify an existing one. The convenience batch file may look like what's shown next. Let's call it .init.bat and save it in the same root folder for the sample along with the schema file. @ECHO OFFIF EXIST .srchwgsrcclient del .srchwgsrcclient*.asCALL "%GAMANTRA%"binPulseCodeGen.bat .GameSchema.xml hw.gsrc .srchwgsrcIF NOT %ERRORLEVEL% == 0 GOTO ERRORECHO Success!GOTO END:ERRORECHO oops!:ENDpause The schema file parameter to the Pulse code generator is specified as .GameSchema.xml because the schema file and the batch file are in the same folder. The second parameter is the package name for the generated classes—in this example, it is specified to be hw.gsrc. You specify the directory that the generated classes will be saved to as the last parameter. Note that the code generator appends client to both the package and directory into which it will be saved. It is also important to match the package name and directory structure as required by the AS3 compiler. Upon running the code gen successfully, there is one AS3 class generated for each class in the schema file and two additional supporting class files. One is a factory class called GNetClientObjectFactory, which is responsible for creating new instances of generated classes, and the other is GNetMetaDataMgr, which aids in serializing and de-serializing the transmitting data over the network. The data carried is what resides in the instances of generated classes. You don't need to deal with these two extra classes first hand; it is mostly used by the underlying Pulse runtime system. As for the generated classes for what is defined in the schema file, the name of the class would be identical to what is specified in the schema file plus the suffix Client. In this example, there would be a class generated with the name HelloGameStateClient.as. Go ahead and try running the batch file called init.bat under $samplesHelloWorld. Project directory structure The Hello World that is part of the Pulse package is organized into the following directory structure: hw gsrc client rsrc ui The package hw being the root package contains the main class HelloWorld.as, and the gsrc as you see contains the generated class. The rsrc folder contains the skin files, which we will discuss in more detail later in this article. The skin files in Pulse consist of three PNG files that provide all the basic buttons and background for the game. You can simply replace these PNG files with your own set, provided the individual elements with the file are of the exact dimensions and are placed at the exact same positions.
Read more
  • 0
  • 1
  • 4777
article-image-solving-least-privilege-problems-application-compatibility-toolkit
Packt
28 Jul 2010
5 min read
Save for later

Solving Least Privilege Problems with the Application Compatibility Toolkit

Packt
28 Jul 2010
5 min read
(For more resources on Microsoft products, see here.) Quick compatibility fixes using the Program Compatibility Wizard In small enterprise environments or on home computers, compatibility fixes can be applied without using the Application Compatibility Toolkit through the user interface. If you want to know how the Windows Application Compatibility Infrastructure works in detail or if you want to deploy fixes to multiple devices, skip straight to the second part of this article: Achieving application compatibility in enterprise environments. Applying compatibility modes to legacy applications Compatibility fixes can be grouped together to form compatibility modes. Windows XP, Vista, and Windows 7 all come with a default set of compatibility modes out of the box. System administrators can also use Compatibility Administrator to create their own compatibility modes. Compatibility modes can be applied directly from the user interface either by using the Program Compatibility Wizard in Windows XP, or by right-clicking on an executable file, or a shortcut to an executable file, and selecting Properties from the menu. Windows XP contains the following compatibility modes: Windows 95 Windows 98 / Windows ME Windows NT 4.0 (Service Pack 5) Windows 2000 As shown in the following screenshot, the Compatibility tab in Vista and Windows 7(left) looks a little different from Windows XP (right). Privilege level in Vista and Windows 7Note that the Run this program as an administrator option will be grayed out if an application manifest is included with the program. Program Compatibility Wizard Included in Windows Vista and later, the Program Compatibility Wizard allows users or system administrators to test legacy applications running against different compatibility modes. To launch the Program Compatibility Wizard in Windows XP, select Start | Accessories | Program Compatibility Wizard. To launch the Program Compatibility Wizard in Windows Vista, type the following command into the Search box on the Start menu:%systemroot%System32mshta.exe res://acprgwiz.dll/compatmode.htaTo launch the Program Compatibility Wizard in Windows 7, search for program compatibility troubleshooter in Start | Help and Support. Click Next on the welcome screen in Help and Support Center. Leave the default I want to choose from a list of programs option selected and click on Next. Select the application you want to test, in this case Maxthon, from the Select a program list and click on Next. Choose a compatibility mode from the list, such as Microsoft Windows 95 or Windows 2000, and click on Next. Compatibility modes set using the Program Compatibility Wizard only apply to the currently logged in user. Compatibility settings in Vista and Windows 7 can be applied to the logged in user or to all users.Administrative privileges are required to apply compatibility settings for a given application to all users of a system. If required, select display settings (256 colors or 640 x 480 screen resolution) to be used with the program and then click on Next. Click Next to test the compatibility mode against your application. The application will launch and you can test it to see if the selected compatibility mode resolves the identified problems. Once you've finished testing, close the application. Back in the Help and Support Center, choose to either apply the compatibility settings or try different settings. Browsing compatibility settings for each userIf compatibility modes are set on programs for specific users, you can use Compatibility Administrator to browse the settings for each user under the Per User Compatibility Settings node. This node only appears if per user settings are found on the system. Program Compatibility Assistant Introduced in Windows Vista, the Program Compatibility Assistant helps to automate the process of applying compatibility fixes to legacy applications by monitoring for known problems when programs are running. This feature runs as a service, and prompts users to apply suggested fixes for applications, either during the setup phase or when running an installed application. The Program Compatibility Assistant can detect the following problems automatically: Errors when launching setup programs Failures in install routines Failures caused by User Account Control An install needing to run as an administrator A control panel applet requiring administrative privileges Errors caused because a component is not present in the current version of Windows Notifying users about unsigned drivers on 64-bit versions of Windows Matching applications against a list of programs with known problems and notifying the user at program startup The Program Compatibility Assistant intercepts an installation routine, prompting the user to try again using recommended settings. Disabling the Program Compatibility Assistant The Program Compatibility Assistant is intended to help home users resolve problems with legacy applications. In an enterprise environment, to avoid potential problems with messages generated by the Program Compatibility Assistant, you should consider disabling the service in Group Policy. The Turn off Program Compatibility Assistant setting can be found in the Group Policy Management Editor under Computer or User Configuration | Policies | Administrative Templates | Windows Components | Application Compatibility. Excluding executables from the Program Compatibility Assistant The Program Compatibility Assistant doesn't monitor programs that have an application manifest that marks them as compatible with Vista or Windows 7. However, if you want to exclude a program but don't want to disable the Program Compatibility Assistant completely, you can create a REG_MULTI_SZ registry value named ExecutablesToExclude under the following key:HKLM SoftwareMicrosoftWindows NTCurrentVersionCompatibility Assistant
Read more
  • 0
  • 0
  • 9069

article-image-application-session-and-request-scope-coldfusion-9
Packt
27 Jul 2010
8 min read
Save for later

Application, Session, and Request Scope in ColdFusion 9

Packt
27 Jul 2010
8 min read
(For more resources on ColdFusion, see here.) The start methods We will have a look at the start methods and make some observations now. Each method has its own set of arguments. All Application.cfc methods return a Boolean value of true or false to declare if they completed correctly or not. Any code you place inside a method will execute when the start event occurs. These are the events that match with the name of the method. We will also include some basic code that will help you build an application core that is good for reuse and discuss what those features provide. Application start method—onApplicationStart() The following is the code structure of the application start method. You could actually place these methods in any order in the CFC, as the order does not matter. Code that uses CFCs only require the methods to exist. If they exist, then it will call them. We place them in our code so that it helps us to read and understand the structure from a human perspective. <cffunction name="onApplicationStart" output="false"> <cfscript> // create default stat structure and pre-request values application._stat = structNew(); application._stat.started = now(); application._stat.thisHit = now(); application._stat.hits = 0; application._stat.sessions = 0; </cfscript></cffunction> There are no arguments for the onApplicationStart() method. We have included some extra code to show you an example of what can be done in this function. Please note that if we change the code in this method, it will only run at the very first time when an application running in ColdFusion is hit. To hit it again, we need to either change the application name or restart the ColdFusion server. The Application variables section that was previously explained shows how to change the application's name. From the start methods, we can see that we can access the variable scopes that allow persistence of key information. To understand the power of this object, we will be creating some statistics that can be used in most situations. We could use them for debugging, logging, or in any other appropriate use case. Again, we have to be aware that this only gets hit the first time a request is made to a ColdFusion server for that application. We will be updating many of our statistics in the request methods. We will also be updating one of our variables in the session end method. Session start method—onSessionStart() The session start method only gets called when a request is made for a new session. It is good that ColdFusion can keep track of these things. The following is example code that allows us to keep a record of the session-based statistics that is similar to the application-based statistics: <cffunction name="onSessionStart" output="false"> <cfscript> // create default session stat structure and pre-request values session._stat.started = now(); session._stat.thisHit = now(); session._stat.hits = 0; // at start of each session update count for application stat application._stat.sessions += 1; </cfscript></cffunction> You might have noticed that in the previous code we used +=. In ColdFusion prior to version 8, you had to type that particular line in a different way. The following two examples are the same in functionality (example one works in all versions and two works only in version 8 and higher): Example 1: myTotal = myTotal +3 Example 2: myTotal += 3 This is common in JavaScript, ActionScript, and many other languages. This syntax was added in ColdFusion version 8. We change the application-based setting because sessions are hidden from one another and cannot see each other. Therefore, we use the application CFC to either count or add a count every time a new session starts. Request start method—onRequestStart() This is one of the longest methods in the article. The first thing you will notice is that the script that is called is passed to the onRequestStart() method by ColdFusion. In this example, we will instruct ColdFusion to block any scripts from execution that begin with an underscore when called remotely. This means that you can call the server and request any .cfm page or .cfc page with an underscore at the start, and this protects it from being called outside the local server. The files can still be run if called from pages inside the server. This makes all these files locally accessible: <cffunction name="onRequestStart" output="false"> <cfargument name="thePage" type="string" required="true"> <cfscript> var myReturn = true; //fancy code to block pages that start with underscore if(left(listLast(arguments.thePage,"/"),1) EQ "_") { myReturn = false; } // update application stat on each request application._stat.lastHit = application._stat.thisHit; application._stat.thisHit = now(); application._stat.hits += 1; // update session stat on each request session._stat.lastHit = session._stat.thisHit; session._stat.thisHit = now(); session._stat.hits += 1; </cfscript> <cfreturn myReturn></cffunction> The methods in the following sections are used to update all the application and session statistics variables that need to be updated with each request. You should also notice that we are recording the last time the application or session was requested. The end methods Previously, some of the methods in this object were impossible to achieve with the earlier versions of ColdFusion. It was possible to code an end request function, but only a few programmers made use of it. We find that by using this object many more people are taking advantage of these features. The new methods that are added have the ability to run code specifically when a session ends, and when an application ends. This allows us to do things that we could not do previously. We can keep a record of how long a user is online without having to access the database with each request. When the session starts, you can store it in the session scope. When the session ends, you can take all that information and store it in the session log table if logging is desired in your site. Request end method—onRequestEnd() We are not going to use every method that is available to us. As we have the concept from the other sections, this would be redundant. The concepts of this method are very similar to the onRequestStart() method with the exception that it occurs after the requested page has been called. If you create content in this method and set the output attribute to true, then it will be sent back to browser requests. Here you can place the code that logs information about our requests: <cffunction name="onRequestEnd" returnType="void" output="false"> <cfargument name="thePage" type="string" required="true"></cffunction> Session end method—onSessionEnd() In the session end method, we can perform logging functions for analytical statistics that are specific to the end of a session if desired for your site. You need to use the argument's scope variables to read both the application and session variables. If you are changing application variables as in our example code, then you must use the argument's scope for that. <cffunction name="onSessionEnd" returnType="void" output="false"> <cfargument name="SessionScope" type="struct" required="true"> <cfargument name="ApplicationScope" type="struct" required="false"> <cfscript> // NOTE: You must use the variable scope below to access the // application structure inside this method. arguments.ApplicationScope._stat.sessions -= 1; </cfscript></cffunction> Application end method—onApplicationEnd This is our end method for applications. Here is where you can do the logging activity. As in the session method, you need to use the argument's scope in order to read variables for the application. It is also good to note that at this point, you can no longer access the session scope. <cffunction name="onApplicationEnd" returnType="void" output="false"> <cfargument name="applicationScope" required="true"></cffunction> On Error method—onError() The following code demonstrates how we can be flexible in managing errors sent to this method. If the error comes from Application.cfc, then the event (or method that had an issue) will be contained in the value of the arguments.eventname variable. Otherwise, it will be an empty string. In our code, we change the label on our dump statement, so that it is a bit more obvious where it was generated. <cffunction name="onError" returnType="void" output="true"> <cfargument name="exception" required="true"> <cfargument name="eventname" type="string" required="true"> <cfif arguments.eventName NEQ ""> <cfdump var="#arguments.exception#" label="Application core exception"> <cfelse> <cfdump var="#arguments.exception#" label="Application exception"> </cfif></cffunction>
Read more
  • 0
  • 0
  • 5086

article-image-integrating-silverlight-4-sharepoint-2010
Packt
27 Jul 2010
7 min read
Save for later

Integrating Silverlight 4 with SharePoint 2010

Packt
27 Jul 2010
7 min read
Understanding the benefits of integrating Silverlight with SharePoint The following list shows many benefits of integrating Silverlight with SharePoint 2010: Rich UX: Silverlight RIAs can offer a rich user experience. You can take full advantage of the rich visual capabilities offered by Silverlight and include them in a SharePoint site. The rich and interactive content offers an incredible new world of possibilities in SharePoint. For example, you can offer an interactive balanced scorecard with animated graphs, rich navigation capabilities, and context menus. Code runs on the client: You can take advantage of the power of the client computers accessing the SharePoint server. You can use threading and asynchronous calls to offer responsive user interfaces and to take advantage of modern multi-core microprocessors found in client computers. You can offer great response times without the need to wait for the server to load another page. You can take advantage of rich controls, animations, and exciting multimedia effects. The processing removes load from the server and enables you to use both the server and the client in your solutions. Additionally, Silverlight 4 is cross-browser capable and we can take advantage of the improved Out of Browser features to create applications that interact with the SharePoint 2010 server but run in the Windows desktop, out of the web browser. Efficient applications: As you can work with the power offered by the client, you can process data without the need to make requests to the server all the time. This way, you can create load-balanced solutions. Access to the Client OM (Client Object Model): When you have to access data and services offered by the SharePoint 2010 server, you don't need to create your own complex infrastructure. There is no need to add additional layers. You can take advantage of the new Client Object Model, also known as Client OM. As you can work with asynchronous calls to the Client OM, you can still offer great responsive applications when consuming services from the server. Users can interact with SharePoint data without requiring server calls as they would from traditional pages. Lots of the processing can be pushed down to the client. This way, as previously explained, you can remove load from the SharePoint server and create load-balanced solutions. Leverage your existing Silverlight knowledge, components, and applications: You can build new capabilities quickly from existing Silverlight components and applications, integrating them with SharePoint 2010.   Creating a SharePoint solution   Now, when we design a new SharePoint 2010 solution, we will be able to consider Silverlight RIAs as new components for the global solution. We have to consider the aforementioned benefits of integrating Silverlight with SharePoint and decide which parts would be convenient to create as Silverlight RIAs. This way, we can focus on preparing the SharePoint 2010 infrastructure and then we can access data and services offered by the server through Silverlight RIAs. For example, you can view the images found in an assets library defined in SharePoint through a Silverlight application. Once you start integrating Silverlight with SharePoint, you will find a new exciting way of enhancing SharePoint solutions. Preparing the development environment We want to take full advantage of modern technologies. First of all, we must install the latest tools and begin working on configurations. Later, we will be able to use our existing knowledge to create different kinds of RIAs for SharePoint 2010, using Silverlight 4—the newest kid-on-the-block from Microsoft. Silverlight 4 is backward-compatible with its previous version, Silverlight 3. Therefore, when an example uses a feature found only in Silverlight 4, you will find a note explaining this situation. Most of the examples work for both Silverlight versions. However, we will also take advantage of some of the new features found in Silverlight 4. The only requirements underpinning the development and integration of RIAs into SharePoint 2010 sites are understanding the basics of the C# programming language, ASP.NET, XAML code, and the Visual Studio IDE. We will cover any other requirements in our journey through the creation of many different kinds of RIAs to run in a SharePoint 2010 site. First, we must download and install various Silverlight development tools. We need Visual C# 2010 Professional, Premium, or Ultimate installed, in order to successfully complete the installations explained in the following section. Visual C# 2010 allows us to choose the desired Silverlight version (for example, version 3 or version 4). The following part will show Visual Studio 2010 Ultimate screenshots. If you use other versions, some elements that appear in the screenshots could be different but the steps are all valid for the aforementioned versions. Setting up the development environment Follow these steps to prepare the development environment: Download the following files: Application's name Download link File name Description Silverlight 4 Tools for Visual Studio 2010 http://www.microsoft.com/downloads/details.aspx?FamilyID=eff8a0da-0a4d-48e8-8366-6ddf2ecad801&displaylang=en Silverlight4_Tools.exe We must install Silverlight 4 Tools in order to create Silverlight 4 applications in the Visual Studio 2010 IDE, using XAML and C#. It will co-exist with previous Silverlight SDKs (Software Development Kits). This new version of Silverlight Tools also includes the WCF RIA Services package. Silverlight 4 Offline Documentation (in CHM format) http://www.microsoft.com/downloads/details.aspx?familyid=B6127B9B-968C-46C2-8CB6-D228E017AD74&displaylang=en Silverlight_Documentation.EXE We must download and run this file to decompress its content because, because we will need access to Silverlight 4 official documentation in due course. Expression Blend for .NET 4 http://www.microsoft.com/downloads/details.aspx?FamilyID=88484825-1b3c-4e8c-8b14-b05d025e1541&displaylang=en Blend_Trial_en.exe This tool will enable us to create content that targets Silverlight 4 and to create rapid prototypes with the SketchFlow tool. Silverlight Toolkit (Updated for Silverlight 4 compatibility) http://codeplex.com/Silverlight Silverlight_4_Toolkit_April_2010.msi It is convenient to download the latest stable release. This toolkit provides a nice collection of Silverlight controls, components, and utilities made available outside the normal Silverlight release cycle. It will be really helpful to use these controls to provide even more attractive user interfaces. Besides, it includes more Silverlight themes. Run the installers in the same order in which they appear in the above table and follow the steps to complete the installation wizards. Once the installations have successfully finished, run Visual Studio 2010 or Visual Web Developer 2010 (or later). Select File | New | Project... or press Ctrl+Shift+N. Select Visual C# | Silverlight under Installed Templates in the New Project dialog box. You will see many Silverlight templates, including Silverlight Business Application and WCF RIA Services Class Library, as shown in the following screenshot: Discovering the rich controls offered by the Silverlight Toolkit Silverlight Toolkit is a Microsoft project offering many rich controls, components, and utilities that can help us to enhance our Silverlight UI (User Interface). As we want to create a very attractive UI for SharePoint, it is convenient to get familiar with its features. Follows these steps to see the controls in action and to change the values for many of their properties. Select Start | All Programs | Microsoft Silverlight 4 Toolkit April 2010 | Toolkit Samples and your default web browser will display a web page with a Silverlight application displaying a list of the controls organized in ten categories as follows: Controls Data DataForm Data Input DataVisualization Input Layout Navigation Theming Toolkit By default, the default.htm web page is located at C:Program Files (x86)Microsoft SDKsSilverlightv4.0ToolkitApr10Samples in 64-bit Windows versions. Click on a control name under the desired category and the right panel will display the control with different values assigned for its properties, creating diverse instances of the control. For example, the following screenshot shows many instances of the Rating control under the Input category. Click on the buttons shown at the bottom of the web page and you will be able to see both the XAML and the C# code used to create the sample for the control. For example, the following screenshot shows the XAML code for the DataGrid control example, DataGridSample.xaml. You can also click on DataGridSample.xaml.cs and check the C# part. This control appears under the Data category.
Read more
  • 0
  • 0
  • 1607
article-image-flash-10-multiplayer-game-lobby-and-new-game-screen-implementation
Packt
27 Jul 2010
5 min read
Save for later

Flash 10 Multiplayer Game: The Lobby and New Game Screen Implementation

Packt
27 Jul 2010
5 min read
(For more resources on Flash and Games, see here.) The lobby screen implementation In this section, we will learn how to implement the room display within the lobby. Lobby screen in Hello World Upon login, the first thing the player needs to do is enter the lobby. Once the player has logged into the server successfully, the default behavior of the PulseGame in PulseUI is to call enterLobby API. The following is the implementation within PulseGame: protected function postInit():void { m_netClient.enterLobby();} Once the player has successfully entered the lobby, the client will start listening to all the room updates that happen in the lobby. These updates include any newly created room, any updates to the room objects, for example, any changes to the player count of a game room, host change, etc. Customizing lobby screen In the PulseUI, the lobby screen is the immediate screen that gets displayed after a successful login. The lobby screen is drawn over whatever the outline object has drawn onto the screen. The following is added to the screen when the lobby screen is shown to the player: Search lobby UI Available game rooms Game room scroll buttons Buttons for creating a new game room Navigation buttons to top ten and register screens When the lobby is called to hide, the lobby UI elements are taken off the screen to make way for the incoming screen. For our initial game prototype, we don't need to make any changes. The PulseUI framework already offers all of the essential set of functionalities of a lobby for any kind of multiplayer game. However, the one place you may want to add more details is in what gets display for each room within the lobby. Customizing game room display The room display is controlled by the class RoomsDisplay, an instance of which is contained in GameLobbyScreen. The RoomsDisplay contains a number of RoomDisplay object instances, one for each room being displayed. In order to modify what gets displayed in each room display, we do it inside of the class that is subclassed from RoomDisplay. The following figure shows the containment of the Pulse layer classes and shows what we need to subclass in order to modify the room display: In all cases, we would subclass (MyGame) the PulseGame. In order to have our own subclass of lobby screen, we first need to create class (MyGameLobbyScreen) inherited from GameLobbyScreen. In addition, we also need to override the method initLobbyScreen as shown below: protected override function initLobbyScreen():void { m_gameLobbyScreen = new MyGameLobbyScreen();} In order to provide our own RoomsDisplay, we need to create a subclass (MyRoomsDisplay) inherited from RoomsDisplay class and we need to override the method where it creates the RoomsDisplay in GameLobbyScreen as shown below: protected function createRoomsDisplay():void { m_roomsDisplay = new MyRoomsDisplay();} Finally, we do similar subclassing for MyRoomDisplay and override the method that creates the RoomDisplay in MyRoomsDisplay as follows: protected override function createRoomDisplay (room:GameRoomClient):RoomDisplay { return new MyRoomDisplay(room);} Now that we have hooked up to create our own implementation of RoomDisplay, we are free to add any additional information we like. In order to add additional sprites, we now simply need to override the init method of GameRoom and provide our additional sprites. Filtering rooms to display The choice is up to the game developer to either display all the rooms currently created or just the ones that are available to join. We may override the method shouldShowRoom method in the subclass of RoomsDisplay (MyRoomsDisplay) to change the default behavior. The default behavior is to show rooms that are only available to join as well as rooms that allow players to join even after the game has started. Following is the default method implementation: protected function shouldShowRoom(room:GameRoomClient):Boolean { var show:Boolean; show = (room.getRoomType() == GameConstants.ROOM_ALLOW_POST_START); if(show == true) return true; else { return (room.getRoomStatus() == GameConstants.ROOM_STATE_WAITING); }} Lobby and room-related API Upon successful logging, all game implementation must call the enterLobby method. public function enterLobby(gameLobbyId:String = "DefaultLobby"):void You may pass a null string in case you only wish to have one default lobby. The following notification will be received again by the client whether the request to enter a lobby was successful or not. At this point, the game screen should switch to the lobby screen. function onEnteredLobby(error:int):void If entering a lobby was successful, then the client will start to receive a bunch of onNewGameRoom notifications, one for each room that was found active in the entered lobby. The implementation should draw the corresponding game room with the details on the lobby screen. function onNewGameRoom(room:GameRoomClient):void The client may also receive other lobby-related notifications such as onUpdateGameRoom for any room updates and onRemoveGameRoom for any room objects that no longer exist in lobby. function onUpdateGameRoom(room:GameRoomClient):voidfunction onRemoveGameRoom(room:GameRoomClient):void If the player wishes to join an existing game room in the lobby, you simply call joinGameRoom and pass the corresponding room object. public function joinGameRoom(gameRoom:GameRoomClient):void In response to a join request, the server notifies the requesting client of whether the action was successful or failed via the game client callback method. function onJoinedGameRoom(gameRoomId:int, error:int):void A player already in a game room may leave the room and go back to the lobby, by calling the following API: public function leaveGameRoom():void Note that if the player successfully left the room, the calling game client will receive the notification via the following callback API: function onLeaveGameRoom(error:int):void
Read more
  • 0
  • 0
  • 4931

article-image-solving-lua-problems-avecto-privilege-guard
Packt
27 Jul 2010
3 min read
Save for later

Solving LUA Problems with Avecto Privilege Guard

Packt
27 Jul 2010
3 min read
(For more resources on Microsoft products, see here.) Configuring applications to run with elevated privileges on-the-fly Despite all the possible workarounds to launch an application or set of commands with elevated privileges from a standard user account, Windows doesn't provide any built-in means of allowing system administrators to configure a particular application to launch as the currently logged in standard user, but with an administrative token. Consider a situation where you don't have time to fix an application that won't run as a standard user, but don't want to grant administrative privileges just for the sake of one application. While it may be possible to start the application using a secondary logon, this is impractical in most cases. Solving LUA problems with Avecto Privilege Guard Privilege Guard is a third-party solution, from Microsoft Gold Partner Avecto, that allows system administrators to dynamically add or remove privileges by modifying the logged in user's access token as it's assigned to new processes. The client-side component, provided as an .exe or .msi file for GPSI deployment, is implemented as a user-mode service and supports Windows XP (or Windows Server 2003) and later. Privilege Guard is licensed on a trust model, so it doesn't adhere to a strict object count in Active Directory. Client settings are deployed with User or Computer Group Policy using a flexible architecture that separates policies, applications, messaging and access tokens. Programs can also be grouped together to minimize the number of policies applied. Defining application groups For each Application Group, you can define one or more programs using the following categories: Executables Control Panel Applets Management Console snap-ins Windows Installer Packages Windows Scripting Host (WSH), PowerShell scripts and batch files Registry Editor files ActiveX controls (matched by URL or CLSID) Application Templates can also be used to quickly locate built-in Windows tools such as Performance Monitor or System Restore. In the screenshot that follows, I used an Application Template to locate the Disk Management console (diskmgmt.msc) in Windows 7. The default setting is to match processes by file or folder name, but processes can also be matched by command line switch, file hash, publisher or any combination thereof. Privilege Guard supports matching by publisher certificate when Windows binaries are indirectly signed using Windows Security Catalogs. Additional options include: The ability to match processes if Privilege Guard detects that an application will trigger UAC. To determine whether child processes spawned by the matched parent process inherit the privileges of the user's modified access token. To suppress elevated privileges on File Open/Save common dialogs to prevent users from modifying protected files. Defining access tokens We can define the rights allotted to access tokens in Privilege Guard based on the privileges assigned to Windows built-in groups. Rights can also be added or removed on an individual basis. The access token below uses the built-in Administrators group as the basis for assigning privileges. An access token's integrity level can also be overridden. Any combination of groups, privileges or integrity levels can be added or removed in an access token.
Read more
  • 0
  • 0
  • 4030
Modal Close icon
Modal Close icon