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-test-driven-development
Packt
05 Jan 2017
19 min read
Save for later

Test-Driven Development

Packt
05 Jan 2017
19 min read
In this article by Md. Ziaul Haq, the author of the book Angular 2 Test-Driven Development, introduces you to the fundamentals of test-driven development with AngularJS, including: An overview of test-driven development (TDD) The TDD life cycle: test first, make it run, and make it better Common testing techniques (For more resources related to this topic, see here.) Angular2 is at the forefront of client-side JavaScript testing. Every Angular2 tutorial includes an accompanying test, and event test modules are a part of the core AngularJS package. The Angular2 team is focused on making testing fundamental to web development. An overview of TDD Test-driven development (TDD) is an evolutionary approach to development, where you write a test before you write just enough production code to fulfill that test and its refactoring. The following section will explore the fundamentals of TDD and how they are applied by a tailor. Fundamentals of TDD Get the idea of what to write in your code before you start writing it. This may sound cliched, but this is essentially what TDD gives you. TDD begins by defining expectations, then makes you meet the expectations, and finally, forces you to refine the changes after the expectations are met. Some of the clear benefits that can be gained by practicing TDD are as follows: No change is small: Small changes can cause a hell lot of breaking issues in the entire project. Only practicing TDD can help out, as after any change, test suit will catch the breaking points and save the project and the life of developers. Specifically identify the tasks: A test suit provides a clear vision of the tasks specifically and provides the workflow step-by-step in order to be successful. Setting up the tests first allows you to focus on only the components that have been defined in the tests. Confidence in refactoring: Refactoring involves moving, fixing, and changing a project. Tests protect the core logic from refactoring by ensuring that the logic behaves independently of the code structure. Upfront investment, benefits in future: Initially, it looks like testing kills the extra time, but it actually pays off later, when the project becomes bigger, it gives confidence to extend the feature as just running the test will get the breaking issues, if any. QA resource might be limited: In most cases, there are some limitations on QA resources as it always takes extra time for everything to be manually checked by the QA team, but writing some test case and by running them successfully will save some QA time definitely. Documentation: Tests define the expectations that a particular object or function must meet. An expectation acts as a contract and can be used to see how a method should or can be used. This makes the code readable and easier to understand. Measuring the success with different eyes TDD is not just a software development practice. The fundamental principles are shared by other craftsmen as well. One of these craftsmen is a tailor, whose success depends on precise measurements and careful planning. Breaking down the steps Here are the high-level steps a tailor takes to make a suit: Test first: Determining the measurements for the suit Having the customer determine the style and material they want for their suit Measuring the customer's arms, shoulders, torso, waist, and legs Making the cuts: Measuring the fabric and cutting it Selecting the fabric based on the desired style Measuring the fabric based on the customer's waist and legs Cutting the fabric based on the measurements Refactoring: Comparing the resulting product to the expected style, reviewing, and making changes Comparing the cut and look to the customer's desired style Making adjustments to meet the desired style Repeating: Test first: Determining the measurements for the pants Making the cuts: Measuring the fabric and making the cuts Refactor: Making changes based on the reviews The preceding steps are an example of a TDD approach. The measurements must be taken before the tailor can start cutting up the raw material. Imagine, for a moment, that the tailor didn't use a test-driven approach and didn't use a measuring tape (testing tool). It would be ridiculous if the tailor started cutting before measuring. As a developer, do you "cut before measuring"? Would you trust a tailor without a measuring tape? How would you feel about a developer who doesn't test? Measure twice, cut once The tailor always starts with measurements. What would happen if the tailor made cuts before measuring? What would happen if the fabric was cut too short? How much extra time would go into the tailoring? Measure twice, cut once. Software developers can choose from an endless amount of approaches to use before starting developing. One common approach is to work off a specification. A documented approach may help in defining what needs to be built; however, without tangible criteria for how to meet a specification, the actual application that gets developed may be completely different from the specification. With a TDD approach (test first, make it run, and make it better), every stage of the process verifies that the result meets the specification. Think about how a tailor continues to use a measuring tape to verify the suit throughout the process. TDD embodies a test-first methodology. TDD gives developers the ability to start with a clear goal and write code that will directly meet a specification. Develop like a professional and follow the practices that will help you write quality software. Practical TDD with JavaScript Let's dive into practical TDD in the context of JavaScript. This walk through will take you through the process of adding the multiplication functionality to a calculator. Just keep the TDD life cycle, as follows, in mind: Test first Make it run Make it better Point out the development to-do list A development to-do list helps to organize and focus on tasks specifically. It also helps to provide a surface to list down the ideas during the development process, which could be a single feature later on. Let's add the first feature in the development to-do list—add multiplication functionality: 3 * 3 = 9. The preceding list describes what needs to be done. It also provides a clear example of how to verify multiplication—3 * 3 = 9. Setting up the test suit To set up the test, let's create the initial calculator in a file, called calculator.js, and is initialized as an object as follows: var calculator = {}; The test will be run through a web browser as a simple HTML page. So, for that, let's create an HTML page and import calculator.js to test it and save the page as testRunner.html. To run the test, open the testRunner.html file in your web browser. The testRunner.html file will look as follows: <!DOCTYPE html> <html> <head> <title>Test Runner</title> </head> <body> <script src="calculator.js"></script> </body> </html> The test suit is ready for the project and the development to-do list for feature is ready as well. The next step is to dive into the TDD life cycle based on the feature list one by one. Test first Though it's easy to write a multiplication function and it will work as its pretty simple feature, as a part of practicing TDD, it's time to follow the TDD life cycle. The first phase of the life cycle is to write a test based on the development to-do list. Here are the steps for the first test: Open calculator.js. Create a new function to test multiplying 3 * 3: function multipleTest1() { // Test var result = calculator.multiply(3, 3); // Assert Result is expected if (result === 9) { console.log('Test Passed'); } else { console.log('Test Failed'); } }; The test calls a multiply function, which still needs to be defined. It then asserts that the results are as expected, by displaying a pass or fail message. Keep in mind that in TDD, you are looking at the use of the method and explicitly writing how it should be used. This allows you to define the interface through a use case, as opposed to only looking at the limited scope of the function being developed. The next step in the TDD life cycle is focused on making the test run. Make it run In this step, we will run the test, just as the tailor did with the suit. The measurements were taken during the test step, and now the application can be molded to fit the measurements. The following are the steps to run the test: Open testRunner.html on a web browser. Open the JavaScript developer Console window in the browser. Test will throw an error, which will be visible in the browser's developer console, as shown in the following screenshot: The thrown error is about the undefined function, which is expected as the calculator application calls a function that hasn't been created yet—calculator.multiply. In TDD, the focus is on adding the easiest change to get a test to pass. There is no need to actually implement the multiplication logic. This may seem unintuitive. The point is that once a passing test exists, it should always pass. When a method contains fairly complex logic, it is easier to run a passing test against it to ensure that it meets the expectations. What is the easiest change that can be made to make the test pass? By returning the expected value of 9, the test should pass. Although this won't add the multiply function, it will confirm the application wiring. In addition, after you have passed the test, making future changes will be easy as you have to simply keep the test passing! Now, add the multiply function and have it return the required value of 9, as illustrated: var calculator = { multiply : function() { return 9; } }; Now, let's refresh the page to rerun the test and look at the JavaScript console. The result should be as shown in the following screenshot: Yes! No more errors, there's a message showing that test has been passed. Now that there is a passing test, the next step will be to remove the hardcoded value in the multiply function. Make it better The refactoring step needs to remove the hardcoded return value of the multiply function that we added as the easiest solution to pass the test and will add the required logic to get the expected result. The required logic is as follows: var calculator = { multiply : function(amount1, amount2) { return amount1 * amount2; } }; Now, let's refresh the browser to rerun the tests, it will pass the test as it did before. Excellent! Now the multiply function is complete. The full code of the calculator.js file for the calculator object with its test will look as follows: var calculator = { multiply : function(amount1, amount2) { return amount1 * amount2; } }; function multipleTest1() { // Test var result = calculator.multiply(3, 3); // Assert Result is expected if (result === 9) { console.log('Test Passed'); } else { console.log('Test Failed'); } }; multipleTest1(); Mechanism of testing To be a proper TDD following developer, it is important to understand some fundamental mechanisms of testing, techniques, and approaches to testing. In this section, we will walk you through a couple of examples of techniques and mechanisms of the tests that will be leveraged in this article. This will mostly include the following points: Testing doubles with Jasmine spies Refactoring the existing tests Building patterns In addition, here are the additional terms that will be used: Function under test: This is the function being tested. It is also referred to as system under test, object under test, and so on. The 3 A's (Arrange, Act, and Assert): This is a technique used to set up tests, first described by Bill Wake (http://xp123.com/articles/3a-arrange-act-assert/). Testing with a framework We have already seen a quick and simple way to perform tests on calculator application, where we have set the test for the multiply method. But in real life, it will be more complex and a way larger application, where the earlier technique will be too complex to manage and perform. In that case, it will be very handy and easier to use a testing framework. A testing framework provides methods and structures to test. This includes a standard structure to create and run tests, the ability to create assertions/expectations, the ability to use test doubles, and more. The following example code is not exactly how it runs with the Jasmine test/spec runner, it's just about the idea of how the doubles work, or how these doubles return the expected result. Testing doubles with Jasmine spies A test double is an object that acts and is used in place of another object. Jasmine has a test double function that is known as spies. Jasmine spy is used with the spyOn()method. Take a look at the following testableObject object that needs to be tested. Using a test double, you can determine the number of times testableFunction gets called. The following is an example of Test double: var testableObject = { testableFunction : function() { } }; jasmine.spyOn(testableObject, 'testableFunction'); testableObject.testableFunction(); testableObject.testableFunction(); testableObject.testableFunction(); console.log(testableObject.testableFunction.count); The preceding code creates a test double using a Jasmine spy (jasmine.spyOn). The test double is then used to determine the number of times testableFunction gets called. The following are some of the features that a Jasmine test double offers: The count of calls on a function The ability to specify a return value (stub a return value) The ability to pass a call to the underlying function (pass through) Stubbing return value The great thing about using a test double is that the underlying code of a method does not have to be called. With a test double, you can specify exactly what a method should return for a given test. Consider the following example of an object and a function, where the function returns a string: var testableObject = { testableFunction : function() { return 'stub me'; } }; The preceding object (testableObject) has a function (testableFunction) that needs to be stubbed. So, to stub the single return value, it will need to chain the and.returnValuemethod and will pass the expected value as param. Here is how to spy chain the single return value to stub it: jasmine.spyOn(testableObject, 'testableFunction') .and .returnValue('stubbed value'); Now, when testableObject.testableFunction is called, a stubbed value will be returned. Consider the following example of the preceding single stubbed value: var testableObject = { testableFunction : function() { return 'stub me'; } }; //before the return value is stubbed Console.log(testableObject.testableFunction()); //displays 'stub me' jasmine.spyOn(testableObject,'testableFunction') .and .returnValue('stubbed value'); //After the return value is stubbed Console.log(testableObject.testableFunction()); //displays 'stubbed value' Similarly, we can pass multiple retuned values as the preceding example. To do so, it will chain the and.returnValuesmethod with the expected values as param, where the values will be separated by commas. Here is how to spy chain the multiple return values to stub them one by one: jasmine.spyOn(testableObject, 'testableFunction') .and .returnValues('first stubbed value', 'second stubbed value', 'third stubbed value'); So, for every call of testableObject.testableFunction, it will return the stubbedvalue in order until reaches the end of the return value list. Consider the given example of the preceding multiple stubbed values: jasmine.spyOn(testableObject, 'testableFunction') .and .returnValue('first stubbed value', 'second stubbed value', 'third stubbed value'); //After the is stubbed return values Console.log(testableObject.testableFunction()); //displays 'first stubbed value' Console.log(testableObject.testableFunction()); //displays 'second stubbed value' Console.log(testableObject.testableFunction()); //displays 'third stubbed value' Testing arguments A test double provides insights into how a method is used in an application. As an example, a test might want to assert what arguments a method was called with or the number of times a method was called. Here is an example function: var testableObject = { testableFunction : function(arg1, arg2) {} }; The following are the steps to test the arguments with which the preceding function is called: Create a spy so that the arguments called can be captured: jasmine.spyOn(testableObject, 'testableFunction'); Then, to access the arguments, do the following: //Get the arguments for the first call of the function var callArgs = testableObject.testableFunction.call.argsFor(0); console.log(callArgs); //displays ['param1', 'param2'] Here is how the arguments can be displayed using console.log: var testableObject = { testableFunction : function(arg1, arg2) {} }; //create the spy jasmine.spyOn(testableObject, 'testableFunction'); //Call the method with specific arguments testableObject.testableFunction('param1', 'param2'); //Get the arguments for the first call of the function var callArgs = testableObject.testableFunction.call.argsFor(0); console.log(callArgs); //displays ['param1', 'param2'] Refactoring Refactoring is the act of restructuring, rewriting, renaming, and removing code in order to improve the design, readability, maintainability, and overall aesthetics of a piece of code. The TDD life cycle step of "making it better" is primarily concerned with refactoring. This section will walk you through a refactoring example. Take a look at the following example of a function that needs to be refactored: var abc = function(z) { var x = false; if(z > 10) return true; return x; } This function works fine and does not contain any syntactical or logical issues. The problem is that the function is difficult to read and understand. Refactoring this function will improve the naming, structure, and definition. The exercise will remove the masquerading complexity and reveal the function's true meaning and intention. Here are the steps: Rename the function and variable names to be more meaningful, that is, rename x and z so that they make sense, as shown: var isTenOrGreater = function(value) { var falseValue = false; if(value > 10) return true; return falseValue; } Now, the function can easily be read and the naming makes sense. Remove unnecessary complexity. In this case, the if conditional statement can be removed completely, as follows: var isTenOrGreater = function(value) { return value > 10; }; Reflect on the result. At this point, the refactoring is complete, and the function's purpose should jump out at you. The next question that should be asked is "why does this method exist in the first place?". This example only provided a brief walk-through of the steps that can be taken to identify issues in code and how to improve them. Building with a builder These days, design pattern is almost a kind of common practice, and we follow design pattern to make life easier. For the same reason, the builder pattern will be followed here. The builder pattern uses a builder object to create another object. Imagine an object with 10 properties. How will test data be created for every property? Will the object have to be recreated in every test? A builder object defines an object to be reused across multiple tests. The following code snippet provides an example of the use of this pattern. This example will use the builder object in the validate method: var book = { id : null, author : null, dateTime : null }; The book object has three properties: id, author, and dateTime. From a testing perspective, you would want the ability to create a valid object, that is, one that has all the fields defined. You may also want to create an invalid object with missing properties, or you may want to set certain values in the object to test the validation logic, that is, dateTime is an actual date. Here are the steps to create a builder for the dateTime object: Create a builder function, as shown: var bookBuilder = function() {}; Create a valid object within the builder, as follows: var bookBuilder = function() { var _resultBook = { id: 1, author: 'Any Author', dateTime: new Date() }; } Create a function to return the built object, as given: var bookBuilder = function() { var _resultBook = { id: 1, author: "Any Author", dateTime: new Date() }; this.build = function() { return _resultBook; } } As illustrated, create another function to set the _resultBook author field: var bookBuilder = function() { var _resultBook = { id: 1, author: 'Any Author', dateTime: new Date() }; this.build = function() { return _resultBook; }; this.setAuthor = function(author){ _resultBook.author = author; }; }; Make the function fluent, as follows, so that calls can be chained: this.setAuthor = function(author) { _resultBook.author = author; return this; }; A setter function will also be created for dateTime, as shown: this.setDateTime = function(dateTime) { _resultBook.dateTime = dateTime; return this; }; Now, bookBuilder can be used to create a new book, as follows: var bookBuilder = new bookBuilder(); var builtBook = bookBuilder.setAuthor('Ziaul Haq') .setDateTime(new Date()) .build(); console.log(builtBook.author); // Ziaul Haq The preceding builder can now be used throughout your tests to create a single consistent object. Here is the complete builder for your reference: var bookBuilder = function() { var _resultBook = { id: 1, author: 'Any Author', dateTime: new Date() }; this.build = function() { return _resultBook; }; this.setAuthor = function(author) { _resultBook.author = author; return this; }; this.setDateTime = function(dateTime) { _resultBook.dateTime = dateTime; return this; }; }; Let's create the validate method to validate the created book object from builder. var validate = function(builtBookToValidate){ if(!builtBookToValidate.author) { return false; } if(!builtBookToValidate.dateTime) { return false; } return true; }; So, at first, let's create a valid book object with builder by passing all the required information, and if this is passed via the validate object, this should show a valid message: var validBuilder = new bookBuilder().setAuthor('Ziaul Haq') .setDateTime(new Date()) .build(); // Validate the object with validate() method if (validate(validBuilder)) { console.log('Valid Book created'); } In the same way, let's create an invalid book object via builder by passing some null value in the required information. And by passing the object to the validate method, it should show the message, why it's invalid. var invalidBuilder = new bookBuilder().setAuthor(null).build(); if (!validate(invalidBuilder)) { console.log('Invalid Book created as author is null'); } var invalidBuilder = new bookBuilder().setDateTime(null).build(); if (!validate(invalidBuilder)) { console.log('Invalid Book created as dateTime is null'); } Self-test questions Q1. A test double is another name for a duplicate test. True False Q2. TDD stands for test-driven development. True False Q3. The purpose of refactoring is to improve code quality. True False Q4. A test object builder consolidates the creation of objects for testing. True False Q5. The 3 A's are a sports team. True False Summary This article provided an introduction to TDD. It discussed the TDD life cycle (test first, make it run, and make it better) and showed how the same steps are used by a tailor. Finally, it looked over some of the testing techniques such as test doubles, refactoring, and building patterns. Although TDD is a huge topic, this article is solely focused on the TDD principles and practices to be used with AngularJS. Resources for Article: Further resources on this subject: Angular 2.0 [Article] Writing a Blog Application with Node.js and AngularJS [Article] Integrating a D3.js visualization into a simple AngularJS application [Article]
Read more
  • 0
  • 0
  • 1719

article-image-soa-java-business-integration-part-1
Packt
16 Oct 2009
5 min read
Save for later

SOA with Java Business Integration (part 1)

Packt
16 Oct 2009
5 min read
SOA—The Motto We have been doing integration for many decades in proprietary or ad-hoc manner. Today, the buzz word is SOA and in the integration space, we are talking about Service Oriented Integration (SOI). Let us look into the essentials of SOA and see whether the existing standards and APIs are sufficient in the integration space. Why We Need SOA We have been using multiple technologies for developing application components, and a few of them are listed as follows: Remote Procedure Call (RPC) Common Object Request Broker Architecture (CORBA) Distributed Component Object Model (DCOM) .NET remoting Enterprise Java Beans (EJBs) Java Remote Method Invocation (RMI) One drawback, which can be seen in almost all these technologies, is their inability to interoperate. In other words, if a .NET remoting component has to send bytes to a Java RMI component, there are workarounds that may not work all the times. Next, all the above listed technologies follow the best Object Oriented Principles (OOP), especially hiding the implementation details behind interfaces. This will provide loose coupling between the provider and the consumer, which is very important especially in distributed computing environments. Now the question is, are these interfaces abstract enough? To rephrase the question, can a Java RMI runtime make sense out of a .NET interface? Along these lines, we can point out a full list of doubts or deficiencies which exist in today's computing environment. This is where SOA brings new promises. What is SOA SOA is all about a set of architectural patterns, principles, and best practices to implement software components in such a way that we overcome much of the deficiencies identified in traditional programming paradigms. SOA speaks about services implemented based on abstract interfaces where only the abstract interface is exposed to the outside world. Hence the consumers are unaware of any implementation details. Moreover, the abstract model is neutral of any platform or technology. This means, components or services implemented in any platform or technology can interoperate. We will list out few more features of SOA here: Standards-based (WS-* Specifications) Services are autonomous and coarse grained Providers and consumers are loosely coupled The list is not exhaustive, but we have many number of literature available speaking on SOA, so let us not repeat it here. Instead we will see the importance of SOA in the integration context. SOA and Web Services SOA doesn't mandate any specific platform, technology, or even a specific method of software engineering, but time has proven that web service is a viable technology to implement SOA. However, we need to be cautious in that using web services doesn't lead to SOA by itself, or implement it. Rather, since web services are based on industry accepted standards like WSDL, SOAP, and XML; it is one of the best available means to attain SOA. Providers and consumers agree to a common interface called Web Services Description Language (WSDL) in SOA using web services. Data is exchanged normally through HTTP protocol, in Simple Object Access Protocol (SOAP) format. WSDL WSDL is the language of web services, used to specify the service contract to be agreed upon by the provider and consumer. It is a XML formatted information, mainly intended to be machine processable (but human readable too, since it is XML). When we host a web service, it is normal to retrieve the WSDL from the web service endpoint. Also, there are mainly two approaches in working with WSDL, which are listed as follows: Start from WSDL, create and host the web service and open the service for clients; tools like wsdl2java help us to do this. Start from the types already available, generate the WSDL and then continue; tools like java2wsdl help us here. Let us now quickly run through the main sections within a WSDL. A WSDL structure is as shown here: <?xml version="1.0" encoding="UTF-8"?><wsdl:definitions targetNamespace= "http://versionXYZ.ws.servicemix.esb.binildas.com" …> <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="http://version20061231.ws. servicemix.esb.binildas.com" > </schema> </wsdl:types> <wsdl:message name="helloResponse"> <!-- other code goes here --> </wsdl:message> <wsdl:portType name="IHelloWeb"> <!-- other code goes here --> </wsdl:portType> <wsdl:binding name="HelloWebService20061231SoapBinding" type="impl:IHelloWeb"> <!-- other code goes here --> </wsdl:binding> <wsdl:service name="IHelloWebService"> <wsdl:port binding="impl:HelloWebService20061231SoapBinding" name="HelloWebService20061231"> <wsdlsoap:address location="http://localhost:8080/AxisEndToEnd20061231/ services/HelloWebService20061231"/> </wsdl:port> </wsdl:service></wsdl:definitions> We will now run through the main sections of a typical WSDL: types: The data types exchanged are expressed here as an XML schema. message: This section details about the message formats (or the documents) exchanged. portType: The PortType can be looked at as the abstract interface definition for the exposed service. binding: The PortType has to be mapped to specific data formats and protocols, which will be detailed out in the binding section. port: The port gives the URL representation of the service endpoint. service: Service can contain a collection of port elements. Since JBI is based on WSDL, we can deal with many WSDL instances.    
Read more
  • 0
  • 0
  • 1711

article-image-diagnostic-leveraging-accelerated-poc-crm-online-service
Packt
24 Jan 2014
16 min read
Save for later

Diagnostic leveraging of the Accelerated POC with the CRM Online service

Packt
24 Jan 2014
16 min read
(For more resources related to this topic, see here.) For customers considering Dynamics CRM solutions, online or on-premises, Sure Step introduced a service called Accelerated Proof of Concept with CRM Online. This service was designed to take advantage of free trial licenses that can be afforded to prospective customers, giving them the ability to "test drive" the CRM Online solution on their own before deciding to move forward with solution envisioning and solution acquisition. Microsoft Dynamics is one of the unique solution providers in the world to give customers the same foundational code base for both on-premises and online solutions. Thus, customers may validate the functionality on CRM Online and still choose to deploy the on-premises solution if they so desire. Hence this Sure Step service is titled Accelerated POC with CRM Online as opposed to for CRM Online solutions only. The activity flow of the Accelerated POC with CRM Online service is shown in the following diagram: The conceptual design behind this service was to provide some standard scenarios to customers. Customers would then have the ability to upload their own dataset for these scenarios, giving them the ability to quickly validate the corresponding CRM functionality and get a comfort feel for the Dynamics CRM product. To start with, the Microsoft Services team developed five out-of-box Sales Force Automation (SFA) scenarios that encompassed basic workflows for the following: Lead capture Lead allocation/routing Opportunity management Quote/contract development Contract conversion The SFA scenarios were made available to the Dynamics partner ecosystem via the CRM Marketplace in the form of a Quick Start package. Besides the solution setup for the scenarios, the package also included a delivery guide, demo scripts, and sample data that could be used as a building block for a customer Proof of Concept for the corresponding scenarios. Using the previously discussed materials, solution providers could execute high-level requirements and Fit Gap reviews in the first step of this service. If one or more of the scenarios fits with the customer needs, the solution provider can conduct a preliminary business value assessment to get an initial gauge of the solution benefits as well as an architecture assessment to determine how the customer's users would access the system. Following that, the provider's team would set up the system with customer data and turn it over to the customer's assigned users, who could use the remainder of the free trial licenses to test the system. The idea of giving the customer's users a setup with their own data was to make it that much more intuitive to them in testing and evaluating a new system. The Accelerated POC concept can be leveraged for scenarios besides the five noted if the solution providers develop other predefined scenarios that they commonly encounter in customer engagements and then follow the process previously noted. The Accelerated POC scenarios can also be leveraged as starting points for customer demonstrations of the CRM solution. It also bears mention that the Accelerated POC was designed to get a quick win for the sales team with a customer by affording them hands-on experience on a limited subset of the CRM functionality. When the customer feels comfortable with that aspect of the solution, the solution provider may avail of the other Decision Accelerator Offering services previously discussed, including Requirements and Process Review, Fit Gap and Solution Blueprint, Architecture Assessment, and Scoping Assessment, to determine the scope of the full solution required for the customer. The Diagnostic phase for a current Dynamics customer We covered the Sure Step Diagnostic phase guidance for a new or prospective Dynamics customer. The Diagnostic phase also supports the process for due diligence and solution selling process for an existing Dynamics customer, which is the topic of discussion in this article. The following diagram shows the flow of activities and services of the Decision Accelerator Offering for an existing customer. The flow is very similar to the one for a prospect, with the only difference being the Upgrade Assessment DA service replacing the Requirements and Process Review DA service. Much like the flow for a prospect, the flow for the existing customer begins with the Diagnostic preparation. In this case, however, the sales team uses the guidance to explain the capabilities and features of the new version of the corresponding Microsoft Dynamics solution. When the customer expresses interest in moving their existing solution to the current version of the solution, the next step is the Upgrade Assessment DA service. Assessing the upgrade requirements The services delivery team has two primary objectives when executing the Upgrade Assessment DA service. First, the delivery team assesses the current solution to determine the impact of the proposed upgrade. Second, they determine the optimal approach to upgrade the solution to the current version. The Upgrade Assessment DA service begins with the solution delivery team meeting with the customer to understand the requirements for the upgrade. The solution delivery team is usually comprised of solution and/or service sales executives as well as solution architects and senior application consultants to provide real-life perspectives to the customer. Sure Step provides product-specific questionnaires that can be leveraged for the Upgrade Assessment exercise, including upgrade questionnaires for Microsoft Dynamics AX, CRM, CRM Online, GP, NAV, and SL. In future releases, the Upgrade questionnaires for AX may be replaced by the Upgrade Analysis tool from the new Microsoft Dynamics R&D Lifecycle Services. In the next step, the solution architect and/or application consultants review the configurations, customizations, integrations, physical infrastructure, and system architecture of the customer's existing solution. The team then proceeds to highlight those requirements that can be met by the new feature enhancements and determine whether there are any customizations that may no longer be necessary in the new product version. The team also reviews the customizations that will need to be promoted to the upgraded solution and identifies any associated complexities and risks involved in upgrading the solution. Finally, the team will clearly delineate those requirements that are met by current functionality and those that require implementation of new functionality. For the new functionality, the delivery team can avail of the corresponding product questionnaires from the Requirements and Process Review DA service. The last step in the Upgrade Assessment DA service is to agree upon the delivery approach for the upgrade. If no new functionality is deemed necessary as part of the upgrade, the solution can use the Technical Upgrade project type guidance, workflow, and templates. On the other hand, if a new functionality is deemed necessary, it is recommended that you use a phased approach, in which the first release is a Technical Upgrade to bring the solution to the current product version, and then the ensuing release or releases implement the new functionality using the other Sure Step project types (Rapid, Standard, Enterprise, or Agile). Applying the other Decision Accelerator Offerings services to upgrade engagements If the upgrade is strictly to promote the solution to a current, supported release of the product, the solution delivery team can skip the Fit Gap and Solution Blueprint exercise and go to the Architecture Assessment DA service to determine the new hardware and infrastructure requirements and the Scoping Assessment DA service to estimate the effort for the upgrade. The team may also choose to combine all these services into a single offering and just use the templates and tools from the other offerings to provide the customer with a Statement of Work and Upgrade estimate. If the upgrade is going to introduce a new functionality, depending on the magnitude of the new requirements, the customer and sales teams may deem it necessary to execute or combine the Fit Gap and Solution Blueprint, Architecture Assessment, and Scoping Assessment DA services. This ensures that a proper blueprint, system architecture, and overall release approach is collectively discussed and agreed upon by both parties. In both cases, the Proof of Concept DA and Business Case DA services may not be necessary, although depending on the scope of the new functionality being introduced in the upgrade, the customer and sales teams may decide to use the Business Case tools to ensure that project justification is established. After the completion of the necessary DA services, the sales team can proceed to the Proposal Generation activity to establish the Project Charter and Project Plan. The next step is then to complete the sale in the Final Licensing and Services Agreement activity, including agreeing upon the new terms of the product licenses and the Statement of Work for the solution upgrade. Finally, the delivery team is mobilized in the Project Mobilization activity to ensure that the upgrade engagement is kicked off smoothly. Supporting the customer's buying cycle The Sure Step Diagnostic phase is designed to help the seller in the solution provider organizations and the buyer in the customer organizations. We also covered the applicability of the phase to the seller; in this article, we will talk about how the customer's due diligence efforts are enabled with a thorough process for selecting the right solution to meet their vision and requirements. We discussed the stages that correspond to the customer's buying cycle. The following diagram shows how the same Sure Step Diagnostic phase activities and Decision Accelerator Offerings that we applied to the solution selling process also align with the phases of the customer's buying cycle: Phase I: Need Determination The Solution Overview activity The Requirements and Process Review Decision Accelerator service Phase II: Alternatives Evaluation The Fit Gap and Solution Blueprint Decision Accelerator service The Architecture Assessment Decision Accelerator service The Scoping Assessment Decision Accelerator service Phase III: Risk Evaluation The Proof of Concept Decision Accelerator service The Business Case Decision Accelerator service The Proposal Generation activity Let's first begin by addressing the application of the Decision Accelerator Offering and its services to a customer's perspective. From a seller's perspective, the term offering can be viewed as a sellable unit. But the term Decision Accelerator on the other hand, extends beyond the seller to the customer, as the intent of these units is to help them get expedient answers to their questions and move their decision making process forward in a logical and structured manner. In that context, the Decision Accelerator Offerings term is very much applicable to the customer as well. The following sections will discuss the alignment of the activities and Decision Accelerator Offering services to the customer's buying cycle. If the reader has not already done so, they are encouraged to review the previous sections to understand the constructs of the Decision Accelerator Offering services as that is not repeated in this article. Defining organizational needs The buyer starts their Need Determination phase by understanding the organizational pain points and gathering information on solutions available in the marketplace. The guidance links to additional websites and other information sources in the Diagnostic preparation activity can help address the solution information gathering effort. If the customer's organization operates in an industry covered by Sure Step, they can also gain additional information on how the solution relates to their specific needs in the industry sections. While the guidance in the Diagnostic preparation activity provides the customer with the external awareness of available solutions, the Sure Step Requirements and Process Review Decision Accelerator service facilitates the customer's understanding of their own internal needs. Using the role-tailored questionnaire templates in this offering, Subject Matter Experts (SMEs) from the customer team can work through "a-day-in-the-life-of" scenarios for each of the roles so that they can quantify the departmental and organizational needs from a user perspective, rather than from only a product perspective. Customers can also use detailed process maps as a starting point, especially the new BPM tool to begin visualizing the organization's workflow with the new solution. Again, this helps the customer describe their needs from a user's perspective. Ultimately, the success or failure of a solution is determined by how applicable or pertinent it is to the user, so this point cannot be overemphasized. The documentation of the requirements and to-be processes forms the basis for the future solution vision. Depending on how they are developed, the customer organization can leverage these documents to conduct a thorough evaluation of the solution alternatives and select the best solution to meet their needs. Determining the right solution After the needs are determined, the buyer begins evaluations of the solution alternatives. This is where the Sure Step Fit Gap and Solution Blueprint, Architecture Assessment, and Scoping Assessment Decision Accelerator services can help the customer determine whether the Microsoft Dynamics solution is the right one for them. As discussed in the earlier section, the Fit Gap and Solution Blueprint DA exercise begins by determining the Degree of Fit of the solution to each of the requirements. Some customers may desire a higher value of the Degree of Fit so as to minimize customizations, while others may be operating in a specialized environment that necessitates a fairly customized solution, and as such, they may be comfortable with a lower value of the Degree of Fit. However, in both the scenarios, the customer will want to ensure that their TCO for the solution is acceptable. Following the determination of the solution fit, the customer SMEs will work with the solution provider to develop the blueprint for the future solution. The solution blueprint is typically presented to the customer's executive or business sponsor. As such, the document should be written in business language and should clearly explain how the business needs or pains will be met or resolved by the proposed solution. Armed with the solution blueprint, the buyer then obtains other key information to evaluate whether the solution meets their cost criteria. The Architecture Assessment DA service will provide the customer with the proposed hardware and architecture, with which the customer's procurement department can determine the physical infrastructure costs. Should the customer have any concerns regarding performance, scalability, and reliability of the solution, they can also request more technical validation from the service provider by requesting more detailed analysis in the corresponding areas. Finally, the Scoping Assessment DA service provides the customer business sponsor with the effort estimate and the associated costs for solution delivery. This exercise also provides the customer with the understanding of the overall approach to delivering the solution, including timelines and projected resources, roles, and responsibilities. Understanding and mitigating risks In the last phase of their buying cycle, the customer will want assurances that the projected solution benefits far outweigh the associated risks. The Sure Step Proof of Concept Decision Accelerator service can help allay any specific concerns for the customer's SMEs or departmental leads around a certain area of the solution. The solution delivery team will set up, configure, and customize the solution and will use customer data where possible to show that the application of the solution matches the customer's requirements. Any solution efforts executed in this offering are then carried over to the implementation and become the starting point for solution delivery. The Sure Step Business Case Decision Accelerator service also helps the customer in this phase of their buying cycle, but more from the perspective of managing the executive and organizational buy-in for the solution. Using an independent analyst-developed ROI tool, this service can help the customer team justify the acquisition of the solution to other key stakeholders in the organization such as the CEO, CFO, or the board of directors. This can be a key step to counter organizational politics, and it can also be very important during the inevitable ebbs and flows of a solution delivery cycle. Finally, the Sure Step Proposal Generation activity provides the customer sponsor and customer project manager with the overall project charter and project plan, ensuring that they have clear documentation of what has been agreed upon between the buyer and the seller to avoid any assumptions or misunderstandings down the line. The project charter will also identify the risks associated with solution delivery and should outline a mitigation strategy for each of them. The project charter developed by the solution provider may also note any dependencies or assumptions owned by the customer; the customer should ensure that they have the necessary resources in place so that these dependencies do not become impediments to the delivery team. Approach to upgrade existing solutions Similar to the evaluation process for a new solution, the Sure Step Diagnostic phase also supports the due diligence process for a current customer looking to upgrade their solution. The following diagram shows a very similar flow to the new solution evaluation, with the only difference being that the Upgrade Assessment DA service now replaces the Requirements and Process Review DA service: As discussed in the earlier section, the Sure Step Upgrade Assessment Decision Accelerator service captures the business needs for the customer to change or enhance their current solution and determines the best approach to upgrade to the latest version of the solution. If the current solution includes customizations that may no longer be deemed necessary because of new features, the delivery team will identify this. They will also evaluate the complexity for the overall upgrade as well as the release process for the upgrade. The Upgrade Assessment DA exercise findings will also dictate the degree to which the customer should undertake the Fit Gap and Solution Blueprint, Architecture Assessment, Scoping Assessment, Proof of Concept, and Business Case Decision Accelerator services. Depending upon the magnitude of the new functionality desired, the customer sponsor and SMEs can decide to skip or combine the services as necessary. Regardless of how the DA Offering services are utilized, the project charter and project plan should be developed for the customer in the Proposal Generation activity. Summary This article discussed the activities and covered in detail the Decision Accelerator Offerings. It also spoke about the ways in which the Diagnostic phase sets the stage for quality implementation by outlining the risks involved. We discuss the selection of the right approach for the deployment as well as the parts that will be played by both the partner and the customer teams. Resources for Article: Further resources on this subject: An Overview of Microsoft Sure Step [Article] Foreword by Microsoft Dynamics Sure Step Practitioners [Article] Upgrading with Microsoft Sure Step [Article]
Read more
  • 0
  • 0
  • 1705

article-image-introduction-drools
Packt
03 Sep 2013
8 min read
Save for later

Introduction to Drools

Packt
03 Sep 2013
8 min read
(For more resources related to this topic, see here.) So, what is Drools? The techie answer guaranteed to get that glazed over look from anyone hounding you for details on project design is that Drools, part of the JBoss Enterprise BRMS product since federating in 2005, is a Business Rule Management System (BRMS) and rules engine written in Java which implements and extends the Rete pattern-matching algorithm within a rules engine capable of both forward and backward chaining inference. Now, how about an answer fit for someone new to rules engines? After all, you're here to learn the basics, right? Drools is a collection of tools which allow us to separate and reason over logic and data found within business processes. Ok, but what does that mean? Digging deeper, the keywords in that statement we need to consider are "logic" and "data". Logic, or rules in our case, are pieces of knowledge often expressed as, "When some conditions occur, then do some tasks". Simple enough, no? These pieces of knowledge could be about any process in your organization, such as how you go about approving TPS reports, calculate interest on a loan, or how you divide workload among employees. While these processes sound complex, in reality, they're made up of a collection of simple business rules. Let's consider a daily ritual process for many workers: the morning coffee. The whole process is second nature to coffee drinkers. As they prepare for their work day, they probably don't consider the steps involved—they simply react to situations at hand. However, we can capture the process as a series of simple rules: When your mug is dirty, then go clean it When your mug is clean, then go check for coffee When the pot is full, then pour yourself a cup and return to your desk When the pot is empty, then mumble about co-workers and make some coffee Alright, so that's logic, but what's data? Facts (our word for data) are the objects that drive the decision process for us. Given the rules from our coffee example, some facts used to drive our decisions would be the mug and the coffee pot. While we know from reading our rules what to do when the mug or pot are in a particular state, we need facts that reflect an actual state on a particular day to reason over. In seeing how a BRMS allows us to define the business rules of a business process, we can now state some of the features of a rules engine. As stated before, we've separated logic from data—always a good thing! In our example, notice how we didn't see any detail about how to clean our mug or how to make a new batch of coffee, meaning we've also separated what to do from how to do it , thus allowing us to change procedure without altering logic. Lastly, by gathering all of our rules in one place, we've centralized our business process knowledge. This gives us an excellent facility when we need to explain a business process or transfer knowledge. It also helps to prevent tribal knowledge, or the ownership and understanding of an undocumented procedure by just one or a few users. So when is a BRMS the right choice? Consider a rules engine when a problem is too complex for traditional coding approaches. Rules can abstract away the complexity and prevent usage of fragile implementations. Rules engines are also beneficial when a problem isn't fully known. More often than not, you'll find yourself iterating business methodology in order to fully understand small details involved that are second nature to users. Rules are flexible and allow us to easily change what we know about a procedure to accommodate this iterative design. This same flexibility comes in handy if you find that your logic changes often over time. Lastly, in providing a straightforward approach in documenting business rules, rules engines are an excellent choice if you find domain knowledge readily available, but via non-technical people who may be incapable of contributing to code. Sounds great, so let's get started, right? Well, I promised I'd also help you decide when a rules engine is not the right choice for you. In using a rules engine, someone must translate processes into actual rules, which can be a blessing in taking business logic away from developers, but also a curse in required training. Secondly, if your logic doesn't change very often, then rules might be overkill. Likewise, If your project is small in nature and likely to be used once and forgotten, then rules probably aren't for you. However, beware of the small system that will grow in complexity going forward! So if rules are right for you, why should you choose Drools? First and foremost, Drools has the flexibility of an open source license with the support of JBoss available. Drools also boasts five modules (to be discussed in more detail later), making their system quite extensible with domain-specific languages, graphical editing tools, web-based tools, and more. If you're partial to Eclipse, you'll also likely come to appreciate their plugin. Still not convinced? Read on and give it a shot—after all, that's why you're here, right? Installation In just five easy steps, you can integrate Drools into a new or existing project. Step 1 – what do I need? For starters, you will need to check that you have all of the required elements, listed as follows (all versions are as of time of writing): Java 1.5 (or higher) SE JDK. Apache Maven 3.0.4. Eclipse 4.2 (Juno) and the Drools plugin. Memory—512 MB (minimum), 1 GB or higher recommended. This will depend largely on the scale of your JVM and rule sessions, but the more the better! Step 2 – installing Java Java is the core language on which Drools is built, and is the language in which we'll be writing, so we'll definitely be needing that. The easiest way to get Java going is to download from and follow the installation instructions found at: www.oracle.com/technetwork/java/javase/downloads/index.html Step 3 – installing Maven Maven is a build automation tool from Apache that lets us describe a configuration of the project we're building and leave dependency management (amongst other things) up to it to work out. Again, the easiest way to get Maven up and running is to download and follow the documentation provided with the tool, found at: maven.apache.org/download.cgi Step 4 – installing Eclipse If you happen to have some other IDE of choice, or maybe you're just the old school type, then it's perfectly acceptable to author and execute your Drools-integrated code in your usual fashion. However, if you're an Eclipse fan, or you'd like to take advantage of auto-complete, syntax highlighting, and debugging features, then I recommend you go ahead and install Eclipse and the Drools plugin. The version of Eclipse that we're after is Eclipse IDE for Java Developers, which you can download and find installation instructions for on their site: http://www.eclipse.org/downloads/ Step 5 – installing the Drools Eclipse plugin In order to add the IDE plugin to Eclipse, the easiest method is to use Eclipse's built-in update manager. First, you'll need to add something the plugin depends on—the Graphical Editing Framework (GEF). In the Eclipse menu, click on Help, then on Install New Software..., enter the following URL in the Work with: field, and hit Add. download.eclipse.org/tools/gef/updates/releases/ Give your repository a nifty name in the pop-up window, such as GEF, and continue on with the install as prompted. You'll be asked to verify what you're installing and accept the license. Now we can add the Drools plugin itself—you can find the URL you'll need by visiting: http://www.jboss.org/drools/downloads.html Then, search for the text Eclipse update site and you'll see the link you need. Copy the address of the link to your clipboard, head back into Eclipse, and follow the same process you did for installing GEF. Note that you'll be asked to confirm the install of unsigned content, and that this is expected. Summary By this point, you know what Drools is, you should also be ready to integrate Drools into your applications. If you find yourself stuck, one of the good parts about an open source community is that there's nearly always someone who has faced your problem before and likely has a solution to recommend. Resources for Article : Further resources on this subject: Drools Integration Modules: Spring Framework and Apache Camel [Article] Human-readable Rules with Drools JBoss Rules 5.0(Part 2) [Article] Drools JBoss Rules 5.0 Flow (Part 2) [Article]
Read more
  • 0
  • 0
  • 1696

article-image-working-zend-framework-20
Packt
29 Aug 2013
5 min read
Save for later

Working with Zend Framework 2.0

Packt
29 Aug 2013
5 min read
(For more resources related to this topic, see here.) So, what is Zend Framework? Throughout the years, PHP has become one of the most popular server-side scripting languages on the Internet. This is largely due to its steep learning curve and ease of use. However, these two reasons have also contributed to many of its shortcomings. With minimal restrictions on how you write code with this language, you can employ any style or structure that you prefer, and thus it becomes much easier to write bad code. But there is a solution: use a framework! A framework simplifies coding by providing a highly modular file organization with code libraries of the most common scripting in everyday programming. It helps you develop faster by eliminating the monotonous details of coding and makes your code more re-usable and easier to maintain. There are many popular PHP frameworks out there. A number of them have large, open source communities that provide a wide range of support and offer many solutions. This is probably the main reason why most beginner PHP developers get confused while choosing a framework. I will not discuss the pros and cons of other frameworks, but I will demonstrate briefly why Zend Framework is a great choice. Zend Framework (ZF) is a modern, free, and open source framework that is maintained and developed by a large community of developers and backed by Zend Technologies Ltd, the company founded by the developers of PHP. Currently, Zend Framework is used by a large number of global companies, such as BBC, Discovery, Offers.com, and Cisco. Additionally, many widely used open source projects and recognized frameworks are powered by Zend Framework, such as in the case of Magento, Centurion, TomatoCMS, and PHProjekt. And lastly, its continued development is sponsored by highly recognizable firms such as Google and Microsoft. With all this in mind, we know one thing is certain—Zend Framework is here to stay. Zend Framework has a rich set of components or libraries and that is why it is also known as a component framework. You will find a library in it for almost anything that you need for your everyday project, from simple form validation to file upload. It gives you the flexibility to select a single component to develop your project or opt for all components, as you may need them. Moreover, with the release of Zend Framework 2, each component is available via Pyrus and Composer. Pyrus is a package management and distribution system, and Composer is a tool for dependency management in PHP that allows you to declare the dependent libraries your project needs and installs them in your project for you. Zend Framework 2 follows a 100 percent object-oriented design principle and makes use of all the new PHP 5.3+ features such as namespaces, late static binding, lambda functions, and closures. Now, let’s get started on a quick-start project to learn the basics of Zend Framework 2, and be well on our way to building our first Zend Framework MVC application. Installation ZF2 requires PHP 5.3.3 or higher, so make sure you have the latest version of PHP. We need a Windows-based PC, and we will be using XAMPP (http://www.apachefriends.org/en/xampp.html) for our development setup. I have installed XAMPP on my D: drive, so my web root path for my setup is d:xampphtdocs. Step 1 – downloading Zend Framework To create a ZF2 project, we will need two things: the framework itself and a skeleton application. Download both Zend Framework and the skeleton application from http://framework.zend.com/downloads/latest and https://github.com/zendframework/ZendSkeletonApplication, respectively. Step 2 – unzipping the skeleton application Now put the skeleton application that you have just downloaded into the web root directory (d:xampphtdocs) and unzip it. Name the directory address-book as we are going to create a very small address book application, or you can name it anything you want your project name to be. When you unzip the skeleton application, it looks similar to the following screenshot: Step 3 – knowing the directories Inside the module directory, there is a default module called Application. Inside the vendor directory, there is an empty directory called ZF2. This directory is for the Zend Framework library. Unzip the Zend Framework that you have downloaded, and copy the library folder from the unzipped folder to the vendorZF2 directory. Step 4 – welcome to Zend Framework 2 Now, in your browser, type: http://localhost/address-book/public. It should show a screen as shown in the following screenshot. If you see the same screen, it means you have created the project successfully. And that’s it By this point, you should have a working Zend Framework, and you are free to play around and discover more about it. Summary In this article we will learned what is Zend Framework and will also learn how to install it on Windows PC. Resources for Article: Further resources on this subject: Authentication with Zend_Auth in Zend Framework 1.8 [Article] Building Your First Zend Framework Application [Article] Authorization with Zend_Acl in Zend Framework 1.8 [Article]
Read more
  • 0
  • 0
  • 1693

article-image-how-it-all-fits-together
Packt
31 Aug 2015
4 min read
Save for later

How It All Fits Together

Packt
31 Aug 2015
4 min read
 In this article by Jonathan Hayward author of the book Reactive Programming with JavaScript he explains that Google Maps were a big hit when it came out, and it remains quite important, but the new functionality it introduced was pretty much nothing. The contribution Google made with its maps site was taking things previously only available with a steep learning cliff and giving them its easy trademark simplicity. And that was quite a lot. (For more resources related to this topic, see here.) Similar things might be said about ReactJS. No one at Facebook invented functional reactive programming. No one at Facebook appears to have significantly expanded functional reactive programming. But ReactJS markedly lowered the bar to entry. Previously, with respect to functional reactive programming, there were repeated remarks among seasoned C++ programmers; they said, "I guess I'm just stupid, or at least, I don't have a PhD in computational mathematics." And it might be suggested that proficiency in C++ is no mean feat; getting something to work in Python is less of a feat than getting the same thing to work in C++, just as scaling the local park's winter sledding hill is less of an achievement than scaling Mount Everest. Also, ReactJS introduces enough of changes so that competent C++ programmers who do not have any kind of degree in math, computational or otherwise, stand a fair chance of using ReactJS and being productive in it. Perhaps they may be less effective than pure JavaScript programmers who are particularly interested in functional programming. But learning to effectively program C++ is a real achievement, and most good C++ programmers have a fair chance of usefully implementing functional reactive programming with ReactJS. However, the same cannot be said for following the computer math papers on Wikipedia and implementing something in the academic authors' generally preferred language of Haskell. Here we'll explore a very important topic that is ReactJS as just a view—but what a view! ReactJS is just a view, but what a view! Charles Cézanne famously said, "Monet is just an eye, but what an eye!" Monet didn't try to show off his knowledge of structure and anatomy, but just copy what his eye saw. The consensus judgment of his work holds on to both "just an eye," and "what an eye!" And indeed, the details may be indistinct in Monet, who rebelled against artistry that tried to impress with deep knowledge of anatomy and knowledge of structure that is far beyond what jumps out to the eye. ReactJS is a framework rather than a library, which means that you are supposed to build a solution within the structure provided by ReactJS instead of plugging ReactJS into a solution that you structure yourself. The canonical example of a library is jQuery, where you build a solution your way, and call on jQuery as it fits into a structure that you design. However, ReactJS is specialized as a view. It's not that this is necessarily good or bad, but ReactJS is not a complete web development framework, and does not have even the intension of being the only tool you will ever need. It focuses on being a view, and in Facebook's offering, this does not include any form of AJAX call. This is not a monumental oversight in developing ReactJS; the expectation is that you use ReactJS as a View to provide the user interface functionality, and other tools to meet other needs as appropriate. This text hasn't covered using ReactJS together with your favorite tools, but do combine your favorite tools with ReactJS if they are not going to step on each other's feet. ReactJS may or may not collide with other Views, but it is meant to work with non-View technologies. Summary In this article, we looked at ReactJS as a view and also learned that ReactJS is not a complete web development framework. Resources for Article: Further resources on this subject: An Introduction to Reactive Programming[article] Kivy – An Introduction to Mastering JavaScript Promises and Its Implementation in Angular.js[article] Object-Oriented JavaScript with Backbone Classes [article]
Read more
  • 0
  • 0
  • 1692
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-navigation-widgets-and-styles-microsoft-silverlight-4
Packt
09 Apr 2010
5 min read
Save for later

Navigation Widgets and Styles in Microsoft Silverlight 4

Packt
09 Apr 2010
5 min read
Retrofitting a website The first thing the client would like to do to their website is spice it up with a new navigation control and a playful, interactive logo for the top of the page. First, we'll work on a navigation control to replace the text links on the left hand side of the page of the current website. As you will notice in the following image, the current website navigation mechanism isn't fancy, but it's simple. However, the client would like the website to be more modern, while preserving ease of use. Adding pizzazz with Silverlight Cake-O-Rama would like to add a fancy navigation widget to their site. They've commissioned a graphic artist to create the following look for the widget.   A few words on search engine optimization We could easily create a Silverlight application that would encompass all the content and functionality of a whole website. However, doing so would severely limit the website's visibility to search engines. Search engines have programs called spiders, or robots, that 'crawl' the internet scanning for content. Generally, these programs can only see text exposed in the HTML. Search results are ranked based on this text-only content. Placing all our content inside a rich internet application platform like Silverlight would effectively hide all of our content. The net result would be reduced visibility on search engines. All Rich Internet Application (RIA) platforms have this issue with search engine visibility. Until this problem is resolved, the best approach is to augment the page's HTML content on sites that you want to be found more easily by search engines. Building a navigation control from the ground up Silverlight 4 has the Grid, Canvas, StackPanel, Border, WrapPanel, ViewBox, and ScrollViewer layout panels. Why are there so many? Well, each one serves a unique purpose. Picking the right kind of container You wouldn't fill a cardboard box with water or drink milk out of a gasoline can, would you? The same could be said of the various layout containers in Silverlight, each one serves a unique purpose and some are better at certain tasks than others. For instance, when you want to create a toolbar, you would probably use a StackPanel or WrapPanel , and not a Canvas. Why? While you could manually code the layout logic to place all the child controls, there's no good reason to. After all, there are already controls to do the heavy lifting for you. Below are the most common layout containers in Silverlight 4: Container Layout Behavior Canvas Manual positioning of items using X and Y coordinates Grid Lays out items using a defined grid of rows and columns InkPresenter Canvas that can handle digital ink StackPanel Stacks items on top of or next to one another WrapPanel Lines up items and wraps them around Border Draws a border around an item Viewbox Scales an item up to take up all the available space ScrollViewer Places a scroll bar around the control Silverlight also provides the means to write your own layout code. While there may be situations where this is warranted, first think about how you can achieve the desired result with a combination of the existing containers. Stack it up: Using the StackPanel Based on the website's current navigation links, StackPanel seems like the best choice. As the name implies, it lays out child controls in a stack, which seems like a good fit for our list of links. Time for action – building navigation buttons in Silverlight Now, let's make a StackPanel of button controls to navigate around the site. In order to do this, we will need to do the following: Launch Visual Studio 2010 and click on File|New Project. Choose to create a new Silverlight Application as shown in the next screen: Name the project CakeNavigationButtons and click OK to accept the default settings. In the MainPage.xaml file, write the following lines of XAML inside the Grid tag: <StackPanel> <Button Content="Home" /> <Button Content="Gallery"/> <Button Content="Order"/> <Button Content="Locations"/> <Button Content="Contact Us"/> <Button Content="Franchise Opportunities"/></StackPanel> Return to Visual Studio 2010 and click on Debug|Start Debugging or press F5 to launch the application. On the following screen, click OK to enable debugging. Your application should look something like this: We have now created a StackPanel of button controls to navigate around the website using Silverlight, but the application is not exactly visually appealing, not to mention, the buttons don't do anything. What we need them to do is reflect the design we've been provided with and navigate to a given page when the user clicks on them. What just happened? What we created here is the foundation for what will eventually become a dynamic navigation control. You have created a new Silverlight application, added a StackPanel, and then added button controls to it. Now, let's move on to make this little navigation bar sparkle. Adding a little style with Styles Many people refer to Silverlight controls as being "lookless", which may sound strange at first as they clearly have a "look." The term refers to the fact that the logic in a control defines its behavior rather than its appearance. That means that all the controls you've seen in Silverlight so far have no presentation logic in them. Their look comes from a default resource file. The good news is that we can create our own resources to customize the look of any control. You can re-style a control in Silverlight in much the same way as you can in Cascading Style Sheets (CSS).
Read more
  • 0
  • 0
  • 1679

article-image-soa-java-business-integration-part-2
Packt
16 Oct 2009
6 min read
Save for later

SOA with Java Business Integration (part 2)

Packt
16 Oct 2009
6 min read
(For more resources on this subject, see here.) Provider—Consumer Contract In the JBI environment, the provider and consumer always interact based on a services model. A service interface is the common aspect between them. WSDL 1.1 and 2.0 are used to define the contract through the services interface. The following figure represents the two parts of the WSDL representation of a service: In the Abstract Model, WSDL describes the propagation of a message through a type system. A message has sequence and cardinality specified by its Message Exchange Pattern (MEP). A Message can be a Fault Message also. An MEP is associated with one or more messages using an Operation. An Interface can contain a single Operation or a group of Operations represented in an abstract fashion—independent of wire formats and transport protocols. An Interface in the Abstract Model is bound to a specific wire format and transport protocol via Binding. A Binding is associated with a network address in an Endpoint and a single Service in the concrete model aggregates multiple Endpoints implementing common interfaces. Detached Message Exchange JBI-based message exchange occurs between a Provider and Consumer in a detached fashion. This means, the Provider and Consumer never interact directly. In technical terms, they never share the same thread context of execution. Instead, the Provider and Consumer use JBI NMR as an intermediary. Thus, the Consumer sends a request message to the NMR. The NMR, using intelligent routers decides the best matched service provider and dispatches the message on behalf of the Consumer. The Provider component can be a different component or the same component as the Consumer itself. The Provider can be an SE or a BC and based on the type it will execute the business process by itself or delegate the actual processing to the remotely bound component. The response message is sent back to the NMR by the Provider, and the NMR in turn passes it back to the Consumer. This completes the message exchange. The following figure represents the JBI-based message exchange: There are multiple patterns by which messages are exchanged, which we will review shortly. Provider—Consumer Role Though a JBI component can function as a Consumer, a Provider, or as both a Consumer and Provider, there is clear cut distinction between the Provider and Consumer roles. These roles may be performed by bindings or engines, in any combination of the two. When a binding acts as a service Provider, an external service is implied. Similarly, when the binding acts as a service Consumer, an external Consumer is implied. In the same way, the use of a Service Engines in either role implies a local actor for that role. This is shown in the following figure: The Provider and Consumer interact with each other through the NMR. When they interact, they perform the distinct responsibilities (not necessarily in the same order). The following is the list of responsibilities, performed by the Provider and Consumer while interacting with NMR: Provider: Once deployed, the JBI activates the service provider endpoint. Provider: Provider then publishes the service description in WSDL format. Consumer: Consumer then discovers the required service. This can happen at design time (static binding) or run time (dynamic binding). Consumer: Invokes the queried service. Provider and Consumer: Send and respond to message exchanges according to the MEP, and state of the message exchange instance. Provider: Provides the service by responding to the function invocations. Provider and Consumer: Responds with status (fault or done) to complete the message exchange. During run-time activation, a service provider activates the actual services it provides, making them known to the NMR. It can now route service invocations to that service. javax.jbi.component.ComponentContext context ;// Initialized via. AOPjavax.jbi.messaging.DeliveryChannel channel = context. getDeliveryChannel();javax.jbi.servicedesc.ServiceEndpoint serviceEndpoint = null; if (service != null && endpoint != null) { serviceEndpoint = context.activateEndpoint (service, endpoint); } The Provider creates a WSDL described service available through an endpoint. As described in the Provider-Consumer contract, the service implements a WSDL-based interface, which is a collection of operations. The consumer creates a message exchange to send a message to invoke a particular service. Since consumers and providers only share the abstract service definition, they are decoupled from each other. Moreover, several services can implement the same WSDL interface. Hence, if a consumer sends a message for a particular interface, the JBI might find more than one endpoint conforming to the interface and can thus route to the best-fit endpoint. Message Exchange A message exchange is the "Message Packet" transferred between a consumer and a provider in a service invocation. It represents a container for normalized messages which are described by an exchange pattern. Thus message exchange encapsulates the following: Normalized message Message exchange metadata Message exchange state Thus, message exchange is the JBI local portion of a service invocation. Service Invocation An end-to-end interaction between a service consumer and a service provider is a service invocation. Service consumers employ one or more service invocation patterns. Service invocation through a JBI infrastructure is based on a 'pull' model, where a component accepts message exchange instances when it is ready. Thus, once a message exchange instance is created, it is sent back and forth between the two participating components, and this continues till the status of the message exchange instance is either set to 'done' or 'error', and sent one last time between the two components. Message Exchange Patterns (MEP) Service consumers interact with service providers for message exchange employing one or more service invocation patterns. The MEP defines the names, sequence, and cardinality of messages in an exchange. There are many service invocation patterns, and, from a JBI perspective, any JBI-compliant ESB implementation must support the following four service invocations: One-Way: Service consumer issues a request to the service provider. No error (fault) path is provided. Reliable One-Way: Service consumer issues a request to the service provider. Provider may respond with a fault if it fails to process the request. Request-Response: Service Consumer issues a request to the service provider, with expectation of response. Provider may respond with a fault if it fails to process request. Request Optional-Response: Service consumer issues a request to the service provider, which may result in a response. Both consumer and provider have the option of generating a fault in response to a message received during the interaction. The above service invocations can be mapped to four different MEPs that are listed as follows. In-Only MEP In-Only MEP is used for one-way exchanges. The following figure diagrammatically explains the In-Only MEP: In the In-Only MEP normal scenario, the sequence of operations is as follows: Service Consumer initiates with a message. Service Provider responds with the status to complete the message exchange. In the In-Only MEP normal scenario, since the Consumer issues a request to the Provider with no error (fault) path, any errors at the Provider-level will not be propagated to the Consumer.    
Read more
  • 0
  • 0
  • 1676

article-image-jboss-tools-palette
Packt
26 Oct 2009
4 min read
Save for later

JBoss Tools Palette

Packt
26 Oct 2009
4 min read
By default, JBoss Tools Palette is available in the Web Development perspective that can be displayed from the Window menu by selecting the Open Perspective | Other option. In the following screenshot, you can see the default look of this palette: Let's dissect this palette to see how it makes our life easier! JBoss Tools Palette Toolbar Note that on the top right corner of the palette, we have a toolbar made of three buttons (as shown in the following screenshot). They are (from left to right): Palette Editor Show/Hide Import Each of these buttons accomplishes different tasks for offering a high level of flexibility and customizability. Next, we will focus our attention on each one of these buttons. Palette Editor Clicking on the Palette Editor icon will display the Palette Editor window (as shown in the following screenshot), which contains groups and subgroups of tags that are currently supported. Also, from this window you can create new groups, subgroups, icons, and of course, tags—as you will see in a few moments. As you can see, this window contains two panels: one for listing groups of tag libraries (left side) and another that displays details about the selected tag and allows us to modify the default values (extreme right). Modifying a tag is a very simple operation that can be done like this: Select from the left panel the tag that you want to modify (for example, the <div> tag from the HTML | Block subgroup, as shown in the previous screenshot). In the right panel, click on the row from the value column that corresponds to the property that you want to modify (the name column). Make the desirable modification(s) and click the OK button for confirming it (them). Creating a set of icons The Icons node from the left panel allows you to create sets of icons and import new icons for your tags. To start, you have to right-click on this node and select the Create | Create Set option from the contextual menu (as shown in the following screenshot). This action will open the Add Icon Set window where you have to specify a name for this new set. Once you're done with the naming, click on the Finish button (as shown in the following screenshot). For example, we have created a set named eHTMLi: Importing an icon You can import a new icon in any set of icons by right-clicking on the corresponding set and selecting the Create | Import Icon option from the contextual menu (as shown in the following screenshot): This action will open the Add Icon window, where you have to specify a name and a path for your icon, and then click on the Finish button (as shown in the following screenshot). Note that the image of the icon should be in GIF format. Creating a group of tag libraries As you can see, the JBoss Tools Palette has a consistent default set of groups of tag libraries, like HTML, JSF, JSTL, Struts, XHTML, etc. If these groups are insufficient, then you can create new ones by right-clicking on the Palette node and selecting the Create | Create Group option from the contextual menu (as shown in the following screenshot). This action will open the Create Group window, where you have to specify a name for the new group, and then click on Finish. For example, we have created a group named mygroup: Note that you can delete (only groups created by the user) or edit groups (any group) by selecting the Delete or Edit options from the contextual menu that appears when you right-click on the chosen group. Creating a tag library Now that we have created a group, it's time to create a library (or a subgroup). To do this, you have to right-click on the new group and select the Create Group option from the contextual menu (as shown in the following screenshot). This action will open the Add Palette Group window, where you have to specify a name and an icon for this library, and then click on the Finish button (as shown in the following screenshot). As an example, we have created a library named eHTML with an icon that we had imported in the Importing an icon section discussed earlier in this article: Note that you can delete a tag library (only tag libraries created by the user) by selecting the Delete option from the contextual menu that appears when you right-click on the chosen library.
Read more
  • 0
  • 0
  • 1669

article-image-event-driven-bpel-process
Packt
19 Sep 2014
5 min read
Save for later

Event-driven BPEL Process

Packt
19 Sep 2014
5 min read
In this article, by Matjaz B. Juric and Denis Weerasiri, authors of the book WS-BPEL 2.0 Beginner's Guide, we will study about the event-driven BPEL process. We will learn to develop a book shelving BPEL process. (For more resources related to this topic, see here.) Developing an event-driven BPEL process Firstly, we will develop an event-driven BPEL process. This is a BPEL process triggered by a business event. We will develop a process for book shelving. As we have already mentioned, such a process can be executed on various occasions, such as when a book arrives to the bookstore for the first time, after a customer has looked at the book, or even during an inventory. In contrast to a BPEL process, which exposes an operation that needs to be invoked explicitly, our book shelving process will react on a business event. We will call it a BookshelfEvent. We can see that in order to develop an event-driven BPEL process, we will need to firstly declare a business event, the BookshelfEvent. Following this, we will need to develop the event-driven book shelving BPEL process. Declaring a business event We will declare the BookshelfEvent business event, which will signal that a book is ready to be book shelved. Each business event contains a data payload, which is defined by the corresponding XML schema type. In our case, we will use the BookData type, the same one that we used in the book warehousing process. Time for action – declaring a business event To declare the BookshelfEvent business event, we will go to the composite view. We will proceed as follows: Right-click on the project in the Application window and select New and then Event Definition: A Create Event Definition dialog box will open. We will specify the EDL filename. This is the file where all the events are defined (similar to WSDL, where the web service operations are defined). We will use the BookEDL for the EDL filename. For the Namespace field, we will use http://packtpub.com/events/edl/BookEDL, as shown in the following screenshot: Next, we need to define the business events. We will use the green plus sign to declare the BookshelfEvent business event. After clicking on the green plus sign, the Create Event dialog box will open. We need to specify the event name, which is BookshelfEvent. We also have to specify the XML Type, which will be used for the event data payload. We will use the BookData from the Book Warehousing BPEL process schema, as shown in the following screenshot: After clicking on the OK button, we should see the following: What just happened? We have successfully declared the BookshelfEvent business event. This has generated the BookEDL.edl file with the source code as shown in the following screenshot: Developing a book shelving BPEL process After declaring the business event, we are ready to develop the event-driven book shelving BPEL process. The process will be triggered by our BookshelfEvent business event. This means that the process will not have a classic WSDL with the operation declaration. Rather it will be triggered by the BookshelfEvent business event. Time for action – developing an event-driven book shelving BPEL process To develop the event-driven book shelving BPEL process, we will go to the composite view. We will carry out the following steps: Drag-and-drop the BPEL Process service component from the right-hand side toolbar to the composite components area. The Create BPEL Process dialog box will open. We will select the BPEL 2.0 Specification, type BookShelvingBPEL for the Name of the process, and specify the namespace as http://packtpub.com/Bookstore/BookShelvingBPEL. Then, we will select Subscribe to Events from the drop-down list for the Template: Next, we will need to specify the event to which our BPEL process will be subscribed. We will select the green plus sign and the Event Chooser dialog window will open. Here, we will simply select the BookshelfEvent business event: After clicking on the OK button, we should see the following screenshot: For event-driven BPEL processes, three consistency strategies for delivering events exist. The one and only one option delivers the events in the global transaction. Guaranteed delivers events asynchronously without a global transaction. Immediate delivers events in the same global transaction and the same thread as the publisher, and the publish call does not return until all immediate subscribers have completed processing. After clicking on the OK button, we can find the new BookShelvingBPEL process on the composite diagram. Please note that the arrow icon denotes that the process is triggered by an event: Double-clicking on the BookShelvingBPEL process opens the BPEL editor, where we can see that the BPEL process has a slightly different <receive> activity, which denotes that the process will be triggered by an event. Also, notice that an event-driven process does not return anything to the client, as event-driven processes are one-way and asynchronous: What just happened? We have successfully created the BookShelvingBPEL process. Looking at the source code we can see that the overall structure is the same as with any other BPEL process. The difference is in the initial <receive> activity, which is triggered by the BookshelfEvent business event, as shown in the following screenshot: Have a go hero – implementing the BookShelvingBPEL process Implementing the event-driven BookShelvingBPEL process does not differ from implementing any other BPEL process. Therefore, it's your turn now. You should implement the BookShelvingBPEL process to do something meaningful. It could, for example, call a service which will query a database table. Or, it could include a human task. Summary In this article, we learned how to develop event-driven BPEL processes and how to invoke events from BPEL processes. We also learned to implement the BookShelvingBPEL process. Resources for Article: Further resources on this subject: Securing a BPEL process [Article] Scopes in Advanced BPEL [Article] Advanced Activities in BPEL [Article]
Read more
  • 0
  • 0
  • 1655
article-image-article-creating-holiday-request-infopath-form-publishing-form-library
Packt
02 Nov 2011
3 min read
Save for later

Creating a holiday request InfoPath form and publishing it to a form library

Packt
02 Nov 2011
3 min read
(For more resources on Microsoft Sharepoint, see here.) Creating a holiday request InfoPath form and publishing it to a form library InfoPath forms are capable of containing repeating data, optional fields, and presenting different views to different users. To access the full power of InfoPath, you will want to create a custom form and publish it to a SharePoint form library. In this recipe we learn how to create a holiday request form and publish it to SharePoint. Getting ready This recipe works for: SharePoint 2010 Enterprise Edition Office 365 (SharePoint Online) You will need a SharePoint site where you want to create an InfoPath form. This recipe creates a holiday request form for illustration. You will need the Design or Full Control permission level to run this recipe. You will need InfoPath Designer 2010 installed on your client machine. How to do it... Open the Microsoft InfoPath Designer 2010 on your computer. The backstage view is displayed. Double click the on SharePoint Form Library button. A new blank form opens. Change the form title to Holiday Request. Change the first subheading to Employee Details. Place the cursor on the first Add control cell in the Employee Details table. Click on Text Box in the Controls section of the Home ribbon. A new textbox will be inserted into the form (field1) and a new field is added to the forms data source (Fields view). Double on click field1 in the Fields view to open the properties dialog. Rename the field to FirstName and click on the OK button. Repeat steps 4 and 5 to add textboxes for LastName, EmailAddress, and Department. Add labels to the form for each of the textboxes that you have added. Highlight the last row in the Employee Details table and delete it. Rename the next section in the form Holiday Details. Add labels for Start Date and End Date. Expand the Controls section in the ribbon. Select the Date Picker control. Add date controls for StartDate and EndDate to the form. Click on the File tab to access the backstage view. Click on the Publish button. The Publish options are displayed. Click on the SharePoint Server button. You will be prompted to first save your form template. Enter the filename holidayrequest.xsn and click on the Save button. The Publishing Wizard will open. Enter the URL of the SharePoint site where you want to publish your form and click on the Next button. Tick the Enable this form to be filled out using a browser. Select the Form Library option. Click on the Next button. Select the Create a new form library option. Click on the Next button. Name the new library Holiday Requests. Click on the Next button. To promote data items in the form to SharePoint list columns, click on the Add button. Select the FirstName column and click on the OK button. Repeat for the LastName, EmailAddress, Department, StartDate, and EndDate fields. Click on the Publish button. The form is published to SharePoint. Click on the Open this form in a browser link. The InfoPath form opens in the web browser. Enter some data to test the form and click on the Save button. You will be prompted for a filename for your form. Enter request1 and click on Save. Your holiday request is saved to the form library. Click on the Close button.
Read more
  • 0
  • 0
  • 1651

article-image-connecting-web-service-should-know
Packt
26 Sep 2013
8 min read
Save for later

Connecting to a web service (Should know)

Packt
26 Sep 2013
8 min read
(For more resources related to this topic, see here.) Getting ready This recipe is going to log a large JSON message to the console, so large that it will actually overflow STS's default console buffer. To ensure that we don't miss anything, we're going to change STS's configuration to have an unlimited console buffer. Open the Preferences dialog by selecting Window | Preferences from the menu if you are running Windows, or by pressing ?+, if you are using a Mac. Open the Run/Debug item and select the Console item. Uncheck the Limit console output checkbox, and then click on the OK button. How to do it... Let's start by creating our project and updating its dependencies. Launch the New Spring Project wizard by navigating to File | New | Spring Project in the menu. In the dialog box, enter the project name WebServiceProject, expand the Integration folder, and select Spring Integration Project (Standalone) – Simple. Click on the Next button. Allow STS to download the project template if you are prompted to do so. Enter the groupId as com.example, artifactId as web-service-project, and top-level package as com.example.webserviceproject. Click on the Finish button to create the project. Open the Maven pom.xml file. Click on the Dependencies tab, and add the following dependencies: org.springframework.integration : spring-integrationhttp : ${spring.integration.version} org.springframework : spring-test : 3.1.3.RELEASE (Spring Integration 2.2.4.RELEASE depends on this version of Spring, and it's a good idea to be consistent) org.codehaus.jackson : jackson-core-asl : 1.9.12 org.codehaus.jackson : jackson-mapper-asl : 1.9.12 Save the file to update the project's dependencies. Now let's create an integration test. Expand the src/test/java source folder, right-click on the top-level package under it, and select New | JUnit Test Case from the pop-up menu. Name the test WebServiceTest, and click on the Finish button. We're creating a Spring context test, so add the following annotations to the top of the class: @ContextConfiguration(locations = "classpath:META-INF/spring/integration/spring-integration-context.xml")@RunWith(SpringJUnit4ClassRunner.class) Our test is going to send a Spring Integration message down one channel and then wait for a response on another channel. We need to inject the following two channels into our test: @Autowired private MessageChannel weatherRequest;@Autowired private SubscribableChannel weatherResponse; Create the following test case: @Testpublic void shouldRetrieveWeatherDataFromWebService() {weatherResponse.subscribe(new MessageHandler() {@Overridepublic void handleMessage(Message<?> message)throws MessagingException {Map payload = (Map) message.getPayload();Map observations = (Map) payload.get("observations");List data = (List) observations.get("data");Map latestData = (Map) data.get(0);assertNotNull(latestData);assertEquals("Sydney - Observatory Hill",latestData.get("name"));assertNotNull(latestData.get("air_temp"));assertNotNull(latestData.get("local_date_time_full"));}});weatherRequest.send(MessageBuilder.withPayload(new WeatherRequest("N", "94768")).build());} Add all required imports using Quick Fixes. The instantiation of the WeatherRequest object will cause a compilation error because the class does not yet exist. Use a Quick Fix to create the class, taking care to change its source folder to WebServiceProject/src/main/java. Create the class as follows: package com.example.webserviceproject;public class WeatherRequest {private final String stateCode;private final String locationId;public WeatherRequest(String stateCode, String locationId) {this.stateCode = stateCode;this.locationId = locationId;}public String getStateCode() {return stateCode;}public String getLocationId() {return locationId;}} Run the test. It will fail, complaining that no Spring beans could be injected into our test. We have our failing test. Now it's time to create our integration pipeline. Open spring-integration-context.xml (found in the src/main/ resources/META-INF/spring/integration folder). Click on the Namespaces tab. You will find that the int namespace is already checked. Check the int-http namespace as well. Click on the integration-graph tab and maximize the editor to give yourself more space. This template project has already created an integration pipeline for us, but we want to create our own, so select all of the components in the workspace area by dragging a box around them, and then press the Delete key to remove them. Expand the Channels category and drag a channel component into the workspace. Double-click on it to bring up its properties in the Properties view. Change its id to weatherRequest. Remember to close the Properties view after editing the properties of each integration component. Drag another channel component into the workspace, and use the Properties view to set its id to weatherServiceResponse. Drag a publish-subscribe-channel component into the workspace. Give it the id weatherResponse. Drag a logging-channel-adapter component into the workspace. Give it the id logger, set its level to INFO, and its logger-name to com.example. webserviceproject.webserviceresponse. Now expand the http category and drag an outbound-gateway component into the workspace. Set its id property to weatherService, its url property to http://www.bom.gov.au/fwo/ID{stateCode}60901/ ID{stateCode}60901.{locationId}.json, its http-method to GET, and expected-response-type to java.lang.String. Expand the Transformation category and drag a json-to-object-transformer component into the workspace. Set its type property to java.util.HashMap. Now we need to connect everything together. Select the connection tool from the palette and make the following connections: weatherRequest channel to weatherService gateway weatherService gateway to weatherServiceResponse channel weatherServiceResponse channel to json-to-object-transformer json-to-object-transformer to weatherResponse channel Select the mapping/recipient/wire-tap tool from the palette and create a connection from the weatherServiceResponse channel to the logging-channel-adapter channel. Our pipeline should now look like the following figure: Select the integration tab. In the Integration Overview panel, expand all of the beans and then right-click on the int-http:outbound-gateway bean. Select Insert <int-http:uri-variable> element from the pop-up menu. This will create a new sub element and show its properties on the right side of editor. Set its name property to stateCode and its expression to payload.stateCode. Create another uri-variable property, setting its name to locationId, and its expression to payload.locationId. And we're done! Save the file, then re-run the WebServiceTest. If all was configured correctly, the test will take a few seconds to run (it has to contact the web service), and then you should be rewarded with a green bar. Maximize the Console view, and you will find the JSON string returned from the web service. How it works... In this recipe, we used a few different Spring Integration components to make a request to a web service and to transform its response to a Map class so that our test could pick out pieces of data. We also used a wire tap component to log messages to the console. Channels We have seen a couple of different channel implementations in action in this recipe. The weatherRequest and weatherService channels are examples of the default Spring Integration channel, DirectChannel , which is a simple point-to-point channel (that is, there is one sender on one side of the channel and one receiver on the other). By contrast, the weatherRequest channel is a PublishSubscribeChannel , which allows for multiple receivers to register for message events (in our test, we only had the one).Spring Integration provides a number of other channel types designed for different requirements. See the Spring Integration Reference Manual ( http://static.springsource.org/spring-integration/reference/htmlsingle ) for further information. URI variables You would have noticed when setting the URL property of the HTTP outbound gateway that the value included two placeholders, namely {stateCode} and {locationId}. We configured a URL variable for each of these, giving them the values payload.stateCode and payload.locationId respectively. These are simply JavaBean property references. In our case, the payload was a WeatherRequest instance, and we had defined both the stateCode and locationId JavaBean properties on that class. The values of those properties are substituted into the placeholders in the configured URL string to determine the actual URL requested. Wire taps and logging When we connected the weatherServiceResponse channel with logging-channel-adapter, under the hood, STS configured a special type of channel interceptor called a wire tap. A wire tap takes messages passing through a channel, and sends a copy to another channel. This makes them excellent for logging and auditing purposes. When we configured our logging-channel-adapter , we told it to log at the INFO level using the logger name com.example.webserviceproject.webserviceresponse . We could have used any name, of course, but the log4j configuration provided in the project template (the log4j.xml file under src/main/resources ) already had an INFO level logging threshold configured for com.example.webserviceproject loggers, so it was convenient for us to choose the logger name that we did. Summary In this article, we retrieved weather data from the Australian Bureau of Meteorology and also learned about how STS and Spring Integration allow us to interact with web services with very little effort. Resources for Article : Further resources on this subject: Vaadin project with Spring and Handling login with Spring [Article] So, what is Spring for Android? [Article] Migration to Spring Security 3 [Article]
Read more
  • 0
  • 0
  • 1644

article-image-developing-web-applications-using-javaserver-faces-part-2
Packt
27 Oct 2009
5 min read
Save for later

Developing Web Applications using JavaServer Faces: Part 2

Packt
27 Oct 2009
5 min read
JSF Validation Earlier in this article, we discussed how the required attribute for JSF input fields allows us to easily make input fields mandatory. If a user attempts to submit a form with one or more required fields missing, an error message is automatically generated. The error message is generated by the <h:message> tag corresponding to the invalid field. The string First Name in the error message corresponds to the value of the label attribute for the field. Had we omitted the label attribute, the value of the fields id attribute would have been shown instead. As we can see, the required attribute makes it very easy to implement mandatory field functionality in our application. Recall that the age field is bound to a property of type Integer in our managed bean. If a user enters a value that is not a valid integer into this field, a validation error is automatically generated. Of course, a negative age wouldn't make much sense, however, our application validates that user input is a valid integer with essentially no effort on our part. The email address input field of our page is bound to a property of type String in our managed bean. As such, there is no built-in validation to make sure that the user enters a valid email address. In cases like this, we need to write our own custom JSF validators. Custom JSF validators must implement the javax.faces.validator.Validator interface. This interface contains a single method named validate(). This method takes three parameters: an instance of javax.faces.context.FacesContext, an instance of javax.faces.component.UIComponent containing the JSF component we are validating, and an instance of java.lang.Object containing the user entered value for the component. The following example illustrates a typical custom validator. package com.ensode.jsf.validators;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.faces.application.FacesMessage;import javax.faces.component.UIComponent;import javax.faces.component.html.HtmlInputText;import javax.faces.context.FacesContext;import javax.faces.validator.Validator;import javax.faces.validator.ValidatorException;public class EmailValidator implements Validator { public void validate(FacesContext facesContext, UIComponent uIComponent, Object value) throws ValidatorException { Pattern pattern = Pattern.compile("w+@w+.w+"); Matcher matcher = pattern.matcher( (CharSequence) value); HtmlInputText htmlInputText = (HtmlInputText) uIComponent; String label; if (htmlInputText.getLabel() == null || htmlInputText.getLabel().trim().equals("")) { label = htmlInputText.getId(); } else { label = htmlInputText.getLabel(); } if (!matcher.matches()) { FacesMessage facesMessage = new FacesMessage(label + ": not a valid email address"); throw new ValidatorException(facesMessage); } }} In our example, the validate() method does a regular expression match against the value of the JSF component we are validating. If the value matches the expression, validation succeeds, otherwise, validation fails and an instance of javax.faces.validator.ValidatorException is thrown. The primary purpose of our custom validator is to illustrate how to write custom JSF validations, and not to create a foolproof email address validator. There may be valid email addresses that don't validate using our validator. The constructor of ValidatorException takes an instance of javax.faces.application.FacesMessage as a parameter. This object is used to display the error message on the page when validation fails. The message to display is passed as a String to the constructor of FacesMessage. In our example, if the label attribute of the component is not null nor empty, we use it as part of the error message, otherwise we use the value of the component's id attribute. This behavior follows the pattern established by standard JSF validators. Before we can use our custom validator in our pages, we need to declare it in the application's faces-config.xml configuration file. To do so, we need to add a <validator> element just before the closing </faces-config> element. <validator> <validator-id>emailValidator</validator-id> <validator-class> com.ensode.jsf.validators.EmailValidator </validator-class></validator> The body of the <validator-id> sub element must contain a unique identifier for our validator. The value of the <validator-class> element must contain the fully qualified name of our validator class. Once we add our validator to the application's faces-config.xml, we are ready to use it in our pages. In our particular case, we need to modify the email field to use our custom validator. <h:inputText id="email" label="Email Address" required="true" value="#{RegistrationBean.email}"> <f:validator validatorId="emailValidator"/></h:inputText> All we need to do is nest an <f:validator> tag inside the input field we wish to have validated using our custom validator. The value of the validatorId attribute of <f:validator> must match the value of the body of the <validator-id> element in faces-config.xml. At this point we are ready to test our custom validator. When entering an invalid email address into the email address input field and submitting the form, our custom validator logic was executed and the String we passed as a parameter to FacesMessage in our validator() method is shown as the error text by the <h:message> tag for the field.
Read more
  • 0
  • 0
  • 1641
article-image-working-local-files-simple
Packt
05 Aug 2013
8 min read
Save for later

Working with local files (Simple)

Packt
05 Aug 2013
8 min read
(For more resources related to this topic, see here.) Getting ready Now that you have Mercurial set up on your computer, you are going to use it to track all the changes that can happen in a configuration directory, for example, in the configuration files of Apache2 (a web server). It could of course be used in any other type of directory and files: your home directory configuration files, some personal development projects, or some Mozilla Firefox configuration files such as user.js and prefs.js, and likewise. If you do not have Apache2 installed on your computer, you can do the same type of exercises, for instance, in $HOME/src. Also, with the owners of the /etc/apache2 files being root, you will need to change their owner to your account. For example, your username/group both being mary/mary: $ sudo chown -R mary:mary /etc/apache2/ How to do it... The first thing to do is to initialize a new repository by typing these lines: $ cd /etc/apache2/$ hg init You can then show the status of the files in your new repository, that is, which files are tracked and which are unknown to Mercurial, and also which files have changed, which have been deleted, and so on. This is done using the Mercurial status command: $ hg status? apache2.conf? conf.d/charset? […]? sites-available/default-ssl? sites-enabled/000-default As you can see, everything is untracked right now. The way to tell Mercurial which files you want to be version controlled and added to your newly created repository is by using the add command. For example, if you want to track changes in the apache2.conf file, and all the files of the sites-available directory, you need to type: $ hg add apache2.conf sites-available/ Showing the status again, Mercurial now tells us that three files have been added (by showing A, which denotes Added ; instead of ?—, denoting Unknown , in front of its path): $ hg statusA apache2.confA sites-available/defaultA sites-available/default-ssl? conf.d/charset[…] Now if you want to record the initial version of these files (the one provided by your distribution), you need to use the commit command and add a log message using the -m option: $ hg commit -m"initial version" Using the log command, you can print the entire history of your repository (here you used commit only once, so only one change—called a changeset —is listed): $ hg logchangeset: 0:7b3b5fcb16d0tag: tipuser: Mary <mary@company.com> […date…]summary: initial version Whenever you change a file, you can record the modification in Mercurial with the commit command. Let's type the following sequence using the status, diff, commit, and log commands: $ vi apache2.conf..make some changes: add "# new line" at the end of the file$ hg status -mM apache2.conf$ hg diffdiff -r 7b3b5fcb16d0 apache2.conf […]+# new line$ hg commit -m"added a line at the end"$ hg logchangeset: 1:02704fcf58b1user: Mary <mary@company.com>summary: added a line at the endchangeset: 0:7b3b5fcb16d0 […] You can also reverse the modifications; for instance, if you modify a line again in apache2.conf, such as changing # new line by # new linez, using the diff command, you can see your modification: $ hg diffdiff -r b0d2bfb95d81 apache2.conf […]-# new line+# new linez It is then possible to come back to the latest saved version using the revert command: $ hg revert apache2.conf$ hg status? apache2.conf.orig$ tail -1 apache2.conf# new line At this stage, you can't see the M apache2.conf file any more, and the value at the last line is the one that is not modified, but there is a new file called apache2.conf.orig; this is because the revert command saves your modifications in a backup file. You can either delete it afterward or you can use the --no-backup option if you know what you do. Mercurial has a conservative philosophy to avoid losing data. Finally, if you realize that you do not need a file any more, you can remove it from being version controlled and from your working directory by using the remove command. For example, if you don't need the SSL configuration file of Apache, you can remove it by typing: $ hg remove sites-available/default-ssl$ hg statusR sites-available/default-ssl Instant Mercurial Distributed SCM Essential How-to13$ hg commit -m"removed unused ssl conf file"$ ls sites-available/default Note that the file has disappeared from your working directory, and even if you create a file with the same name, it will not be version controlled anymore (unless you add it again). But, of course, it is still possible to get it back or to get a version of apache2.conf exactly how it came with the distribution. In order to do that, you need to use the update command and ask to switch to revision 0: $ hg update -C 0$ ls sites-available/default default-ssl$ tail -1 apache2.confInclude sites-enabled/ In order to switch back to the latest revision (it is coined the tip), you can just call update again with no revision passed as an argument: $ hg update -C2 files updated, 0 files merged, 1 files removed, 0 files unresolved How it works... With this sequence, you already know how to manage versions of your personal projects: save a version, undo a change, retrieve an older version, and so on. Let's take a closer look at what happens under the hood. After you type hg init, a directory called .hg is created: $ ls -a. apache2.conf envvars magic mods-enabled sites-availabl.. conf.d .hg mods-available ports.conf sites- This directory, called a repository, contains the history of your project and some Mercurial metadata. This is where Mercurial records all your revisions of tracked files (actually, it stores only the differences between each revision, like RCS/CVS/Subversion, and in compressed form, so the size is usually less than that of the the actual data!). And also, this is where it stores the commit messages, information about branches, tags, bookmarks, and so on. All the other files and directories beside .hg are your project files; they form what is called a working directory. If ever you would like to forget version control in this zone, you can just remove the .hg directory. Another interesting thing to note is that, contrary to Subversion for instance, in a local .hg repository, you do not have less information than in a repository in a central server! Your installation of Mercurial actually allows you to have both a client command (or GUI), with which you can work locally or with distant servers, and a server, with which you can share your work with colleagues. This is because, with DVCS ( Distributed VCS ), there is no difference between the data checked out to work with and the data ready to be published. When you either create a local repository or clone an existing one from a server, you have all the necessary information (in the .hg directory) to become a publisher yourself. There's more... This section will discuss supplementary commands or options. Other commands First of all, Mercurial has many commands (the list of which you can get with the command hg help); in addition to adding and removing files from being version controlled, you can also use the copy command to copy a file into a new file, and similarly, you have a rename command. The difference between the OS file copy and the one that Mercurial has is that when you receive a change made by somebody else to the original file, it will also be applied by Mercurial to the new file; but for this magic to work, you have to tell Mercurial about the copies/renames so it can track them. There are also convenient commands, such as addremove, which allows you to automatically add all new files and remove (from version control) files that have been deleted. Options Please refer to the built-in help system or to reference documentation, such as Mercurial: The Definitive Guide, available online at o http://hgbook.red-bean.com/, to get the complete list of options for each command. You have seen -m (or --message) in the commit command to specify a log message; if you omit this option, Mercurial will prompt you to get a message using $EDITOR. Also, you have seen -C (or --clean) in the update command; it will tell Mercurial to discard uncommitted changes when switching to another version (otherwise, local changes would automatically be merged into the requested version). Summary This article explained how to work with local files, either personal projects or files that you wanted to be version controlled (for example, source code or configuration files). You also learned how to create a new repository, make changes, and track them (selecting files to track, recording changes, and reversing those changes). Resources for Article : Further resources on this subject: Apache Continuum: Ensuring the Health of your Source Code (Part 1) [Article] Apache Continuum: Ensuring the Health of your Source Code (Part 2) [Article] Negotiation Strategy for Effective Implementation of COTS Software [Article]
Read more
  • 0
  • 0
  • 1641

article-image-adding-raster-layers
Packt
24 Dec 2013
9 min read
Save for later

Adding Raster Layers

Packt
24 Dec 2013
9 min read
(For more resources related to this topic, see here.) This article will cover about working with raster layers. The collection of sections is composed of most common use cases regarding the handling of raster layers in the Google Maps JavaScript API. Raster is one of the prime data types in the GIS world and Google Maps JavaScript API presents an extensive set of tools to integrate external sources of imagery. Also, the API enables the application developers to change the styling of its own base maps with a palette of practically unlimited array of choices. This article will introduce you to change the styling of base maps and then continue with the display of raster data, focusing on external Tiled Map Services (TMS) where the raster layer is composed of organized tiles in the map display.(ex: Openstreetmap). Lastly, there a number of raster layers (traffic, transit, weather, bicycle and Panoramio) that are to be presented within their integration with Google Maps JavaScript API. Styling of Google base maps Google base maps show a variety of details, such as water bodies (oceans, seas, rivers, lakes etc.), roads, parks, and built-up areas (residential, industrial and so on.). As you have observed in the first article, all these are shown in predefined cartographic parameters. With the styling capability of base maps, you have a virtually unlimited set of choices in terms of cartographic representation of base maps. In your web or mobile applications, it is very beneficial to have diversity of representations (in all different colour schemes with different emphasis) in terms of keeping your audience more involved and having maps blend in nicely into your website design. The following steps will guide you through the process of changing the styling of base maps. Getting ready… We can continue from the 1st part of Article 1 – Google Maps JavaScript API Basics – as we do not need to call back the basics of getting the map and so on. How to do it… Your result will look like bluish Google Maps, if you follow the steps below: Create an array of styles as follows: var bluishStyle = [ { stylers: [ { hue: "#009999" }, { saturation: -5 }, { lightness: -40 } ] },{ featureType: "road", elementType: "geometry", stylers: [ { lightness: 100 }, { visibility: "simplified" } ] }, { featureType: "water", elementType: "geometry", stylers: [ { hue: "#0000FF" }, {saturation:-40} ] }, { featureType: "administrative.neighborhood", elementType: "labels.text.stroke", stylers: [ { color: "#E80000" }, {weight: 1} ] },{ featureType: "road", elementType: "labels.text", stylers: [ { visibility: "off" } ] }, { featureType: "road.highway", elementType: "geometry.fill", stylers: [ { color: "#FF00FF" }, {weight: 2} ] } ] Add your styles array to the initMap() function. Within the initMap() function, create a styledMapType object with its name and referencing the your styles array: var bluishStyledMap = new google.maps.StyledMapType(bluishStyle, {name: "Bluish Google Base Maps with Pink Highways"}); Add mapTypeControlOptions object having mapTypeIds property to your original mapOptions object: var mapOptions = { center: new google.maps.LatLng(39.9078, 32.8252), zoom: 10, mapTypeControlOptions: {mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'new_bluish_style']} }; Relate the new mapTypeId to your styledMapType object: map.mapTypes.set('new_bluish_style', bluishStyledMap); And lastly, set this new mapTypeId to be displayed: map.setMapTypeId('new_bluish_style'); You can observe the bluish styled Google base maps, as seen above. How it works... Firstly, let's observe the bluishStyle array consisting of one or more google.maps.MapTypeStyle objects arranged like this: var bluishStyle = [ { featureType: '', elementType: '', stylers: [ {hue: ''}, {saturation: ''}, {lightness: ''}, // etc... ] }, { featureType: '', // etc... } ] In this array, you can include several styles (specified in google.maps.MapTypeStyleElementType) for different map features (specified in google.maps.MapTypeStyleFeatureType) and their respective elements – their geometries, labels, and so on (specified in google.maps.MapTypeStyleElementType). Map features embrace the types of geographic representations that are found in the base maps. Administrative areas, landscape features, points of interest, roads and water bodies are examples of map features. In addition to these general definitions of map features, Google Maps JavaScript API enables you to specify subtypes of these features. For example, you may wish to be specific on which poi types to change the default style by giving the featureType property as follows: featureType: 'poi.school' Or, you can be more specific on landscape map features: featureType: 'landscape.man_made' More about google.maps.MapTypeStyleFeatureType object Complete listing on MapTypeStyleFeatureType object can be found at (https://developers.google.com/maps/documentation/javascript/reference#MapTypeStyleFeatureType) in details. Please note that, the first element of our styles array does not include any featureType property, making the styler options be valid for the entire base map: { stylers: [ { hue: "#009999" }, { saturation: -5 }, { lightness: -40 } ] } In addition to google.maps.MapTypeStyleFeatureType and their constants, you can also detail google.maps.MapTypeStyleElementType for each map feature: the geometries, geometry strokes and fills, labels, label texts (also, text fill and stroke) and label icons. Having this opportunity, you can style the geometries of roads in different settings than their related icons. In our article, you have disabled the visibility of all road label texts, not touching their geometry or label icons: { featureType: "road", elementType: "labels.text", stylers: [ { visibility: "off" } ] } More about google.maps.MapTypeStyleElementType object Complete listing on MapTypeStyleElementType object can be found at (https://developers.google.com/maps/documentation/javascript/reference#MapTypeStyleElementType) in details. For every map feature type and its element type, you can specify a google.maps.MapTypeStyler that covers the options of hue, lightness, saturation, gamma, inverse_lightness, visibility and weight options as an array. In our article, the styler options that make the highway road appear as pink are: { featureType: "road.highway", elementType: "geometry.fill", stylers: [ { color: "#FF00FF" }, {weight: 2} ] } where color option in the stylers array is a RGB Hex string of a pink tone and weight defines the weight of the feature in pixels. More about google.maps.MapTypeStyler object Complete listing on MapTypeStyler object can be found at (https://developers.google.com/maps/documentation/javascript/reference#MapTypeStyler) in details. After defining the styles array in our initMap() function, we have created a StyledMapType object: var bluishStyledMap = new google.maps.StyledMapType(bluishStyle, {name: "Bluish Google Base Maps with Pink Highways"}); This object takes two arguments, first one is the styles array, the second one is a google.maps.StyledMapTypeOptions object. . Here, we have included only the name property, however you can additionally include maxZoom and minZoom properties between which this StyledMapType object will be displayed. You can note that, the value that we have assigned for the name property is displayed in the interface, as you can see in the screen snapshot of this article. Once we have created the StyledMapType object, we have added an additional object called mapTypeControlOptions that takes mapTypeIds array in the mapOptions object replacing the mapTypeId property: var mapOptions = { center: new google.maps.LatLng(39.9078, 32.8252), zoom: 10, mapTypeControlOptions: {mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'new_bluish_style']} }; This enables us to add multiple styles in addition to the standard ROADMAP map type. Next comes the step of linking the mapTypeId ('new_bluish_style') that we have specified in mapTypeIds array with the StyledMapType object (bluishStyledMap): map.mapTypes.set('new_bluish_style', bluishStyledMap); After linking the mapTypeId with the StyledMapType, we can finish with: map.setMapTypeId('new_bluish_style'); so that, the map interface opens with a base map styled within our intentions. In our article, we have covered how to style the base maps according to our taste. We have made use of google.maps.MapTypeStyle object to select the features types (google.maps.MapTypeStyleFeatureType) and related elements (google.maps.MapTypeStyleElementType) and styled them using the google.maps.MapTypeStyler object. Then, we have added our StyledMapType object to the map, showing our own styling of the base maps of Google Maps. There's more... Using StyledMapType object is only one of way handling user defined styled base maps in Google Maps JavaScript API. Another, yet simpler usage is through specifying the styles array in mapOptions object's styles property: var mapOptions = { center: new google.maps.LatLng(39.9078, 32.8252), zoom: 10, mapTypeId: google.maps.MapTypeId.ROADMAP, styles: bluishStyle }; Or; after defining our mapOptions object, we can add the styles property later by: map.setOptions({styles: bluishStyle }); There is an important difference between using StyledMapType object and mapOptions object's style property. Using StyledMapType object enables us to define a number of (virtually infinite) styles as map types. In addition, these map types can be seen in the map type control in the map interface, so that it is very easy to change back and forth between map types for the user. However, if the styles are attached to the map by mapOptions object's style property, there is no way for the user to change between multiple styles. In fact, in the map type control, there will be option for your new selecting the styles, because styles are not attached to a StyledMapType object, therefore cannot be identified as map types. Styled Map Wizard http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html Preparing style arrays is a detailed job, with many cartographic details. Finding the correct combination in stylers for each feature and element type would take too much time, especially if you have the only way of editing in a text editor. Google has done a great job on preparing "The Styled Map Wizard" for easing this time consuming task that enables you to perform all your styling in an interface so, you can overview what you are changing in real time. After you finish your work, you can export your changes as JSON to be used as styles array in your application. Summary In this article, we presented the addition of external raster data through a series of steps alongside Google layers such as the Tile, Traffic, Transit, and Weather layers. Resources for Article: Further resources on this subject: Including Google Maps in your Posts Using Apache Roller 4.0 [Article] QR Codes, Geolocation, Google Maps API, and HTML5 Video [Article] Google Earth, Google Maps and Your Photos: a Tutorial Part II [Article]
Read more
  • 0
  • 0
  • 1639
Modal Close icon
Modal Close icon