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 - Programming

1081 Articles
article-image-thread-executors
Packt
31 Dec 2012
7 min read
Save for later

Thread Executors

Packt
31 Dec 2012
7 min read
(For more resources related to this topic, see here.) Creating a thread executor The first step to work with the Executor framework is to create an object of the ThreadPoolExecutor class. You can use the four constructors provided by that class or use a factory class named Executors that creates ThreadPoolExecutor. Once you have an executor, you can send Runnable or Callable objects to be executed. In this recipe, you will learn how these two operations implement an example that will simulate a web server processing requests from various clients. Getting ready You can compare both mechanisms and select the best one depending on the problem. The example of this recipe has been implemented using the Eclipse IDE. If you use Eclipse or other IDE such as NetBeans, open it and create a new Java project. How to do it... Follow these steps to implement the example: First, you have to implement the tasks that will be executed by the server. Create a class named Task that implements the Runnable interface. public class Task implements Runnable { Declare a Date attribute named initDate to store the creation date of the task and a String attribute named name to store the name of the task. private Date initDate; private String name; Implement the constructor of the class that initializes both attributes. public Task(String name){ initDate=new Date(); this.name=name; } Implement the run() method. @Override public void run() { First, write to the console the initDate attribute and the actual date, which is the starting date of the task. System.out.printf("%s: Task %s: Created on: %sn",Thread. currentThread().getName(),name,initDate); System.out.printf("%s: Task %s: Started on: %sn",Thread. currentThread().getName(),name,new Date()); Then, put the task to sleep for a random period of time. try { Long duration=(long)(Math.random()*10); System.out.printf("%s: Task %s: Doing a task during %d secondsn",Thread.currentThread().getName(),name,duration); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } Finally, write to the console the completion date of the task. System.out.printf("%s: Task %s: Finished on: %sn",Thread. currentThread().getName(),name,new Date()); Now, implement the Server class that will execute every task it receives using an executor. Create a class named Server. public class Server { Declare a ThreadPoolExecutor attribute named executor. private ThreadPoolExecutor executor; Implement the constructor of the class that initializes the ThreadPoolExecutor object using the Executors class. public Server(){ executor=(ThreadPoolExecutor)Executors.newCachedThreadPool(); } Implement the executeTask() method. It receives a Task object as a parameter and sends it to the executor. First, write a message to the console indicating that a new task has arrived. public void executeTask(Task task){ System.out.printf("Server: A new task has arrivedn"); Then, call the execute() method of the executor to send it the task. executor.execute(task); Finally, write some executor data to the console to see its status. System.out.printf("Server: Pool Size: %dn",executor. getPoolSize()); System.out.printf("Server: Active Count: %dn",executor. getActiveCount()); System.out.printf("Server: Completed Tasks: %dn",executor. getCompletedTaskCount()); Implement the endServer() method. In this method, call the shutdown() method of the executor to finish its execution. public void endServer() { executor.shutdown(); } Finally, implement the main class of the example by creating a class named Main and implement the main() method. public class Main { public static void main(String[] args) { Server server=new Server(); for (int i=0; i<100; i++){ Task task=new Task("Task "+i); server.executeTask(task); } server.endServer(); } } How it works... The key of this example is the Server class. This class creates and uses ThreadPoolExecutor to execute tasks. The first important point is the creation of ThreadPoolExecutor in the constructor of the Server class. The ThreadPoolExecutor class has four different constructors but, due to their complexity, the Java concurrency API provides the Executors class to construct executors and other related objects. Although we can create ThreadPoolExecutor directly using one of its constructors, it's recommended to use the Executors class. In this case, you have created a cached thread pool using the newCachedThreadPool() method. This method returns an ExecutorService object, so it's been cast to ThreadPoolExecutor to have access to all its methods. The cached thread pool you have created creates new threads if needed to execute the new tasks, and reuses the existing ones if they have finished the execution of the task they were running, which are now available. The reutilization of threads has the advantage that it reduces the time taken for thread creation. The cached thread pool has, however, a disadvantage of constant lying threads for new tasks, so if you send too many tasks to this executor, you can overload the system. Use the executor created by the newCachedThreadPool() method only when you have a reasonable number of threads or when they have a short duration. Once you have created the executor, you can send tasks of the Runnable or Callable type for execution using the execute() method. In this case, you send objects of the Task class that implements the Runnable interface. You also have printed some log messages with information about the executor. Specifcally, you have used the following methods: getPoolSize(): This method returns the actual number of threads in the pool of the executor getActiveCount(): This m ethod returns the number of threads that are executing tasks in the executor getCompletedTaskCount(): This method returns the number of tasks completed by the executor One critical aspect of the ThreadPoolExecutor class, and of the executors in general, is that you have to end it explicitly. If you don't do this, the executor will continue its execution and the program won't end. If the executor doesn't have tasks to execute, it continues waiting for new tasks and it doesn't end its execution. A Java application won't end until all its non-daemon threads finish their execution, so, if you don't terminate the executor, your application will never end. To indicate to the executor that you want to finish it, you can use the shutdown() method of the ThreadPoolExecutor class. When the executor finishes the execution of all pending tasks, it finishes its execution. After you call the shutdown() method, if you try to send another task to the executor, it will be rejected and the executor will throw a RejectedExecutionException exception. The following screenshot shows part of one execution of this example: When the last task arrives to the server, the executor has a pool of 100 tasks and 97 active threads. There's more... The ThreadPoolExecutor class provides a lot of methods to obtain information about its status. We used in the example the getPoolSize(), getActiveCount(), and getCompletedTaskCount() methods to obtain information about the size of the pool, the number of threads, and the number of completed tasks of the executor. You can also use the getLargestPoolSize() method that returns the maximum number of threads that has been in the pool at a time. The ThreadPoolExecutor class also provides other methods related with the finalization of the executor. These methods are: shutdownNow(): This method shut downs the executor immediately. It doesn't execute the pending tasks. It returns a list with all these pending tasks. The tasks that are running when you call this method continue with their execution, but the method doesn't wait for their finalization. isTerminated(): This m ethod returns true if you have called the shutdown() or shutdownNow() methods and the executor finishes the process of shutting it down. isShutdown(): This method returns true if you have called the shutdown() method of the executor. awaitTermination(long timeout, TimeUnit unit): This m ethod blocks the calling thread until the tasks of the executor have ended or the timeout occurs. The TimeUnit class is an enumeration with the following constants: DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, and SECONDS. If you want to wait for the completion of the tasks, regardless of their duration, use a big timeout, for example, DAYS.
Read more
  • 0
  • 0
  • 1637

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-all-about-protocol
Packt
22 Nov 2016
19 min read
Save for later

All About the Protocol

Packt
22 Nov 2016
19 min read
In this article, Jon Hoffman, the author of the book Swift 3 Protocol Oriented Programming - Second Edition, talks about coming from an object-oriented background, I am very familiar with protocols (or interfaces, as they are known in other object-oriented languages). However, prior to Apple introducing protocol-oriented programming, protocols, or interfaces, were rarely the focal point of my application designs, unless I was working with an Open Service Gateway Initiative (OSGi) based project. When I designed an application in an object-oriented way, I always began the design with the objects. The protocols or interfaces were then used where they were appropriate, mainly for polymorphism when a class hierarchy did not make sense. Now, all that has changed, and with protocol-oriented programming, the protocol has been elevated to the focal point of our application design. (For more resources related to this topic, see here.) In this article you will learn the following: How to define property and method requirements within a protocol How to use protocol inheritance and composition How to use a protocol as a type What polymorphism is When we are designing an application in an object-oriented way, we begin the design by focusing on the objects and how they interact. The object is a data structure that contains information about the attributes of the object in the form of properties, and the actions performed by or to the object in the form of methods. We cannot create an object without a blueprint that tells the application what attributes and actions to expect from the object. In most object-oriented languages, this blueprint comes in the form of a class. A class is a construct that allows us to encapsulate the properties and actions of an object into a single type. Most object-oriented programming languages contain an interface type. This interface is a type that contains method and property signatures, but does not contain any implementation details. An interface can be considered a contract where any type that conforms to the interface must implement the required functionality defined within it. Interfaces in most object-oriented languages are primarily used as a way to achieve polymorphism. There are some frameworks, such as OSGi, that use interfaces extensively; however, in most object-oriented designs, the interface takes a back seat to the class and class hierarchy. Designing an application in a protocol-oriented way is significantly different from designing it in an object-oriented way. As we stated earlier, object-oriented design begins with the objects and the interaction between the objects, while protocol-oriented design begins with the protocol. While protocol-oriented design is about so much more than just the protocol, we can think of the protocol as the backbone of protocol-oriented programming. After all, it would be pretty hard to have protocol-oriented programming without the protocol. A protocol in Swift is similar to interfaces in object-oriented languages, where the protocol acts as a contract that defines the methods, properties, and other requirements needed by our types to perform their tasks. We say that the protocol acts as a contract because any type that adopts, or conforms, to the protocol promises to implement the requirements defined by the protocol. Any class, structure, or enumeration can conform to a protocol. A type cannot conform to a protocol unless it implements all required functionality defined within the protocol. If a type adopts a protocol and it does not implement all functionality defined by the protocol, we will get a compile time error and the project will not compile. Most modern object-oriented programming languages implement their standard library with a class hierarchy; however, the basis of Swift's standard library is the protocol (https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/SwiftStandardLibraryReference/index.html). Therefore, not only does Apple recommend that we use the protocol-oriented programming paradigm in our applications, but they also use it in the Swift standard library. With the protocol being the basis of the Swift standard library and also the backbone of the protocol-oriented programming paradigm, it is very important that we fully understand what the protocol is and how we can use it. In this article, we will go over the basic usage of the protocol, which will include the syntax for defining the protocol, how to define requirements in a protocol, and how to make our types conform to a given protocol. Protocol syntax In this section, we will look at how to define a protocol, define requirements within a protocol, and specify that a type conforms to a protocol. Defining a protocol The syntax we use to define a protocol is very similar to the syntax used to define a class, structure, or enumeration. The following example shows the syntax used to define a protocol: protocol MyProtocol { //protocol definition here } To define the protocol, we use the protocol keyword followed by the name of the protocol. We then put the requirements, which our protocol defines, between curly brackets. Custom types can state that they conform to a particular protocol by placing the name of the protocol after the type's name, separated by a colon. The following example shows how we would state that the MyStruct structure conforms to the MyProtocol protocol: struct MyStruct: MyProtocol { //structure implementation here } A type can also conform to multiple protocols. We list the multiple protocols that the type conforms to by separating them with commas. The following example shows how we would specify that the MyStruct structure type conforms to the MyProtocol, AnotherProtocol, and ThirdProtocol protocols: struct MyStruct: MyProtocol, AnotherProtocol, ThirdProtocol { // Structure implementation here } Having a type conform to multiple protocols is a very important concept within protocol-oriented programming, as we will see later in the article. This concept is known as protocol composition. Now let's see how we would add property requirements to our protocol. Property requirements A protocol can require that the conforming types provide certain properties with specified names and types. The protocol does not say whether the property should be a stored or computed property because the implementation details are left up to the conforming types. When defining a property within a protocol, we must specify whether the property is a read-only or a read-write property by using the get and set keywords. We also need to specify the property's type since we cannot use the type inference in a protocol. Let's look at how we would define properties within a protocol by creating a protocol named FullName, as shown in the next example: protocol FullName { var firstName: String {get set} var lastName: String {get set} } In the FullName protocol, we define two properties named firstName and lastName. Both of these properties are defined as read-write properties. Any type that conforms to the FullName protocol must implement these properties. If we wanted to define the property as read-only, we would define it using only the get keyword, as shown in the following code: var readOnly: String {get} If the property is going to be a type property, then we must define it in the protocol. A type property is defined using the static keyword, as shown in the following example: static var typeProperty: String {get} Now let's see how we would add method requirements to our protocol. Method requirements A protocol can require that the conforming types provide specific methods. These methods are defined within the protocol exactly as we define them within a class or structure, but without the curly brackets and method body. We can define these methods as instance or type methods using the static keyword. Adding default values to the method's parameters is not allowed when defining the method withina protocol. Let's add a method named getFullName() to our FullName protocol: protocol FullName { var firstName: String {get set} var lastName: String {get set} func getFullName() -> String } Our fullName protocol now requires one method named getFullName() and two read-write properties named firstName and lastName. For value types, such as the structure, if we intend for a method to modify the instances that it belongs to, we must prefix the method definition with the mutating keyword. This keyword indicates that the method is allowed to modify the instance it belongs to. The following example shows how to use the mutating keyword with a method definition: mutating func changeName() If we mark a method requirement as mutating, we do not need to write the mutating keyword for that method when we adopt the protocol with a reference (class) type. The mutating keyword is only used with value (structures or enumerations) types. Optional requirements There are times when we want protocols to define optional requirements—that is, methods or properties that are not required to be implemented. To use optional requirements, we need to start off by marking the protocol with the @objc attribute. It is important to note that only classes can adopt protocols that use the @objc attribute. Structures and enumerations cannot adopt these protocols. To mark a property or method as optional, we use the optional keyword. Let's look at how we would use the optional keyword to define optional properties and methods: @objc protocol Phone { var phoneNumber: String {get set} @objc optional var emailAddress: String {get set} func dialNumber() @objc optional func getEmail() } In the Phone protocol we just created, we define a required property named phoneNumber and an optional property named emailAddress. We also defined a required function named dialNumber() and an optional function named getEmail(). Now let's explore how protocol inheritance works. Protocol inheritance Protocols can inherit requirements from one or more other protocols and then add additional requirements. The following code shows the syntax for protocol inheritance: protocol ProtocolThree: ProtocolOne, ProtocolTwo { // Add requirements here } The syntax for protocol inheritance is very similar to class inheritance in Swift, except that we are able to inherit from more than one protocol. Let's see how protocol inheritance works. We will use the FullName protocol that we defined earlier in this section and create a new protocol named Person: protocol Person: FullName { var age: Int {get set} } Now, when we create a type that conforms to the Person protocol, we must implement the requirements defined in the Person protocol, as well as the requirements defined in the FullName protocol. As an example, we could define a Student structure that conforms to the Person protocol as shown in the following code: struct Student: Person { var firstName = "" var lastName = "" var age = 0 func getFullName() -> String { return "(firstName) (lastName)" } } Note that in the Student structure we implemented the requirements defined in both the FullName and Person protocols; however, the only protocol specified when we defined the Student structure was the Person protocol. We only needed to list the Person protocol because it inherited all of the requirements from the FullName protocol. Now let's look at a very important concept in the protocol-oriented programming paradigm: protocol composition. Protocol composition Protocol composition lets our types adopt multiple protocols. This is a major advantage that we get when we use protocols rather than a class hierarchy because classes, in Swift and other single-inheritance languages, can only inherit from one superclass. The syntax for protocol composition is the same as the protocol inheritance that we just saw. The following example shows how to do protocol composition: struct MyStruct: ProtocolOne, ProtocolTwo, Protocolthree { // implementation here } Protocol composition allows us to break our requirements into many smaller components rather than inheriting all requirements from a single superclass or class hierarchy. This allows our type families to grow in width rather than height, which means we avoid creating bloated types that contain requirements that are not needed. Protocol composition may seem like a very simple concept, but it is a concept that is essential to protocol-oriented programming. Let's look at an example of protocol composition so we can see the advantage we get from using it. Let's say that we have the class hierarchy shown in the following diagram: In this class hierarchy, we have a base class named Athlete. The Athlete base class then has two subclasses named Amateur and Pro. These classes are used depending on whether the athlete is an amateur athlete or a pro athlete. An amateur athlete may be a colligate athlete, and we would need to store information such as which school they go to and their GPA. A pro athlete is one that gets paid for playing the game. For the pro athletes, we would need to store information such as what team they play for and their salary. In this example, things get a little messy under the Amateur and Pro classes. As we can see, we have a separate football player class under both the Amateur and Pro classes (the AmFootballPlayer and ProFootballPlayer classes). We also have a separate baseball class under both the Amateur and Pro classes (the AmBaseballPlayer and ProBaseballPlayer classes). This will require us to have a lot of duplicate code between theses classes. With protocol composition, instead of having a class hierarchy where our subclasses inherit all functionality from a single superclass, we have a collection of protocols that we can mix and match in our types. We then use one or more of these protocols as needed for our types. For example, we can create an AmFootballPlayer structure that conforms to the Athlete, Amateur, and Footballplayer protocols. We could also create the ProFootballPlayer structure that conforms to the Athlete, Pro, and Footballplayer protocols. This allows us to be very specific about the requirements for our types and only adopt the requirements that we need. From a pure protocol point of view, this last example may not make a lot of sense right now because protocols only define the requirements. One word of warning: If you find yourself creating numerous protocols that only contain one or two requirements in them, then you are probably making your protocols too granular. This will lead to a design that is hard to maintain and manage. Now let's look at how a protocol is a full-fledged type in Swift. Using protocols as a type Even though no functionality is implemented in a protocol, they are still considered a full-fledged type in the Swift programming language, and can mostly be used like any other type. What this means is that we can use protocols as parameters or return types for a function. We can also use them as the type for variables, constants, and collections. Let's take a look at some examples. For these next few examples, we will use the following PersonProtocol protocol: protocol PersonProtocol { var firstName: String {get set} var lastName: String {get set} var birthDate: Date {get set} var profession: String {get} init (firstName: String, lastName: String, birthDate: Date) } In this PersonProtocol, we define four properties and one initializer. For this first example, we will show how to use a protocol as a parameter and return type for a function, method, or initializer. Within the function itself, we also use the PersonProtocol as the type for a variable: func updatePerson(person: PersonProtocol) -> PersonProtocol { var newPerson: PersonProtocol // Code to update person goes here return newPerson } We can also use protocols as the type to store in a collection, as shown in the next example: var personArray = [PersonProtocol]() var personDict = [String: PersonProtocol]() The one thing we cannot do with protocols is create an instance of one. This is because no functionality is implemented within a protocol. As an example, if we tried to create an instance of the PersonProtocol protocol, as shown in the following example, we would receive the error error: protocol type 'PersonProtocol' cannot be instantiated: var test = PersonProtocol(firstName: "Jon", lastName: "Hoffman", ?birthDate: bDateProgrammer) We can use the instance of any type that conforms to our protocol anywhere that the protocol type is required. As an example, if we define a variable to be of the PersonProtocol protocol type, we can then populate that variable with the instance of any type that conforms to the PersonProtocol protocol. Let's assume that we have two types named SwiftProgrammer and FootballPlayer that conform to the PersonProtocol protocol. We can then use them as shown in this next example: var myPerson: PersonProtocol myPerson = SwiftProgrammer(firstName: "Jon", lastName: "Hoffman", birthDate: bDateProgrammer) myPerson = FootballPlayer(firstName: "Dan", lastName: "Marino", ?birthDate: bDatePlayer) In this example, the myPerson variable is defined to be of the PersonProtocol protocol type. We can then set this variable to instances of either of the SwiftProgrammer and FootballPlayer types. One thing to note is that Swift does not care if the instance is a class, structure, or enumeration. It only matters that the type conforms to the PersonProtocol protocol type. As we saw earlier, we can use our PersonProtocol protocol as the type for an array, which means that we can populate the array with instances of any type that conforms to the PersonProtocol protocol. The following is an example of this (note that the bDateProgrammer and bDatePlayer variables are instances of the Date type that would represent the birthdate of the individual): var programmer = SwiftProgrammer(firstName: "Jon", lastName: "Hoffman", birthDate: bDateProgrammer) var player = FootballPlayer(firstName: "Dan", lastName: "Marino", birthDate: bDatePlayer) var people: [PersonProtocol] = [] people.append(programmer) people.append(player) What we are seeing in these last couple of examples is a form of polymorphism. To use protocols to their fullest potential, we need to understand what polymorphism is. Polymorphism with protocols The word polymorphism comes from the Greek roots poly (meaning many) and morphe (meaning form). In programming languages, polymorphism is a single interface to multiple types (many forms). There are two reasons to learn the meaning of the word polymorphism. The first reason is that using such a fancy word can make you sound very intelligent in casual conversion. The second reason is that polymorphism provides one of the most useful programming techniques not only in object-oriented programming, but also protocol-oriented programming. Polymorphism lets us interact with multiple types though a single uniform interface. In the object-oriented programming world the single uniform interface usually comes from a superclass, while in the protocol-oriented programming world that single interface usually comes from a protocol. In the last section, we saw two examples of polymorphism with Swift. The first example was the following code: var myPerson: PersonProtocol myPerson = SwiftProgrammer(firstName: "Jon", lastName: "Hoffman", birthDate: bDateProgrammer) myPerson = FootballPlayer(firstName: "Dan", lastName: "Marino", birthDate: bDatePlayer) In this example, we had a single variable of the PersonProtocol type. Polymorphism allowed us to set the variable to instances of any type that conforms to the PersonProtocol protocol, such as the SwiftProgrammer or FootballPlayer types. The other example of polymorphism was in the following code: var programmer = SwiftProgrammer(firstName: "Jon", lastName: "Hoffman", birthDate: bDateProgrammer) var player = FootballPlayer(firstName: "Dan", lastName: "Marino", birthDate: bDatePlayer) var people: [PersonProtocol] = [] people.append(programmer) people.append(player) In this example, we created an array of PersonProtocol types. Polymorphism allowed us to add instances of any types that conform to PersonProtocol to this array. When we access an instance of a type though a single uniform interface, as we just showed, we are unable to access type-specific functionality. As an example, if we had a property in the FootballPlayer type that records the age of the player, we would be unable to access that property because it is not defined in the PeopleProtocol protocol. If we do need to access type-specific functionality, we can use type casting. Type casting with protocols Type casting is a way to check the type of an instance and/or to treat the instance as a specified type. In Swift, we use the is keyword to check whether an instance is of a specific type and the as keyword to treat an instance as a specific type. The following example shows how we would use the is keyword: if person is SwiftProgrammer { print("(person.firstName) is a Swift Programmer") } In this example, the conditional statement returns true if the person instance is of the SwiftProgrammer type or false if it isn't. We can also use the switch statement (as shown in the next example) if we want to check for multiple types: for person in people { switch (person) { case is SwiftProgrammer: print("(person.firstName) is a Swift Programmer") case is FootballPlayer: print("(person.firstName) is a Football Player") default: print("(person.firstName) is an unknown type") } } We can use the where statement in combination with the is keyword to filter an array to only return instances of a specific type. In the next example, we filter an array that contains instances of the PersonProtocol to only return those elements of the array that are instances of the SwiftProgrammer type: for person in people where person is SwiftProgrammer { print("(person.firstName) is a Swift Programmer") } Now let's look at how we would cast an instance to a specific type. To do this, we can use the as keyword. Since the cast can fail if the instance is not of the specified type, the as keyword comes in two forms: as? and as!. With the as? form, if the casting fails it returns a nil; with the as! form, if the casting fails we get a runtime error. Therefore, it is recommended to use the as? form unless we are absolutely sure of the instance type or we perform a check of the instance type prior to doing the cast. The following example shows how we would use the as? keyword to attempt to cast an instance of a variable to the SwiftProgammer type: if let p = person as? SwiftProgrammer { print("(person.firstName) is a Swift Programmer") } Since the as? keyword returns an optional, in the last example we could use optional binding to perform the cast. If we are sure of the instance type, we can use the as! keyword as shown in the next example: for person in people where person is SwiftProgrammer { let p = person as! SwiftProgrammer } Summary While protocol-oriented programming is about so much more than just the protocol, it would be impossible to have the protocol-oriented programming paradigm without the protocol. We can think of the protocol as the backbone of protocol-oriented programming. Therefore, it is important to fully understand the protocol in order to properly implement protocol-oriented programming. Resources for Article: Further resources on this subject: Using Protocols and Protocol Extensions [Article] What we can learn from attacks on the WEP Protocol [Article] Hosting the service in IIS using the TCP protocol [Article]
Read more
  • 0
  • 0
  • 1635

article-image-using-reactivecocoa-4-style
Packt
13 Jan 2016
5 min read
Save for later

Using the ReactiveCocoa 4 Style

Packt
13 Jan 2016
5 min read
In this article by Cecil Costa, author of Reactive Programming with Swift, we will cover the following topics: Setting up a project Developing a currency class (For more resources related to this topic, see here.) The first version of ReactiveCocoa for Swift was 3.0; however, it worked like the Objective-C way of programming, except for some operators and some other stuff. For this reason, the ReactiveCocoa team decided to create another version, quickly taking the advantages of the new features of Swift 2. Setting up the project Open Xcode and create a new project called Chapter 6 Shop Cart; ensure that Swift is the main programming language. Install the ReactiveCocoa using your favorite method; just ensure that version 4 is installed. For example, if you use CocoaPods, make sure that you have specified version 4. Once you have set up the project, go to the storyboard. Here, we will start by adding a layout where the user can see the whole supermarket catalog on a table view, the Total label in the bottom-left corner, and a Checkout button in the bottom-right corner. Of course, a label with a screen title would be fine to make it more visible to the user. In short, you can have a simple layout, as shown in the following screenshot: Now we have to think about how to display the products. Here, we have to display a picture, its price, description, a label with the quantity that was added to the shopping cart, button to add one unit of the product, and a button to remove it. To do it, just add a Table View cell on the only table we have on the screen. Place an image view on the cell, three labels (one for the product name, the other for its price, and the third for the quantity in the basket), and two buttons. Set the buttons' image to minus and plus images. The final cell layout will look similar to what is shown in the following screenshot. Feel free to change this layout if you are a creative person. Using the Assistant Editor, connect the table view, the Total label, and the Checkout button with their corresponding property in the ViewController class:    @IBOutlet weak var catalogTableView: UITableView!     @IBOutlet weak var totalLabel: UILabel!     @IBOutlet weak var checkoutButton: UIButton! Finally, let's create a class for the table view cell that we have created. Add a new file to your project called ProductCell.swift. Import UIKit, and create an empty class that inherits from UITableViewCell using the following code: import UIKit class ProductCell:UITableViewCell { } Return to the storyboard, select Table View Cell, go to its Identity Inspector with command+option+3, and change its class to ProductCell, as is demonstrated in this screenshot: Now, with command+option+4, we can go to Attribute Inspector, and change the cell identifier to productcell: Open the Assistant Editor, and connect the UI cell components with their corresponding attributes: @IBOutlet weak var nameLabel:UILabel!     @IBOutlet weak var priceLabel:UILabel!     @IBOutlet weak var productImage:UIImageView!     @IBOutlet weak var addButton:UIButton!     @IBOutlet weak var removeButton:UIButton!     @IBOutlet weak var numberOfItemsLabel:UILabel! Great, the basic setup for the first screen is done. Now, let's start implementing our shopping cart. Developing the Currency class In this app, a currency is an important class. The output on the screen will change according to the user's currency. The only stored properties we will need is the name, which is a three letter code, such as USD for US Dollar and GBP for Great Britain Pounds, and its rate according to the base currency. As mentioned in the beginning of this article, the base currency will be GBP; however, you can easily change it if you like by changing the setting of the static attribute, called baseCurrency. The final code for this class is as simple as this one: class Currency:NSObject{     var name:String     var rate:Double         static var baseCurrency:Currency = {         return Currency(name:"GBP", rate: 1.0)     }()         init(name: String, rate:Double){         self.name = name         self.rate = rate     } } Why does this class inherit from NSObject? The reason for this is that objects of the Currency type can only be marked as dynamic if they are Object-C ready; to do it, you just need to inherit from NSObject. Summary To summarize this article, we covered the basic steps to set up our project. We installed ReactiveCocoa and added a layout to our project. We also developed our dynamic Currency class, which inherits from NSObject. Resources for Article:   Further resources on this subject: Exploring Swift [article] The Swift Programming Language [article] Sprites, Camera, Actions! [article]
Read more
  • 0
  • 0
  • 1632

article-image-rules-and-events
Packt
12 Jul 2013
10 min read
Save for later

Rules and Events

Packt
12 Jul 2013
10 min read
(For more resources related to this topic, see here.) Handling specifc events is something everybody expects from an application. While JavaScript has its own event handling model, working with Dynamics CRM offers a different set of events that we can take advantage of. The JavaScript event model, while it might work, is not supported, and defnitely not the approach you want to take when working within the context of Dynamics CRM. Some of the most notable events and their counterparts in JavaScript are described in the following table: Dynamics CRM 2011 JavaScript Description OnLoad onload This is a form event. Executes when a form is loaded. Most common use is to filter and hide elements on the form. OnSave onsubmit This is a form event. It executes when a form is saved. Most common use is to stop an operation from executing, as a result of a failed validation procedure. TabStateChange n/a This is a form event. It executes when the DisplayState of the tab changes. OnChange onchange This is a field specific event. It executes when tabbing out of a field where you've changed the value. Please note that there is no equivalent for onfocus and onblur. OnReadyStateComplete n/a This event indicates that the content of an IFrame has completed loading. Additional details on Dynamics CRM 2011 specifc events can be found on MSDN at http://msdn.microsoft.com/en-us/library/gg334481.aspx. Form load event usage In this recipe, we will focus on executing a few operations triggered by the form load event. We can check the value of a specifc field on the form, and based on that we can decide to hide a tab, hide a field, and prepopulate a text field with a predefned value. Getting ready... Just as with any of the previous recipes, you will need access to an environment, and permissions to make customizations. You should be a system administrator, a system customizer, or a custom role configured to allow you to perform the following operations. How to do it... For the purpose of this exercise, we will add to the Contact entity a new tab called "Special Customer", with some additional custom fields. We will also add an option set that we will check to determine if we hide or not the fields, as well as two new fields: one text field and one lookup field. So let's get started! Open the contact's main form for editing. Add a new tab by going to Insert | Tab | One Column. Double-click on the newly added tab to open the Tab Properties window. Change the Label field of the tab to Special Customer. Make sure the show label is expanded by default and visible checkboxes are checked. Click on OK. Add a few additional text fields on this tab. We will be hiding the tab along with the content within the tab. Add a new field, named Is Special Customer (new_IsSpecialCustomer). Leave the default yes/no values. Add the newly created field to the general form for the contact. Add another new text field, named Customer Classifcation (new_ CustomerClassifcation). Leave the Format as Text, and the default Maximum Length to 100, as shown in the following screenshot: Add the newly created text field to the general form, under the previously added field. Add a new lookup field, called Partner (new_Partner). Make it a lookup for a contact, as shown in the following screenshot: Add this new field to the general form, under the other two fields. Save and Publish the Contact form. Your form should look similar to the following screenshot: Observe the fact that I have ordered the three fields one on top of the other. The reason for this is because the default tab order in CRM is vertical and across. This way, when all the fields are visible, I can tab right from one to another. In your solution where you made the previous changes, add a new web resource named FormLoader (new_FormLoader). Set the Type to JScript. Click on the Text Editor button and insert the following function: function IsSpecialCustomer(){var _isSpecialSelection = null;var _isSpecial = Xrm.Page.getAttribute("new_isspecialcustomer");if(_isSpecial != null){_isSpecialSelection = _isSpecial.getValue();}if(_isSpecialSelection == false){// hide the Special Customer tabXrm.Page.ui.tabs.get("tab_5").setVisible(false);// hide the Customer Classification fieldXrm.Page.ui.controls.get("new_customerclassification").setVisible(false);// hide the Partner fieldXrm.Page.ui.controls.get("new_partner").setVisible(false);}} Save and Publish the web resource. Go back to the Contact form, and on the ribbon select Form Properties. On the Events tab, add the library created as web resource in the Forms Libraries section, and in the Event Handlers area, on the Form OnLoad add the function we created: Click on the Text Editor button and insert the following function: Click on OK, then click on Save andPublish the form Test your configuration by opening a new contact, setting the Is Special Customer field to No. Save and close the contact. Open it again, and the tab and fields should be hidden. How it works... The whole idea of this script is not much different from what we have demonstrated in some of the previous recipes. Based on a set form value, we hide a tab and some fields. Where we capture the difference is where we set the script to execute. Working with scripts executing when the form loads gives us a whole new way of handling various scenarios. There's more... In many scenarios, working with the form load events in conjunction with the other field events can potentially result in a very complex solution. When debugging, always pay close attention to the type of event you associate your script function with. See also See the Combining events recipe towards the end of this article for a more complex recipe detailing how to work with multiple events to achieve the expected result. Form save event usage While working with the Form OnLoad event can help us format and arrange the user interface, working with the Form OnSave opens up a new door towards validation of user input and execution of business process amongst others. Getting ready Using the same solution we have worked on in the previous recipe, we will continue to demonstrate a few other aspects of working with the forms in Dynamics CRM 2011. In this recipe the focus is on the handling the Form OnSave event. How to do it... First off, in order to kick off this, we might want to verify a set of fields for a condition, or perform a calculation based on a formula. In order to simplify this process, we can just check a simple yes/no condition on a form. How it works... Using the previously customized solution, we will be taking advantage of the Contact entity and the fields that we have already customized on that form. If you are starting with this recipe fresh, take the following step before delving into this recipe: Add a new two-options field, named Is Special Customer (new_IsSpecialCustomer). Leave the default yes/no values. Using this field, if the answer is No, we will stop the save process. In your solution add a new web resource. I have named it new_ch4rcp2. Set its type to JScript. Enter the following function in your resource: function StopSave(context){var _isSpecialSelection = null;var _isSpecial = Xrm.Page.getAttribute("new_isspecialcustomer");if(_isSpecial != null){_isSpecialSelection = _isSpecial.getValue();}if(_isSpecialSelection == false){alert("You cannot save your record while the Customer is not afriend!");context.getEventArgs().preventDefault();}} The function basically checks for the value in our Is Special Customer. If a value is retrieved, and that value is No, we can bring up an alert and stop the Save and Close event. Now, back on to the contact's main form, we attach this new function to the form's OnSave event. Save and Publish your solution. In order to test this functionality, we will create a new contact, populate all the required fields, and set the Is Special Customer field to No. Now try to click on Save and Close. You will get an alert as seen in the following screenshot, and the form will not close nor be saved. Changing the Is Special Customer selection to Yes and saving the form will now save and close the form. There's more... While this recipe only describes in a very simplistic manner the way to stop a form from saving and closing, the possibilities here are immense. Think about what you can do on form save, and what you can achieve if a condition should be met in order to allow the form to be saved. Starting a process instead of saving the form Another good use for blocking the save and close form is to take a different path. Let's say we want to kick off a workfow when we block the save form. We can call from the previous function a new function as follows: function launchWorkflow(dialogID, typeName, recordId){var serverUri = Mscrm.CrmUri.create('/cs/dialog/rundialog.aspx');window.showModalDialog(serverUri + '?DialogId=' + dialogID +'&EntityName=' + typeName +'&ObjectId=' + recordId, null, 'width=615,height=480,resizable=1,status=1,scrollbars=1');// Reload formwindow.location.reload(true);} We pass to this function the following three parameters: GUID of the Workfow or Dialog The type name of the entity The ID of the record See also For more details on parameters see the following article on MSDN: http://msdn.microsoft.com/en-us/library/gg309332.aspx Field change event usage In this recipe we will drill down to a lower level. We have handled form events, and now it is time to handle field events. The following recipe will show you how to bring all these together and achieve exactly the result you need. Getting ready For the purpose of this recipe, let's focus on reusing the previous solution. We will check the value of a field, and act upon it. How to do it... In order to walkthrough this recipe, follow these steps:> Create a new form field called new_changeevent, with a label of Change Event, and a Type of Two Options. Leave the default values of No and Yes. Leave the Default Value as No. Add this field to your main Contact form. Add the following script to a new JScript web resource: function ChangeEvent(){var _changeEventSelection = null;var _isChanged = Xrm.Page.getAttribute("new_changeevent");if(_isChanged != null){_changeEventSelection = _isChanged.getValue();}if(_changeEventSelection == true){alert("Change event is set to True");// perform other actions here}else{alert("Change event is set to False");}} This function, as seen in the previous recipes, checks the value of the Two Options field, and performs and action based on the user selection. The action in this example is simply bringing an alert message up. Add the new web resource to the form libraries. Associate this new function to the OnChange event of the field we have just created. Save and Publish your solution. Create a new contact, and try changing the Change Event value from No to Yes and back. Every time the selection is changed, a different message comes up in the alert. How it works... Handling events at the field level, specifcally the OnSave event, allows us to dynamically execute various other functions. We can easily take advantage of this functionality to modify the form displayed to a user dynamically, based on a selection. Based on a field value, we can defne areas or field on the form to be hidden and shown.
Read more
  • 0
  • 0
  • 1629

article-image-grunt-action
Packt
20 Jan 2014
5 min read
Save for later

Grunt in Action

Packt
20 Jan 2014
5 min read
(For more resources related to this topic, see here.) Step 4 – optimizing our build files At this point, we should have a structured set of source files and can now perform additional transformations on the result. Let's start by downloading the plugins from npm and saving them in our package.json file: $ npm install --save-dev grunt-contrib-uglify grunt-contrib-cssmin grunt-contrib-htmlmin Then, at the top of our Gruntfile.js file, where we have loaded our other Grunt plugins, we will load our new additions with: grunt.loadNpmTasks("grunt-contrib-uglify"); grunt.loadNpmTasks("grunt-contrib-cssmin"); grunt.loadNpmTasks("grunt-contrib-htmlmin"); Scripts We will start by compressing our scripts. In this example, we use the grunt-contrib-uglify plugin http://gswg.io#grunt-contrib-uglify), which is a wrapper around the popular UglifyJS library (http://gswg.io#uglifyjs). Now we have loaded the plugin, which provides the uglify task, we just need to configure it: uglify: { compress: { src: "<%= coffee.build.dest %>", dest: "<%= coffee.build.dest %>" } } Here, inside the uglify property, we have made a compress target, which has src and dest set to the same file. Instead of entering the actual filename, we are making use of Grunt templates to retrieve the value at the given configuration path (coffee.build.dest), which in this case, resolves to build/js/app.js. Grunt templates make it easy to have a single source of truth within our configuration. Therefore, if we ever want to change the file path of our JavaScript, we only need to change one configuration entry. Since we have set the source and destination to the same file path, in effect, we are overwriting our JavaScript with the compressed version of itself. However, if we were writing a JavaScript library instead of a web application, we'd most likely want to compress our app.js file into an app.min.js file, so its users could download an uncompressed and a compressed version. Running this uglify task with this basic configuration should result in the following app.js file: (function(){var a,b;a=function(a,b){return a+b},b=function(a,b){return a-b},alert(a(7,b(4,1)))}).call(this); Generally, this will suffice, however, UglifyJS also offers advanced features. For example, in some cases, we might have portions of code that are only used during development. We could remove this unnecessary code with the following technique. By defining a DEBUG variable and place our debug-related code inside an if block as follows: if(DEBUG) { //do things here } Then, if we used the following options object inside our uglify configuration as follows: options: { compress: { global_defs: { "DEBUG": false }, dead_code: true } } This would result in UglifyJS locking the value of DEBUG to false and also to remove the inaccessible code (dead code). Therefore, in addition to compressing code, we also have the ability to completely remove code from our builds. The documentation for this feature can be found at http://gswg.io#grunt-contrib-uglify-conditional-compilation. Styles To compress our styles, we use the grunt-contrib-cssmin plugin (http://gswg.io#grunt-contrib-cssmin), which is a wrapper around the clean-css library (http://gswg.io#clean-css). Since we have installed this plugin, we just need to include the cssmin task configuration: cssmin: { compress: { src: "<%= stylus.build.dest %>", dest: "<%= stylus.build.dest %>" } } Similar to our scripts configuration, we can see that the only real difference is that we point to the stylus task's output instead of pointing to the coffee task's output. When we run grunt cssmin, our css/app.css file should be modified to the following one: html,body{margin:0;padding:0}.content .middle{font-size:16pt}@media (max-width:768px){.content .middle{font-size:8pt}} Views Finally, to compress our views, we will use the grunt-contrib-htmlmin plugin (http://gswg.io#grunt-contrib-htmlmin), which is a wrapper around the html-minifier library (http://gswg.io#html-minifier). The htmlmin configuration has a little more to it: since its compression options are disabled by default, we need to enable the rules we wish to use: htmlmin: { options: { removeComments: true, collapseWhitespace: true, collapseBooleanAttributes: true, removeAttributeQuotes: true, removeRedundantAttributes: true, removeOptionalTags: true }, compress: { src: "<%= jade.build.dest %>", dest: "<%= jade.build.dest %>" } } Now our htmlmin task is configured, we can run it with grunt htmlmin, which should modify our build/app.html to the following: <!DOCTYPE html><html><head><link rel=stylesheet href=css/app. css><body><section class=header>this is the <b>amazing</b> header section</section><section class=content><div class=top>some content with this on top</div><div class=middle>and this in the middle</ div><div class=bottom>and this on the bottom</div></section><section class=footer>and this is the footer, with an awesome copyright symbol with the year next to it - © 2013</section><script src = js/app. js></script> In addition to the GitHub repository, we can read more about html-minifier on Juriy "Kangax" Zaytsev's blog at http://gswg.io#experimenting-with-html-minifier. Summary In this article we performed additional transformations on set of source files by using Grunt. Resources for Article: Further resources on this subject: Trapping Errors by Using Built-In Objects in JavaScript Testing [article] Developing Wiki Seek Widget Using Javascript [article] Working with JavaScript in Drupal 6: Part 1 [article]
Read more
  • 0
  • 0
  • 1623
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 R$50/month. Cancel anytime
article-image-service-oriented-java-business-integration-whats-whys
Packt
23 Oct 2009
4 min read
Save for later

Service Oriented Java Business Integration - What's & Why's

Packt
23 Oct 2009
4 min read
Many of you as (Java) programmers generate business purpose code, like "confirming an order" or "find available products". At times, you may also want to connect to external systems and services, since your application in isolation alone will not provide you the required functionality. When the number of such connections increases, you would be generating more and more of "integration code", mixed along with your business code. For single or simple systems and services this is fine, but what if your "Enterprise" has got many (say 100? or even more...) such systems and services to be integrated together? Here, integration becomes a prime concern, which is separate from fulfilling your business concerns. In the SOA context, we will have services fulfilling your business use cases. Existing Java tools help us to define services. But are they enough to support Service Oriented Integration (SOI)? Perhaps not, and this is where JSR-208 (Java Specification Request) introduces the Java Business Integration (JBI) specification. And in the world of integration, we have multiple Architectures to follow including the Point-to-Point, Hub-and-Spoke, Message-Bus and the Service-Bus. Each of them have their own advantages and disadvantages, and the Enterprise Service Bus (ESB) is an Architectural pattern best suited for doing SOI. This book provides a consistent style and visual representations to describe the message flows in sample scenarios, which helps the reader to understand the code samples fully. This book also presents practical advice on designing code that connects services together, based again on practical experiences gathered over the last one decade in java business integration. I believes in "Practice What You Preach" and hence equips you with enough tools to "Practice What You Read". What does the book have to offer? or What does it teach? This book introduces ESB - The book guarantees you understand ESB and can also code for ESB. This book introduces JBI - The book don't reproduce specification, but give you just enough highlights alone. Teaches you ServiceMix - ServiceMix is an Apache Open source Java ESB. The book teach you from step 1 of installation Teaches you to implement practical scenarios - Proxies, Web Services gateway, web services over JMS, service versioning, etc. Implementation for EIP - Gives you code on how to implement Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf For more, have a glance through the Table of Contents [PDF] Who would benefit from it? Any Java/J2EE enthusiast, who wants to know something more than daily POJO, Spring & Hibernate Developers & Architects who deals with integration Developers & Architects who don't consciously deal with integration - its high time for you to seperate out spaghetti integration aspects from your business purpose code - for that, you need to first understand and sense integration! Even people with Non-Java background - My .NET peers, don't envy on the lightweight approaches described in this book using java tools. The integration is done mostly in XML configurations with minimum java code, and you too can benefit from the literature. Anything special about the book First book published on JBI First book published on Apache ServiceMix First book which shows you how to integrate following ESB, using lightweight tools. A book with code, which makes you feel running and seeing the code in action, even without actually running the code (nothing prevents you from trying the samples). You can go though a Sample Chapter here: JBI-Bind-Web-Services-in-ESB-Gateway.pdf [1 MB] No heavy Workshops, IDEs, Studios, Plugins or 4GB RAM required - Use a text editor and Apache Ant, and you can run the samples. Based on existing knowledge on web services Authored and reviewed by practicing Architects, who are developers too in their everyday role. What this book is not about? Not a collection of white papers alone - The book provide you implementation samples. Not a repetition of ServiceMix online documentation - The book provide practical scenarios as samples Not about JBI Service Provider Interface (SPI) - Hence this book is not for tool vendors, but for developers Fine, if you think you need some starters before the real chill, you can go through the article titled Aggregate Services in ServiceMix JBI ESB
Read more
  • 0
  • 0
  • 1622

article-image-liferay-portal-6pluggable-enterprise-search-and-plugin-management
Packt
17 May 2010
13 min read
Save for later

Liferay Portal 6:Pluggable Enterprise Search and Plugin Management

Packt
17 May 2010
13 min read
(Read more interesting articles on Liferay Portal 6 here.) Pluggable Enterprise Search As an alternative to using Lucene, the portal supports pluggable search engines. The first implementation of this uses the open source search engine Solr, but in the future, there will be many such plugins for search engine of your choice, such as FAST, GSA, Coveo, and so on. In this section, we're going to discuss caching, indexing, and using Solr for search Caching settings EHCache is a widely-used cache implemented in Java, which the portal uses to provide distributed caching in a clustered environment. EHCache is also used in a non-clustered environment to speed up repeated data retrievals. The portal uses EHCache caching by default. At the same time, the portal uses Hibernate caching as well. The portal provides the capability to confi gure EHCache caching and Hibernate caching. The portal has specified Hibernate as default ORM (Object-Relational Mapping) persistence in portal.properties. persistence.provider=hibernate The preceding code sets the provider hibernate used for ORM persistence. Of course, you can set this property to jpa (Java Persistence API), thus the properties with the prefi x jpa.* will be read. Similarly, if this property is set to hibernate, then the properties with the prefix hibernate.* will be read. Note that this property affects the loading of hibernate-spring.xml or jpa-spring.xml in the property spring.configs. For example, the portal has the following JPA configuration specified in portal.properties: jpa.configs=META-INF/mail-orm.xml,META-INF/portal-orm.xmljpa.provider=eclipselinkjpa.provider.property.eclipselink.allow-zero-id=truejpa.load.time.weaver=org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver As shown in the preceding code, the property jpa.configs sets a list of commadelimited JPA configurations. The default JPA provider is set as eclipselink via the property jpa.provider. You can set it to other values such as hibernate, openjpa, and toplink. The property jpa.provider.property.eclipselink. allow-zero-id specifies provider-specific properties prefixed with jpa.provider. property.*.On the other hand, LoadTimeWeaver interface specified via the property jpa.load.time.weaver is a Spring class that allows JPA ClassTransformer instances to be plugged in a specific manner depending on the environment. Note that not all JPA providers require a JVM agent. If your provider doesn't require an agent or you have other alternatives, the loadtime weaver shouldn't be used. Configure Hibernate caching First of all, let's consider Hibernate caching settings. The portal will automatically detect the Hibernate dialect. However, you can set the property in portal-ext.properties to manually override the automatically detected dialect. hibernate.dialect= The portal also specified the following properties related to Hibernate caching in portal.properties. hibernate.configs=//ignore detailsMETA-INF/ext-hbm.xmlhibernate.cache.provider_class=com.liferay.portal.dao.orm.hibernate.EhCacheProvidernet.sf.ehcache.configurationResourceName=/ehcache/hibernate.xmlhibernate.cache.use_query_cache=truehibernate.cache.use_second_level_cache=truehibernate.cache.use_minimal_puts=truehibernate.cache.use_structured_entries=falsehibernate.jdbc.batch_size=20hibernate.jdbc.use_scrollable_resultset=truehibernate.bytecode.use_reflection_optimizer=truehibernate.query.factory_class=org.hibernate.hql.classic.ClassicQueryTranslatorFactoryhibernate.generate_statistics=false As shown in the preceding code, the property hibernate.configs sets Hibernate configurations. You may input a list of comma-delimited Hibernate configurations in portal-ext.properties. The property hibernate.cache.provider_class sets the Hibernate cache provider. On the other hand, the property net.sf.ehcache.configurationResourceName is used if Hibernate is confi gured to use Ehcache's cache provider, where Ehcache is recommended in a clustered environment. In a clustered environment, you need to set the property in portal-ext.properties as follows: net.sf.ehcache.configurationResourceName=/ehcache/hibernate-clustered.xml The portal has specified other Hibernate cache settings with properties starting with hibernate.cache.use_*. The property hibernate.jdbc.batch_size sets the JDBC batch size to improve performance. Note that if you're using Hypersonic databases or Oracle 9i, you should set the batch size to 0 as a workaround for a logging bug in the Hypersonic database driver or Oracle 9i driver. In addition, the property hibernate.query.factory_class sets the classic query factory, whereas the portal sets the property hibernate.generate_statistics to false. Of course, you could set the property hibernate.generate_statistics to true to enable Hibernate cache monitoring in portal-ext.properties. Setting up EHCache caching The portal has specified the following EHCache caching settings in portal.properties ehcache.single.vm.config.location=/ehcache/liferay-single-vm.xmlehcache.multi.vm.config.location=/ehcache/liferay-multi-vm.xmlehcache.portal.cache.manager.jmx.enabled=trueehcache.blocking.cache.allowed=true As shown in the preceding code, the property ehcache.single.vm.config.location sets the classpath to the location of the Ehcache configuration file / ehcache/liferay-single-vm.xml for internal caches of a single VM, whereas the property ehcache.multi.vm.config.location sets the classpath to the location of the Ehcache configuration file /ehcache/liferay-multi-vm.xml for internal caches of multiple VMs. In a clustered environment, you need to set the following in ehcache.multi.vm.config.location=/ehcache/liferay-multi-vm-clustered.xml In addition, the portal sets the property ehcache.portal.cache.manager.jmx.enabled to true to enable JMX integration in com.liferay.portal.cache.EhcachePortalCacheManager. Moreover, the portal sets the property ehcache.blocking.cache.allowed to, true to allow Ehcache to use blocking caches. This improves performance signifi cantly by locking on keys instead of the entire cache. The drawback is that threads can hang if the cache isn't used properly. Therefore, make sure that all queries that return a miss also immediately populate the cache, or else other threads that are blocked on a query of that same key will continue to hang. Of course, you can override the preceding properties in portal-ext.properties. Customization As you can see, the property net.sf.ehcache.configurationResourceName can have the value /ehcache/hibernate.xml for a non-clustered environment and /ehcache/hibernate-clustered.xml for a clustered environment. The propertynet.sf.ehcache.configurationResourceName can have the value /ehcache/hibernate.xml for a non-clustered environment and /ehcache/hibernateclustered.xml for a clustered environment. In the same pattern, the property ehcache.single.vm.config.location can havethe value /ehcache/liferay-single-vm.xml and the property ehcache.multi.vm.config.location can have the value /ehcache/liferay-multi-vm.xml for a non-clustered environment. ehcache.multi.vm.config.location has a value /ehcache/liferay-multi-vmclustered.xml for a clustered environment. In real cases, you may need to update both Hibernate caching settings and Ehcache caching settings, either in a non-clustered environment or in a clustered environment. The following is an example of how to do this: Create a folder named ext-ehcache under the folder $PORTAL_ROOT_HOME/WEB-INF/classes/. Obviously, you can have different names for the folder ${ehcache.folder.name}. Here we use the folder ext-ehcache of ${ehcache.folder.name} as an example Locate the JAR file portal-impl.jarunder the folder $PORTAL_ROOT_HOME/WEB-INF/lib and unzip all the fi les under the folder ehcache into the folder $PORTAL_ROOT_HOME/WEB-INF/classes/ext-ehcache. Update following fi les according to your requirements for both a non-clustered environment and a clustered environment. hibernate.xmlhibernate-clustered.xmlliferay-single-vm.xmlliferay-multi-vm.xmlliferay-multi-vm-clustered.xml Set the following for a non-clustered environment in portal-ext.properties:net.sf.ehcache.configurationResourceName=/ext-ehcache/hibernate.xmlehcache.single.vm.config.location=/ext-ehcache/liferay-single-vm.xmlehcache.multi.vm.config.location=/ext-ehcache/liferay-multi-vm.xml Otherwise, set the following for a clustered environment in portal-ext.properties:net.sf.ehcache.configurationResourceName=/ext-ehcache/hibernateclustered.xmlehcache.multi.vm.config.location=/ext-ehcache/liferay-multi-vmclustered.xml That's it! You have customized both the both Hibernate caching settings and Ehcache caching settings   Indexing settings Search engine indexing collects, parses, and stores data to facilitate fast and accurate information retrieval. Apache Lucene is a high-performance, full-featured text search engine library written entirely in Java-based indexing. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform. Refer to http://lucene.apache.org for more information. By default, the portal uses Lucene search and indexing. Lucene search The portal sets the default Lucene index on start-up to false for faster performance, as follows,in portal.properties: index.read.only=falseindex.on.startup=falseindex.on.startup.delay=60index.with.thread=true As you can see, the portal sets the property index.read.only to false to allow any writes to the index. You should set it to true if you want to avoid any writes to the index. This is useful in some clustering environments where there is a shared index, and only one node of the cluster updates it. The portal sets the property index.on.startup to false in order to avoid indexing on every startup. You could set this property to true if you want to index your entire library of files on startup. This property is available so that automated test environments index the files on startup. Don't set this to true on production systems, or else your index data will be indexed on every startup. The property index.on.startup.delay adds a delay before indexing on startup. A delay may be necessary if a lot of plugins need to be loaded and re-indexed. Note that this property is only valid if the property index.on.startup is set to true. In addition, the portal sets the property index.with.thread to true to allow indexing on startup to be executed on a separate thread to speed up execution. Of course, you could re-index either all resources or an individual resource through web UI. For example, for re-indexing all search indexing, you can go to Control Panel | Server | Server Administration | Resources | Actions, and click on the button Execute next to the "Reindex all search indexes" option. Suppose that you're going to re-index individual resource like Users, you can use the Plugin Installation portlet in the Control Panel. Go to Control Panel | Server | Plugin Installation | Portlet Plugins, and click on the button Reindex next to the portlet Users. Index storage Lucene stores could be in the filesystem, the database, or in RAM. Anyway, the portal provides a set of properties to configure index storage as follows in portal.properties. lucene.store.type=filelucene.store.jdbc.auto.clean.up=falselucene.store.jdbc.dialect.*lucene.dir=${liferay.home}/data/lucene/lucene.file.extractor=com.liferay.portal.search.lucene.LuceneFileExtractorlucene.file.extractor.regexp.strip=lucene.analyzer=org.apache.lucene.analysis.standard.StandardAnalyzerlucene.commit.batch.size=0lucene.commit.time.interval=0lucene.buffer.size=16lucene.merge.factor=10lucene.optimize.interval=100 As shown in the preceding code, the property lucene.store.type designates whether Lucene stores indexes in a database via JDBC, filesystem, or in RAM. The default setting is filesystem. When using Lucene's storage of indexes via JDBC, temporary files don't get removed properly. This can eat up disk space over time. Thus set the property lucene.store.jdbc.auto.clean.up to true to automatically clean up the temporary files once a day. The property lucene.store.jdbc.dialect.* sets the JDBC dialect so that Lucene can use it to store indexes in the database. This property is referenced only when Lucene stores indexes in the database. The portal will attempt to load the proper dialect based on the URL of the JDBC connection. The property lucene.dir sets the directory where Lucene indexes are stored. This is referenced only when Lucene stores indexes in the filesystem. In a clustered environment, you could point the property lucene.dir to a shared folder, which is accessible for all nodes. More interestingly, you could set one node to allow any writes to the indexes via the property index.read.only and set the rest of nodes to allow read only. The property lucene.file.extractor specifies a class, called by Lucene to extract text from complex fi les so that they can be properly indexed. The file extractor can sometimes return text that isn't valid for Lucene. The property lucene.file. extractor.regexp.strip expects a regular expression. Any character that doesn't match the regular expression will be replaced with a blank space. You can set an empty regular expression to disable this feature. The property lucene.analyzer sets the default analyzer used for indexing and retrieval. In addition, the property lucene.commit.batch.size sets how often index updates will be committed. Set the batch size to confi gure how many consecutive updates will trigger a commit. If the value is 0, then the index will be committed on every update. The property lucene.commit.time.interval sets the time interval in milliseconds to confi gure how often to commit the index. The time interval isn't read unless the batch size is greater than 0 because the time interval works in conjunction with the batch size to guarantee that the index is committed after a specifi ed time interval. The portal sets the time interval to 0 to disable committing the index by a time interval. The property lucene.buffer.size sets Lucene's buffer size in megabytes and the property lucene.merge.factor sets Lucene's merge factor. For both of these properties, higher numbers mean that indexing goes faster but uses more memory. The default value from Lucene is 10. Note that this should never be set to a number less than 2. The property lucene.optimize.interval sets how often to run Lucene's optimize method. Optimization speeds up searching but slows down writing. You can set this property to 0 to always optimize. Indexer framework As mentioned earlier, you could re-index either all resources or an individual resource through web UI. For example, you could re-index out-of-the-box portlets like Users (Portlet ID 125) and plugins like the Mail portlet. This is because, in $PORTAL_ROOT_HOME/WEB-INF/liferay-portlet.xml, the portlet Users (named as enterprise_admin_users) has specified the following line: <indexer-class>com.liferay.portlet.enterpriseadmin.util.UserIndexer</indexer-class> As shown in the preceding code, the indexer-class value, which is the specified indexer framework, must be a class that implements com.liferay.portal.kernel.search.Indexer and is called to create or update a search index for the portlet Users. Additionally, you could fi nd the indexer framework in out-of-the-box portlets such as Organizations (portlet ID 126, called enterprise_admin_organizations), Web Content (portlet ID 15), Image Gallery (Portlet ID 31), Document Library (Portlet ID 20), and so on. Similarly the indexer-class value, which is the specified indexer framework, is also available in plugins. For example, the portlet Mail has specifi ed the following line in $AS_WEB_APP_HOME/mail-portlet/WEB-INF/liferay-portlet.xml. <indexer-class>com.liferay.mail.search.Indexer</indexer-class> In the same pattern, you may add the indexer framework in other plugins, like the Knowledge base portlet KBIndexer, which supports keyword search against titles, descriptions, content, tags, categories and category hierarchy, and "San Francisco" as oneword, and 'San Francisco' as multiple words ("San" or "Francisco") at http://liferay.cignex.com/palm_tree/book/0387/chapter11/knowledge-base-portlet-6.0.0.1.war
Read more
  • 0
  • 0
  • 1621

article-image-building-data-driven-application
Packt
06 Feb 2017
8 min read
Save for later

Building Data Driven Application

Packt
06 Feb 2017
8 min read
In this article by Ashish Srivastav the authors of the book ServiceNow Cookbook, we will learn following recipes: Starting a new application Getting into new modules (For more resources related to this topic, see here.) Service-Now provides a great platform to developers. Although it's a java-based application. Starting a new application Out of the box, Service-Now provides many applications for facilitating business operations and other activities in an IT environment, but if you find that the customer's requirements are not fitting into the system's applications boundaries then you can think of creating new applications. In these recipes, we will build a small application which will include table, form, business rules, client script, ACL, update sets, deployment, and so on. Getting ready To step through this recipe, you must have an active Service-Now instance, valid credentials, and an admin role. How to do it… Open any standard web browser and type the instance address. Log in to the Service-Now instance with the credentials. On the left-hand side in the search box, type local update and Service-Now will search the module for you: Local update set for a new application Now, you need to click on Local Update Sets to create a new update set so that you can capture all your configuration in the update set:   Create new update set On clicking, you need to give the name as Book registration application and click on the Submit and Make Current button:   Local update set – book registration application Now you will able to see the Book registration application update set next to your profile, which means you are ready to create a new application:   Current update set On the left-hand side in the search box, type system definition and click on the Application Menus module:   Application menu to create a new application To understand better, you can click on any application menu as shown here, where you can see the application and associated modules. For example, you can clicked on the self-service application as shown here:   Self-service application Now to see the associated modules, you need to scroll down as shown here, and if you want to create a new module then you need to click on the New button:   Self-service application's modules Now you should have a better understanding of how applications look within the Service-Now environment. So, to make a new application, you need to click on the New button on the Application Menus page:   Applications repository After clicking on the New button, you will able to see the configuration page. To understand better, let's consider this example. For instance, you are creating a Book Registration application for your customer, with the following configuration: Title: Book Registration Role: Leave blank Application: Global Active: True Category: Custom Applications (You can change it as per your requirement)   Book registration configuration Click on the Submit button. After sometime, a new Book Registration application menu will be visible under the application menu:   Book registration Getting into new modules A module is a part of an application which contains actually workable items. As a developer, you will always have an option to add a new module to support business requirements. Getting ready To step through this recipe, you should have an active Service-Now instance, valid credentials, and an admin role. How to do it… Open any standard web browser and type the instance address. Log into the Service-Now instance with the credentials. Service-Now gives you many options to create a new module. You can create a new module from the Application Menu module or you can go through the Table & Column module as well. If you have chosen to create a new module from the Application Menu module, then in order to create the module, click on the Book Registration application menu and scroll down. To create a new module, click on the New button:   Creating a New Module After clicking on the New button, you will able to see a configuration screen, where you need configure the following fields: Title: Author Registration Application Menu: Book Registration   The Author Registration module registration under the Book Registration menu Now in the Link Type section, you will need to configure the new module, rather I would say, you will need to define the base line regarding what your new module will do? Whether the new module will show a form to create a record or it will show a list of reports from a table or it will execute some the reports? That's why this is a critical step:   Link type to create a new module and select a table Link type gives you many options to decide the behavior of the new module.   Link type options Now, let's take a different approach to create a new module: On the left-hand side, type column and Service-Now will search the Tables & Columns module for you. Click on the Tables & Columns module:   The Tables & Columns module Now you will able to see the configuration page as shown here, where you need to click on the Create Table button. Note that by clicking on Create Table, you can create a new table:   Tables & Columns – Create a new table After clicking on the Create Table button, you will able to see the configuration page as given here, where you need to configure the following fields: Label: Author Registration (Module name) Name: Auto populate Extends table: Task (By extends, your module will incorporate all fields of the base table, in this scenario, Task table)   Module Configuration Create module: To create a new module through table, check the Create module check box, and to add a module under your application, you will need to select the application name:   Add module in application Controls is a critical section as out of the box, Service-Now gives an option to auto create number. For incident, INC is the prefix or for change ticker CHG is the prefix; here you are also allowed to create your prefix for a new module record:   Configure the new module Controls section Now you will able to auto number the configuration, as shown here; your new records will start with the AUT prefix:   New module auto numbering Click on Submit. After submission of the form, Service-Now will create a role automatically for the new module, as shown here. Only the u_author_registration_user role holder will able to view the module. So whenever a request is generated, you will need to go into that particular user's profile from the user administration module, to add a role:   Role created for module Your module is created, but there are no fields. So for rapid development, you can directly add a column to the table by clicking on Insert a new row...:   The Insert field in the form As an output, you will able to see that a new Author Registrations module is added under the Book Registration application:   Search newly created module Now if you click on the Author Registrations module, you will be able to see the following page:   The Author Registration Page On clicking the New button, you will be able to see the form as shown here. Note that you have not added any field on the u_author_registration table, but the table extends to the TASK table. That's why you are able to see fields on the form, but they are coming through the TASK table:   Author registration form without new fields If you want to add new fields to the form, then you can do so by performing the following steps: Right-click on banner. Select Configure. Click on Form Layout. Now in the Create new field section, you can enter the desired field Name and Type, as shown here: Form Fields Field Type Author Name String Author Primary Email Address String Author Secondary Email Address String Author Mobile Number String Author Permanent Address String Author Temporary Address String Country India USA UK Australia Author Experience String Book Type Choice Book Title String Contract Start Date String Contract End Date String Author registration form fields Click on Add and Save. After saving the form, new fields are added to the Author Registration form:   Author registration form To create a new form section in the form view and section, click on the New option and add the name:   Create a new section After creating the new Payment Details section, you can add fields under this section: Form Fields Field Type Country String Preferred Payment Currency Currency Bank Name String Branch Name String IFSC Code String Bank Address String Payment Details section fields As an output, you will able to see the following screen:   Author registration Payment Details form section Summary In this article we have learned how Service-Now provides a great platform to developers and also starting a new application, and getting into new modules. Resources for Article: Further resources on this subject: Client and Server Applications [article] Modules and Templates [article] My First Puppet Module [article]
Read more
  • 0
  • 0
  • 1610

article-image-creating-data-forms-silverlight-4
Packt
23 Apr 2010
4 min read
Save for later

Creating Data Forms in Silverlight 4

Packt
23 Apr 2010
4 min read
Collecting data Now that we have created a business object and a WCF service here-http://www.packtpub.com/article/creating-wcf-service-business-object-data-submission-silverlight, we are ready to collect data from the customer through our Silverlight application. Silverlight provides all of the standard input controls that .NET developers have come to know with Windows and ASP.NET development, and of course the controls are customizable through styles. Time for action – creating a form to collect data We will begin by creating a form in Silverlight for collecting the data from the client. We are going to include a submission form to collect the name, phone number, email address, and the date of event for the person submitting the sketch. This will allow the client (Cake O Rama) to contact this individual and follow up on a potential sale. We'll change the layout of MainPage.xaml to include a form for user input. We will need to open the CakeORama project in Expression Blend and then open MainPage.xaml for editing in the Blend art board. Our Ink capture controls are contained within a Grid, so we will just add a column to the Grid and place our input form right next to the Ink surface. To add columns in Blend, select the Grid from the Objects and Timeline panel, position your mouse in the highlighted area above the Grid and click to add a column: Blend will add a <Grid.ColumnDefinitions> node to our XAML: <Grid.ColumnDefinitions><ColumnDefinition Width="0.94*"/><ColumnDefinition Width="0.06*"/></Grid.ColumnDefinitions> Blend also added a Grid.ColumnSpan="2" attribute to both the StackPanel and InkPresenter controls that were already on the page. We need to modify the StackPanel and inkPresenter, so that they do not span both columns and thereby forcing us to increase the size of our second column. In Blend, select the StackPanel from the Objects and Timeline panel: In the Properties panel, you will see a property called ColumnSpan with a value of 2. Change this value to 1 and press the Enter key. We can see that Blend moved the StackPanel into the first column, and we now have a little space next to the buttons. We need to do the same thing to the inkPresenter control, so that it is also within the first column. Select the inkPresenter control from the Objects and Timeline panel: Change the ColumnSpan from 2 to 1 to reposition the inkPresenter into the left column: The inkPresenter control should be positioned in the left column and aligned with the StackPanel containing our ink sketch buttons: Now that we have moved the existing controls into the first column, we will change the size of the second column, so that we can start adding our input controls. We also need to change the overall size of the MainPage.xaml control to fit more information on the right side of the ink control. Click on the [UserControl] in the Objects and Timeline panel, and then in the Properties panel change the Width to 800: Now we need to change the size of our grid columns. We can do this very easily in XAML, so switch to the XAML view in Blend by clicking on the XAML icon: In the XAML view, change the grid column settings to give both columns an equal width: <Grid.ColumnDefinitions><ColumnDefinition Width="0.5*"/><ColumnDefinition Width="0.5*"/></Grid.ColumnDefinitions> Switch back to the design view by clicking on the design button: Our StackPanel and inkPresenter controls are now positioned to the left of the page and we have some empty space to the right for our input controls: Select the LayoutRoot control in the Objects and Timeline panel and then doubleclick on the TextBlock control in the Blend toolbox to add a new TextBlock control: Drag the control to the top and right side of the page: On the Properties panel, change the Text of the TextBlock to Customer Information, change the FontSize to 12pt and click on the Bold indicator:
Read more
  • 0
  • 0
  • 1609
article-image-creating-sample-project
Packt
06 Aug 2013
6 min read
Save for later

Creating a sample project

Packt
06 Aug 2013
6 min read
(For more resources related to this topic, see here.) In this article, we will create a sample project based on a transit system. We will use AutoMapper to help us transform our domain objects to ViewModel objects that we will use in the presentation layer. Before we begin, we need to explain the business overview of our domain objects used in the transit system. There are four main domain objects that we will work with. TransitStop will be the main entry point to our system; this represents a bus stop in the real world. The TransitStop domain object provides a commuter GeoLocation to give the latitude and longitude of the location, which would allow a commuter to easily locate nearby bus stops in a map if they desire to. A commuter can also use its UniqueNumber to find out when the next bus will be arriving at the bus stop. Each TransitStop has a UniqueNumber identifier so that a commuter can easily locate the stop without a GPS device. From there, we have the Transit object, which represents the vehicle that will be arriving at the stop. There could be multiples vehicles arriving, and everyone has an arrival time object representing the arrival time of the bus/transit to the stop for the commuter to go from one destination to the other. The following screenshot shows us the overall model: Step 1 – defining the ViewModel object Our first view model that we will define and use in our presentation layer will be the BusStopViewModel object, which will be mapped from TransitStop. The following screenshot represents the same: The preceding screenshot shows the class diagram of our BusStopViewModel and TransitStop domain objects. The code for the same is defined as follows: public class BusStopViewModel { public string Name { get; set; } public GeoLocationViewModel Location { get; set; } public int TransitStopNumber { get; set; } } Compare that to our domain object, as in the following code: public class TransitStop { public string StationName { get; set; } public int UniqueNumber { get; set; } public GeoLocation Location { get; set; } public IEnumerable<Transit> Buses { get; set; } public string GetName() { return string.Format("{0} - {1}", UniqueNumber, StationName); } } Our ViewModel object will most likely have a different structure than our domain object, since there are properties or data that do not pertain to the presentation layer but are required for our domain object. Note that the naming convention in BusStopViewModel is mostly identical; in doing so, we will have AutoMapper automatically map the data for us. Step 2 – creating the mapping In our mapping code, we will use a repository to get the data. Our repository will be an in-memory data that we generate; however, in real-world situations, one would use a WCF web service, WebApi, SQL, or a NoSQL solution as in the following code: public class TransitStopRepository { private readonly IList<TransitStop> _data = new List<TransitStop>(); /// <summary> /// Initializes a new instance of the <see cref="DataRepository"/> class. /// </summary> public TransitStopRepository() { Populate(); } /// <summary> /// Populates this instance. /// </summary> private void Populate() { var transitStop = new TransitStop { StationName = "Tsim Sha Tsui", UniqueNumber = 123, Location = new GeoLocation(114.171575, 22.293314), Buses = GenerateTSTBuses() }; _data.Add(transitStop); } We are using an IList that contains all our transit data. The Populate method populates the list with all the information needed. It acts like a database containing all the TransitStop information. The following code interprets the same: /// <summary> /// Generates the TST KMB buses. /// </summary> /// <returns></returns> private IEnumerable<Transit> GenerateTSTBuses() { var buses = new List<Transit> { new Transit { Number = "23A", ArrivalTimes = GenerateTimeTable(DateTime.Now), TransitColor = "Green" }, new Transit { Number = "23B", ArrivalTimes = GenerateTimeTable(DateTime.Now), TransitColor = "Yellow" } }; return buses; } We use the GenerateTSTBuses method to generate two transit routes that will be arriving at the transit stop. It will also generate a timetable for the transits arriving at the transit stop for our in-memory database so that our domain objects will be fully populated when we send a query to them, as in the following code: /// <summary> /// Generates a timetable with 2 minute apart arrival time. /// </summary> /// <param name="from">From.</param> /// <param name="incrementMinutes">The incrementMinutes.</param> /// <returns></returns> private IEnumerable<ArrivalTime> GenerateTimeTable(DateTime from) { //create a list var list = new List<ArrivalTime>(); var everyXminute = 2; //we will always generate 10 transits arriving to the stop for(var i = 0; i < 10; i++) { var arrivalTime = new ArrivalTime { Arrival = from.AddMinutes(everyXminutes) }; //double it for next everyXminutes *= 2; list.Add(arrivalTime); } return list; } The GenerateTimeTable method generates the ArrivalTime object of the transit acting as a timetable for buses; we have hardcoded it to ten transits for our in-memory database, each arriving at an increment of 2 minutes apart. Now that our repository has data fully populated, we can now use our repository to get fully populated domain objects. The following example uses the GetByUniqueNumber method to get a TransitStop object from the repository: public static BusStopViewModel GetTransitStop(int uniqueNumber) { var repo = new TransitStopRepository(); var tStop = repo.GetByUniqueNumber(uniqueNumber); //create the map from -> to object AutoMapper.Mapper.CreateMap<TransitStop, BusStopViewModel>(); We then create the declaration of our mapping of the domain object to ViewModel by calling CreateMap, where AutoMapper will automatically map the objects that have the same naming convention. The step of creating a map is essential to AutoMapper your doing so tells AutoMapper what to map and what not to map. Step 3 – mapping the object The mapping is done by calling the Map method in AutoMapper and passing the data to map from. In the preceding example, the tStop variable contains data that we will be passing into for AutoMapper. By calling the Map method, we are essentially requesting AutoMapper to create another object based on the data we have provided, as illustrated in the following code: //map the object var result = AutoMapper.Mapper.Map<TransitStop, BusStopViewModel>(tStop); return result; } In the preceding code, we are requesting AutoMapper to map the TransitStop object into BusStopViewModel object. Step 4 – not mapping certain data Let's assume that the Location object is a very computing-intense object that requires lots of memory and CPU, or that we wish to use some other means of finding geolocation from a service, such as Google or Bing Maps. We can request AutoMapper not to map the object for us in our CreateMap method by using its mapping expression method ForMember as follows: AutoMapper.Mapper.CreateMap<TransitStop, BusStopViewModel>() .ForMember(dest => dest.Location, opt => opt.Ignore()); By providing the Ignore option in the ForMember method, AutoMapper will not map the Location object. Summary In this article, we saw how to install AutoMapper, how to create a sample project, and how to transform our domain objects to ViewModel objects. Resources for Article : Further resources on this subject: ER Diagrams, Domain Model, and N-Layer Architecture with ASP.NET 3.5 (part2) [Article] Deploying .NET-based Applications on to Microsoft Windows CE Enabled Smart Devices [Article] ER Diagrams, Domain Model, and N-Layer Architecture with ASP.NET 3.5 (part1) [Article]
Read more
  • 0
  • 0
  • 1609

article-image-build-advanced-contact-manager-using-jboss-richfaces-33-part-1
Packt
18 Nov 2009
11 min read
Save for later

Build an Advanced Contact Manager using JBoss RichFaces 3.3: Part 1

Packt
18 Nov 2009
11 min read
The main layout Let's start preparing the space for the core features of the application. We want a three-column layout for groups, contacts list, and contact detail. Let's open the home.xhtml file and add a three-column panel grid inside the body: <h:panelGrid columns="3" width="100%" columnClasses="main-group-column, main-contacts-list-column,  main-contact-detail-column"></h:panelGrid> We are using three new CSS classes (one for every column). Let's open the /view/stylesheet/theme.css file and add the following code: .main-group-column { width: 20%; vertical-align: top;}.main-contacts-list-column { width: 40%; vertical-align: top;}.main-contact-detail-column { width: 40%; vertical-align: top;} The main columns are ready; now we want to split the content of every column in a separate file (so we don't have a large and difficult file to read) by using the Facelets templating capabilities—let's create a new folder inside the/view folder called main, and let's create the following empty files inside it: contactsGroups.xhtml contactsList.xhtml contactEdit.xhtml contactView.xhtml Now let's open them and put the standard code for an empty (included) file: <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><ui:composition ><!-- my code here --></ui:composition> Now, we have all of the pieces ready to be included into the home.xhtml file, let's open it and start adding the first column inside h:panelGrid: <a:outputPanel id="contactsGroups"> <ui:include src="main/contactsGroups.xhtml"/></a:outputPanel> As you can see, we surrounded the include with an a:outputPanel that will be used as a placeholder for the re-rendering purpose. Include a Facelets tag (ui:include) into the a:outputPanel that we used in order to include the page at that point. Ajax placeholders A very important concept to keep in mind while developing is that the Ajax framework can't add or delete, but can only replace existing elements in the page.For this reason, if you want to append some code, you need to use a placeholder. RichFaces has a component that can be used as a placeholder—a4j:outputPanel. Inside a4j:outputPanel, you can put other components that use the "rendered" attribute in order to decide if they are visible or not. When you want to re-render all the included components, just re-render the outputPanel, and all will work without any problem. Here is a non-working code snippet: <h:form> <h:inputText value="#{aBean.myText}"> <a4j:support event="onkeyup" reRender="out1" /> </h:inputText></h:form><h:outputText id="out1" value="#{aBean.myText}" rendered="#{not empty aBean.myText}"/> This code seems the same as that of the a4j:support example, but it won't work. The problem is that we added the rendered attribute to outputText, so initially, out1 will not be rendered (because the text property is initially empty and rendered will be equal to false). After the Ajax response, the JavaScript Engine will not find the out1 element (it is not in the page because of rendered="false"), and it will not be able to update it (remember that you can't add or delete elements, only replace them). It is very simple to make the code work: <h:form> <h:inputText value="#{aBean.myText}"> <a4j:support event="onkeyup" reRender="out2" /> </h:inputText></h:form><a4j:outputPanel id="out2"> <h:outputText id="out1" rendered="#{not empty aBean.myText}" value="#{aBean.myText}" /></a4j:outputPanel> As you can see, you just have to put the out1 component inside a4j:outputPanel (called out2) and tell a4j:support to re-render out2 instead of out1. Initially, out2 will be rendered but empty (because out1 will not be rendered). After the Ajax response, the empty out2 will be replaced with markup elements that also contain the out1 component (that is now visible, because the myText property is not empty after the Ajax update and the rendered property is true). A very important concept to keep in mind while developing is that the Ajax framework can't add or delete, but can only replace existing elements of the page. For this reason, if you want to append some code, you need to use a placeholder. The groups box This box will contain all the contacts groups, so the user will be able to organize contacts in different groups in a better way. We will not implement the group box features in this article. Therefore, by now the group column is just a rich:panel with a link to refresh the contact list. Let's open the contactsGroups.xhtml file and insert the following code: <h:form> <rich:panel> <f:facet name="header"> <h:outputText value="#{messages['groups']}" /> </f:facet> <h:panelGrid columns="1"> <a:commandLink value="#{messages['allContacts']}" ajaxSingle="true" reRender="contactsList"> <f:setPropertyActionListener value="#{null}" target="#{homeContactsListHelper.contactsList}" /> </a:commandLink> </h:panelGrid> </rich:panel></h:form> As you can see, we've put a three-column h:panelGrid (to be used in the future) and a:commandLink, which just sets the contactsList property of the homeContactListHelper bean (that we will see in the next section) to null, in order to make the list be read again. At the end of the Ajax interaction, it will re-render the contactsList column in order to show the new data. Also, notice that we are still supporting i18n for every text using the messages property; the task to fill the messages_XX.properties file is left as an exercise for the user. The contacts list The second column inside h:panelGrid of home.xhtml looks like: <a:outputPanel id="contactsList"> <ui:include src="main/contactsList.xhtml"/></a:outputPanel> As for groups, we used a placeholder surrounding the ui:include tag. Now let's focus on creating the data table—open the /view/main/contactsList.xhtml file and add the first snippet of code for dataTable: <h:form> <rich:dataTable id="contactsTable" reRender="contactsTableDS" rows="20" value="#{homeContactsListHelper.contactsList}" var="contact"> <rich:column width="45%"> <h:outputText value="#{contact.name}"/> </rich:column> <rich:column width="45%"> <h:outputText value="#{contact.surname}"/> </rich:column> <f:facet name="footer"> <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"/> </f:facet> </rich:dataTable> <h:outputText value="#{messages['noContactsInList']}" rendered="#{homeContactsListHelper.contactsList.size()==0}"/></h:form> We just added the rich:dataTable component with some columns and an Ajax data scroller at the end. Differences between h:dataTable and rich:dataTable RichFaces provides its own version of h:dataTable, which contains more features and is better integrated with the RichFaces framework. The first important additional feature, in fact, is the skinnability support following the RichFaces standards. Other features are row and column spans support (we will discuss it in the Columns and column groups section), out-of-the-box filter and sorting (discussed in the Filtering and sorting section), more JavaScript event handlers (such as onRowClick, onRowContextMenu, onRowDblClick, and so on) and the reRender attribute. Like other data iteration components of the RichFaces framework, it also supports the partial-row update. Data pagination Implementing Ajax data pagination using RichFaces is really simple—just decide how many rows must be shown in every page by setting the rows attribute of dataTable (in our case, we've chosen 20 rows per page), and then "attach" the rich:datascroller component to it by filling the for attribute with the dataTable id: <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"/> Here you can see another very useful attribute (renderIfSinglePage) that makes the component hidden when there is just a single page in the list (it means the list contains a number of items that is less than or equal to the value of the rows attribute). A thing to keep in mind is that the rich:datascroller component must stay inside a form component (h:form or a:form) in order to work. Customizing rich:datascroller is possible not only by using CSS classes (as usual), but also by personalizing our own parts using the following facets: pages controlsSeparator first, first_disabled last, last_disabled next, next_disabled previous, previous_disabled fastforward, fastforward_disabled fastrewind, fastrewinf_disabled Here is an example with some customized facets (using strings): <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"> <f:facet name="first"> <h:outputText value="First" /> </f:facet> <f:facet name="last"> <h:outputText value="Last" /> </f:facet></rich:datascroller> Here is the result: You can use an image (or another component) instead of text, in order to create your own customized scroller. Another interesting example is: <rich:datascroller id="contactsTableDS" for="contactsTable" renderIfSinglePage="false"> <f:facet name="first"> <h:outputText value="First"/> </f:facet> <f:facet name="last"> <h:outputText value="Last"/> </f:facet> <f:attribute name="pageIndexVar" value="pageIndexVar"/> <f:attribute name="pagesVar" value="pagesVar"/> <f:facet name="pages"> <h:panelGroup> <h:outputText value="Page #{pageIndexVar} / #{pagesVar}"/> </h:panelGroup> </f:facet></rich:datascroller> The result is: By setting the pageIndexVar and pagesVar attributes, we are able to use them in an outputText component, as we've done in the example. A useful attribute of the component is maxPages that sets the maximum number of page links (the numbers in the middle), which the scroller shows—therefore, we can control the size of it. The page attribute could be bound to a property of a bean, in order to switch to a page giving the number—a simple use-case could be using an inputText and a commandButton, in order to let the client insert the page number that he/she wants to go to. Here is the code that shows how to implement it: <rich:datascroller for="contactsList" maxPages="20" fastControls="hide" page="#{customDataScrollerExampleHelper.scrollerPage}" pagesVar="pages" id="ds"> <f:facet name="first"> <h:outputText value="First" /> </f:facet> <f:facet name="first_disabled"> <h:outputText value="First" /> </f:facet> <f:facet name="last"> <h:outputText value="Last" /> </f:facet> <f:facet name="last_disabled"> <h:outputText value="Last" /> </f:facet> <f:facet name="previous"> <h:outputText value="Previous" /> </f:facet> <f:facet name="previous_disabled"> <h:outputText value="Previous" /> </f:facet> <f:facet name="next"> <h:outputText value="Next" /> </f:facet> <f:facet name="next_disabled"> <h:outputText value="Next" /> </f:facet> <f:facet name="pages"> <h:panelGroup> <h:outputText value="Page "/> <h:inputText value="#{customDataScrollerExampleHelper. scrollerPage}" size="4"> <f:validateLongRange minimum="0" /> <a:support event="onkeyup" timeout="500" oncomplete="#{rich:component('ds')}. switchToPage(this.value)" /> </h:inputText> <h:outputText value=" of #{pages}"/> </h:panelGroup> </f:facet></rich:datascroller> As you can see, besides customizing the text of the First, Last, Previous, and Next sections, we defined a pages facet by inserting h:inputText connected with an integer value inside a backing bean. We also added the a:support tag, in order to trim the page change after the keyup event is completed. We've also set the timeout attribute, in order to call the server every 500 ms and not every time the user types. You can see a screenshot of the feature here:
Read more
  • 0
  • 0
  • 1601

article-image-service-oriented-java-business-integration-proxy
Packt
07 Apr 2010
9 min read
Save for later

Service Oriented Java Business Integration Proxy

Packt
07 Apr 2010
9 min read
Proxy—A Primer Wikipedia defines Proxy as: Proxy may refer to something which acts on behalf of something else. In the software a proxy is a substitute for a target instance and is a general pattern which appears in many other patterns in different variants. Proxy Design Pattern A proxy is a surrogate class for the target object. If a method call has to be invoked in the target object, it happens indirectly through the proxy object. The feature which makes proxy ideal for many situations is that the client or the caller is not aware that it is dealing with the proxy object. The proxy class is shown in the following figure: In the above figure, when a client invokes a method target towards the Target service, the proxy intercepts the call in between. The proxy also expose a similar interface to the target, hence the client is unaware of the dealing with the proxy. Thus the proxy method is invoked. The proxy then delegates the call to the actual target since it cannot provide the actual functionality. When doing so, the proxy can provide call management towards the actual method. The entire dynamics is shown in the following figure: A proxy is usually implemented by using a common, shared interface or super class. Both the proxy and the target share this common interface. Then, the proxy delegates the calls to the target class. JDK Proxy Class JDK provides both the class Proxy and the interface InvocationHandler in the java.lang.reflect package, since version 1.3. Using JDK Proxy classes, you can create your own classes implementing multiple interfaces of your choice, at run time. Proxy is the super class for any dynamic proxy instances you create at run time. Moreover, the Proxy class also accommodates a host of static methods which will help you to create your proxy instances. getProxyClass and newProxyInstance are two such utility methods. The Proxy API is listed in the following in brevity: package java.lang.reflect;public class Proxy implements java.io.Serializable{ protected InvocationHandler h; protected Proxy(InvocationHandler h); public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException; public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException; public static boolean isProxyClass(Class<?> cl); public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException} In the above code, you can invoke the Proxy.getProxyClass with a class loader and an array of interfaces for which you need to proxy, to get a Class instance for the proxy. Proxy objects have one constructor, to which you pass an InvocationHandler object associated with that proxy. When you invoke a method on the proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler. Let us also look at the InvocationHandler API reproduced as follows: package java.lang.reflect;public interface InvocationHandler{ Object invoke(Object proxy, Method method, Object[] args) throws Throwable;} We need to implement this interface and provide code for the invoke method. Once you get a Class instance for the proxy by invoking the Proxy.getProxyClass with a class loader and an array of interfaces for which you need to proxy to. Now, you can get a Constructor object for this proxy from the Class instance. On the constructor you can use newInstance (passing in an invocation handler instance) to create the proxy instance. The created instance should be implementing all the interfaces that were passed to getProxyClass. The steps are shown in the following code: InvocationHandler handler = new SomeInvocationHandler(...);Class proxyClazz = Proxy.getProxyClass(Blah.class.getClassLoader(), new Class[] {Blah.class});Blah blah = (Blah) proxyClazz.getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] {handler}); There is also a shortcut to get a proxy object. You can invoke Proxy.newProxyInstance, which takes a class loader, an array of interface classes, and an invocation handler instance. InvocationHandler handler = new SomeInvocationHandler(...);Blah blah = (Blah) Proxy.newProxyInstance(Blah.class. getClassLoader(),new Class[] {Blah.class}, handler); Now you can invoke methods on the proxy object during which these method invocations are turned into calls on to the invocation handler's invoke method is shown here: blah.interfaceMethod(); Sample JDK Proxy Class We will now write some simple code to demonstrate how you can write your own proxies at run time, for your interface classes. As a first step, if you haven't done it before, edit examples.PROPERTIES, and change the paths there to match your development environment. We will now look at the source code that can be found in the folder ch13JdkProxysrc. The files are explained here: ch13JdkProxysrcSimpleIntf.java public interface SimpleIntf { public void print(); } SimpleIntf is a simple interface with a single method print. print does not accept any parameters and also does not return any value. Our aim is that when we invoke methods on the proxy object for SimpleIntf, the method invocation should be turned into calls to an invocation handler's invoke method. Let us now define an invocation handler in the following code: ch13JdkProxysrcSimpleInvocationHandler.java import java.lang.reflect.InvocationHandler; import java.io.Serializable; import java.lang.reflect.Method; public class SimpleInvocationHandler implements InvocationHandler, Serializable { public SimpleInvocationHandler(){} public Object invoke(final Object obj, Method method, Object[] args) throws Throwable { if (method.getName().equals("print") && (args == null || args.length == 0)) { System.out.println("SimpleInvocationHandler.invoked"); } else { throw new IllegalArgumentException("Interface method does not support param(s) : " + args); } return null; }} Since SimpleIntf.print() does not accept any parameters and also does not return any value, in the invoke method of SimpleInvocationHandler, we double check the intention behind the actual invoker. In other words, we check that no parameters are passed and we return null only. Now, we have all the necessary classes to implement a proxy for SimpleIntf interface. Let us now execute it by writing a Test class. ch13JdkProxysrcTest.java import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; public class Test { public static void main(String[] args) { InvocationHandler handler = new SimpleInvocationHandler(); SimpleIntf simpleIntf = (SimpleIntf)Proxy.newProxyInstance (SimpleIntf.class.getClassLoader(),new Class[] { SimpleIntf. class }, handler); simpleIntf.print(); } } The wiring of the above described interfaces and classes are better represented in the UML class diagram in the following figure: The above figure shows the relationship between various classes and interfaces in the sample. $Proxy0 class represents the actual proxy class generated on the fly and as you can deduce it from the class diagram. $Proxy0 is a type of our interface (SimpleIntf). To build the sample, first change directory to ch13JdkProxy and execute ant as shown here: cd ch13JdkProxyant The command ant run will execute the Test class which will print out the following in the console: ServiceMix JBI Proxy Java proxies for the JBI endpoints can be created in ServiceMix using JSR181 components. For this, the requirement is that the JBI endpoints should expose a WSDL. A jsr181:endpoint takes a value for the serviceInterface attribute. The JBI container will be able to generate the WSDL out of this serviceInterface. Thus, if we have a jsr181:endpoint exposing service to the JBI bus, it is possible to provide a proxy for that service too. The basic configuration for defining a JBI proxy is shown as follows: <jsr181:proxy id="proxyBean" container="#jbi" interfaceName="test:HelloPortType" type="test.Hello" /> Once a proxy is defined, the same can then be referenced from your client bean or from one of your components. The proxied JBI endpoint can then be invoked just like a normal POJO. If you want to define a JBI proxy within a SU, you can follow the configuration given as follows: <jsr181:endpoint annotations="none" service="test:echoService" serviceInterface="test.Echo"> <jsr181:pojo> <bean class="test.EchoProxy"> <property name="echo"> <jsr181:proxy service="test:EchoService" context="#context" type="test.IService" /> </property> </bean> </jsr181:pojo></jsr181:endpoint> Let us now look into a few examples to make the concept clearer. JBI Proxy Sample Implementing Compatible Interface First, we will create a JBI proxy implementing an interface compatible with the target service. Then, in place of the target service we will use the proxy instance, so that any calls intended for the target service will be first routed to the proxy. The proxy in turn will delegate the call to the target service. The structural relationship between various classes participating in the interaction is shown in the following figure: Here, EchoProxyService is the class which we later expose in the JBI bus as the service. This class implements the IEcho interface. In order to demonstrate the proxy, EchoProxyService doesn't implement the service as such, instead depends on the JbiProxy derived out of another class TargetService. The TargetService contains the actual service code. As you can see, both the EchoProxyService and the TargetService implement the same interface. Proxy Code Listing The codebase for the sample is located in the folder ch13JbiProxy1_CompatibleInterface1_JsrProxysrc. This folder contains an interface IEcho and two other classes implementing the IEcho interface namely EchoProxyService and TargetService. These classes are explained here: IEcho.java: The IEcho interface declares a single method echo which takes a String parameter and returns a String. public interface IEcho{ public String echo(String input);} EchoProxyService.java: EchoProxyService is a convenient class which will act as mechanism for routing requests to the JBI proxy. Moreover, EchoProxyService implements the above interface IEcho. public class EchoProxyService implements IEcho{ private IEcho echo; public void setEcho(IEcho echo) { this.echo = echo; } public String echo(String input) { System.out.println("EchoProxyService.echo. this = " + this); return echo.echo(input); }} TargetService.java: TargetService also implements the interface IEcho. TargetService is supposed to be our target service, and we will be generating a JBI proxy for the TargetService. public class TargetService implements IEcho{ public String echo(String input) { System.out.println("TargetService.echo : String. this = " + this); return input; }}
Read more
  • 0
  • 0
  • 1600
article-image-oracle-web-rowset-part2
Packt
27 Oct 2009
4 min read
Save for later

Oracle Web RowSet - Part2

Packt
27 Oct 2009
4 min read
Reading a Row Next, we will read a row from the OracleWebRowSet object. Click on Modify Web RowSet link in the CreateRow.jsp. In the ModifyWebRowSet JSP click on the Read Row link. The ReadRow.jsp JSP is displayed. In the ReadRow JSP specify the Database Row to Read and click on Apply. The second row values are retrieved from the Web RowSet: In the ReadRow JSP the readRow() method of the WebRowSetQuery.java application is invoked. TheWebRowSetQuery object is retrieved from the session object. WebRowSetQuery query=( webrowset.WebRowSetQuery)session.getAttribute("query"); The String[] values returned by the readRow() method are added to theReadRow JSP fields. In the readRow() method theOracleWebRowSet object cursor is moved to the row to be read. webRowSet.absolute(rowRead); Retrieve the row values with the getString() method and add to String[]. Return the String[] object. String[] resultSet=new String[5];resultSet[0]=webRowSet.getString(1);resultSet[1]=webRowSet.getString(2);resultSet[2]=webRowSet.getString(3);resultSet[3]=webRowSet.getString(4);resultSet[4]=webRowSet.getString(5);return resultSet; ReadRow.jsp JSP is listed as follows: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><%@ page contentType="text/html;charset=windows-1252"%><%@ page session="true"%><html><head><meta http-equiv="Content-Type" content="text/html;charset=windows-1252"><title>Read Row with Web RowSet</title></head><body><form><h3>Read Row with Web RowSet</h3><table><tr><td><a href="ModifyWebRowSet.jsp">Modify Web RowSetPage</a></td></tr></table></form><%webrowset.WebRowSetQuery query=null;query=( webrowset.WebRowSetQuery)session.getAttribute("query");String rowRead=request.getParameter("rowRead");String journalUpdate=request.getParameter("journalUpdate");String publisherUpdate=request.getParameter("publisherUpdate");String editionUpdate=request.getParameter("editionUpdate");String titleUpdate=request.getParameter("titleUpdate");String authorUpdate=request.getParameter("authorUpdate");if((rowRead!=null)){int row_Read=Integer.parseInt(rowRead);String[] resultSet=query.readRow(row_Read);journalUpdate=resultSet[0];publisherUpdate=resultSet[1];editionUpdate=resultSet[2];titleUpdate=resultSet[3];authorUpdate=resultSet[4];}%><form name="query" action="ReadRow.jsp" method="post"><table><tr><td>Database Row to Read:</td></tr><tr><td><input name="rowRead" type="text" size="25"maxlength="50"/></td></tr><tr><td>Journal:</td></tr><tr><td><input name="journalUpdate" value='<%=journalUpdate%>'type="text" size="50" maxlength="250"/></td></tr><tr><td>Publisher:</td></tr><tr><td><input name="publisherUpdate"value='<%=publisherUpdate%>' type="text" size="50"maxlength="250"/></td></tr><tr><td>Edition:</td></tr><tr><td><input name="editionUpdate" value='<%=editionUpdate%>'type="text" size="50" maxlength="250"/></td></tr><tr><td>Title:</td></tr><tr><td><input name="titleUpdate" value='<%=titleUpdate%>'type="text" size="50" maxlength="250"/></td></tr><tr><td>Author:</td></tr><tr><td><input name="authorUpdate" value='<%=authorUpdate%>'type="text" size="50" maxlength="250"/></td></tr><tr><td><input class="Submit" type="submit" value="Apply"/></td></tr></table></form></body></html>
Read more
  • 0
  • 0
  • 1587

article-image-setting-test-infrastructure
Packt
12 Sep 2013
9 min read
Save for later

Setting Up a Test Infrastructure

Packt
12 Sep 2013
9 min read
(For more resources related to this topic, see here.) Setting up and writing our first tests Now that we have the base test libraries, we can create a test driver web page that includes the application and test libraries, sets up and executes the tests, and displays a test report. The test driver page A single web page is typically used to include the test and application code and drive all frontend tests. Accordingly, we can create a web page named test.html in the chapters/01/test directory of our repository starting with just a bit of HTML boilerplate—a title and meta attributes: <html> <head> <title>Backbone.js Tests</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> Then, we include the Mocha stylesheet for test reports and the Mocha, Chai, and Sinon.JS JavaScript libraries: <link rel="stylesheet" href="js/lib/mocha.css" /> <script src = "js/lib/mocha.js"></script> <script src = "js/lib/chai.js"></script > <script src = "js/lib/sinon.js"></script> Next, we prepare Mocha and Chai. Chai is configured to globally export the expect assertion function. Mocha is set up to use the bdd test interface and start tests on the window.onload event: <script> // Setup. var expect = chai.expect; mocha.setup("bdd"); // Run tests on window load event. window.onload = function () { mocha.run(); }; </script> After the library configurations, we add in the test specs. Here we include a single test file (that we will create later) for the initial test run: <script src = "js/spec/hello.spec.js"></script> </head> Finally, we include a div element that Mocha uses to generate the full HTML test report. Note that a common alternative practice is to place all the script include statements before the close body tag instead of within the head tag: <body> <div id="mocha"></div> </body> </html> And with that, we are ready to create some tests. Now, you could even open chapters/01/test/test.html in a browser to see what the test report looks like with an empty test suite. Adding some tests It is sufficient to say that test development generally entails writing JavaScript test files, each containing some organized collection of test functions. Let's start with a single test file to preview the testing technology stack and give us some tests to run. The test file chapters/01/test/js/spec/hello.spec.js creates a simple function (hello()) to test and implements a nested set of suites introducing a few Chai and Sinon.JS features. The function under test is about as simple as you can get: window.hello = function () { return "Hello World"; }; The hello function should be contained in its own library file (perhaps hello.js) for inclusion in applications and tests. The code samples simply include it in the spec file for convenience. The test code uses nested Mocha describe statements to create a test suite hierarchy. The test in the Chai suite uses expect to illustrate a simple assertion. The Sinon.JS suite's single test shows a test spy in action: describe("Trying out the test libraries", function () { describe("Chai", function () { it("should be equal using 'expect'", function () { expect(hello()).to.equal("Hello World"); }); }); describe("Sinon.JS", function () { it("should report spy called", function () { var helloSpy = sinon.spy(window, 'hello'); expect(helloSpy.called).to.be.false; hello(); expect(helloSpy.called).to.be.true; hello.restore(); }); }); }); Not to worry if you do not fully understand the specifics of these tests and assertions at this point, as we will shortly cover everything in detail. The takeaway is that we now have a small collection of test suites with a set of specifications ready to be run. Running and assessing test results Now that all the necessary pieces are in place, it is time to run the tests and review the test report. The first test report Opening up the chapters/01/test/test.html file in any web browser will cause Mocha to run all of the included tests and produce a test report: Test report This report provides a useful summary of the test run. The top-right column shows that two tests passed, none failed, and the tests collectively took 0.01 seconds to run. The test suites declared in our describe statements are present as nested headings. Each test specification has a green checkmark next to the specification text, indicating that the test has passed. Test report actions The report page also provides tools for analyzing subsets of the entire test collection. Clicking on a suite heading such as Trying out the test libraries or Chai will re-run only the specifications under that heading. Clicking on a specification text (for example, should be equal using 'expect') will show the JavaScript code of the test. A filter button designated by a right triangle is located to the right of the specification text (it is somewhat difficult to see). Clicking the button re-runs the single test specification. The test specification code and filter The previous figure illustrates a report in which the filter button has been clicked. The test specification text in the figure has also been clicked, showing the JavaScript specification code. Advanced test suite and specification filtering The report suite and specification filters rely on Mocha's grep feature, which is exposed as a URL parameter in the test web page. Assuming that the report web page URL ends with something such as chapters/01/test/test.html, we can manually add a grep filter parameter accompanied with the text to match suite or specification names. For example, if we want to filter on the term spy, we would navigate a browser to a comparable URL containing chapters/01/test/test.html?grep=spy, causing Mocha to run only the should report spy called specification from the Sinon.JS suite. It is worth playing around with various grep values to get the hang of matching just the suites or specifications that you want. Test timing and slow tests All of our tests so far have succeeded and run quickly, but real-world development necessarily involves a certain amount of failures and inefficiencies on the road to creating robust web applications. To this end, the Mocha reporter helps identify slow tests and analyze failures. Why is test speed important? Slow tests can indicate inefficient or even incorrect application code, which should be fixed to speed up the overall web application. Further, if a large collection of tests run too slow, developers will have implicit incentives to skip tests in development, leading to costly defect discovery later down the deployment pipeline. Accordingly, it is a good testing practice to routinely diagnose and speed up the execution time of the entire test collection. Slow application code may be left up to the developer to fix, but most slow tests can be readily fixed with a combination of tools such as stubs and mocks as well as better test planning and isolation. Let's explore some timing variations in action by creating chapters/01/test/js/spec/timing.spec.js with the following code: describe("Test timing", function () { it("should be a fast test", function (done) { expect("hi").to.equal("hi"); done(); }); it("should be a medium test", function (done) { setTimeout(function () { expect("hi").to.equal("hi"); done(); }, 40); }); it("should be a slow test", function (done) { setTimeout(function () { expect("hi").to.equal("hi"); done(); }, 100); }); it("should be a timeout failure", function (done) { setTimeout(function () { expect("hi").to.equal("hi"); done(); }, 2001); }); }); We use the native JavaScript setTimeout() function to simulate slow tests. To make the tests run asynchronously, we use the done test function parameter, which delays test completion until done() is called. The first test has no delay before the test assertion and done() callback, the second adds 40 milliseconds of latency, the third adds 100 milliseconds, and the final test adds 2001 milliseconds. These delays will expose different timing results under the Mocha default configuration that reports a slow test at 75 milliseconds, a medium test at one half the slow threshold, and a failure for tests taking longer than 2 seconds. Next, include the file in your test driver page (chapters/01/test/test-timing.html in the example code): <script src = "js/spec/timing.spec.js"></script> Now, on running the driver page, we get the following report: Test report timings and failures This figure illustrates timing annotation boxes for our medium (orange) and slow (red) tests and a test failure/stack trace for the 2001-millisecond test. With these report features, we can easily identify the slow parts of our test infrastructure and use more advanced test techniques and application refactoring to execute the test collection efficiently and correctly. Test failures A test timeout is one type of test failure we can encounter in Mocha. Two other failures that merit a quick demonstration are assertion and exception failures. Let's try out both in a new file named chapters/01/test/js/spec/failure.spec.js: // Configure Mocha to continue after first error to show // both failure examples. mocha.bail(false); describe("Test failures", function () { it("should fail on assertion", function () { expect("hi").to.equal("goodbye"); }); it("should fail on unexpected exception", function () { throw new Error(); }); }); The first test, should fail on assertion, is a Chai assertion failure, which Mocha neatly wraps up with the message expected 'hi' to equal 'goodbye'. The second test, should fail on unexpected exception, throws an unchecked exception that Mocha displays with a full stack trace. Stack traces on Chai assertion failures vary based on the browser. For example, in Chrome, no stack trace is displayed for the first assertion while one is shown in Safari. See the Chai documentation for configuration options that offer more control over stack traces. Test failures Mocha's failure reporting neatly illustrates what went wrong and where. Most importantly, Chai and Mocha report the most common case—a test assertion failure—in a very readable natural language format. Summary In this article, we introduced an application and test structure suitable for development, gathered the Mocha, Chai, and Sinon.JS libraries, and created some basic tests to get things started. Then, we reviewed some facets of the Mocha test reporter and watched various tests in action—passing, slow, timeouts, and failures. Resources for Article: Further resources on this subject: The Aliens Have Landed! [Article] Testing your App [Article] Quick Start into Selenium Tests [Article]
Read more
  • 0
  • 0
  • 1585
Modal Close icon
Modal Close icon