My question is regarding dynamic By Locators.
My Page classes usually looks like that:
public class MyPage {
private WebDriver driver;
private By myFixedLocator = By.xpath(".......");
private String myDynamicLoactor = "//div[#id = 'someId']" +
"//div[contains( #class, '<className>')]";
public MyPage(WebDriver driver) {this.driver = driver;}
public AnotherSuperPage getAnotherPage(String className) {
By tmpBy = By.xpath(myDynamicLocator.replace("<className>", className));
driver.findElement(tmpBy);
return new AnotherSuperPage(driver);
}
//for example here: childOne and Two are sub classes of AnotherSuperClass
public AnotherChild1Page getChildOne() {return getAnotherPage("childOne");}
public AnotherChild1Page getChildTwo() {return getAnotherPage("childTwo")}
}
Locators like myDynamicLocator represents elements, the all have similar xpath structure except of the one String part.
Is there any better way to do this? As far as I understood, the By locators are final and immutible.
This is also why I don't use Page Factory, since the #FindBy annotation I can use flexible locator as in the example above.
And when I have a By locator, can I get the text inside in a smooth way? because By.toString() gives me the whole information, including "xpath"....
You could have also achieved it by simply doing it as:
public AnotherSuperPage getAnotherPage(String className) {
driver.findElement(By.xpath("//div[#id = 'someId']//div[contains( #class, '" + className +"')]"));
return new AnotherSuperPage(driver);
}
instead of creating a string object then replacing it and storing it in another variable, though anyhow this is what happens internally, but less coding. Hope am understanding you right...
Related
I created test framework with Selenium and setup ExtentReports for test report. Used page object model and #FindBy annotation for fields to create own store of WebElements for each page. Now I would like to create custom annotation #Name
#Name(description = "google main page")
#FindBy(linkText = "Gmail")
private WebElement gmail;
And implementation for it, to be able to use description of each WebElement later in my report. I have my own implementation of click() method
public static void click(WebElement element) {
try{
element.click();
TestReport.addLog(LogStatus.INFO, "Element "+NameImpl.getDescription(element)+" clicked");
} catch (NoSuchElementException e) {
TestReport.addLog(LogStatus.ERROR, "Element "+NameImpl.getDescription(element)+" not found");
}
}
I'm able to get description of all elements annotated in class with reflection like here
Is it possible to read the value of a annotation in java?
but cannot get description of specific element used in my click method.
Any ideas how to achieve that?
Just from the parameter passed to the click method, there's no way the get annotations. This reason is the annotation are on the gmail field, not on the WebElement class. So the only way to get the #Name annotation is to first get the Field representing your gmail field, and that will have to be done through the declaring class:
ClassWithGmailField.class.getField("gmail").getAnnotation(Name.class).description()
Just from the parameter of the click method, you could only reach annotations defined on the WebElement class itself e.g.:
#SomeAnnotation
public class WebElement {...}
but this is not useful for anything in your case.
To achieve something similar to what you want, you could potentially:
Reflectively analyze the class, extract all #Name'd fields and collect the meta together with the field values, perhaps into some kind of wrapper e.g. NamedElement that would have the description from #Name and the WebElement itself
Reflectively call the click method providing it with the meta it needs (the description in your case). But for this you'd need to somehow know which method to invoke for each field (e.g. by yet another annotation), making your logic encoded external to your actual code. Might make sense in some cases but probably a bad idea in general.
A quick (uncompiled, untested) code example of the first idea:
public class NamedElement extends WebElement {
public String description;
public WebElement element;
public NamedElement(String description, WebElement element) {
this.description = description;
this.element = element;
}
}
public class NamedElementExtractor {
public static Collection<NamedElement> getNamedElements(Object instanceWithWebElements) {
//instanceWithElements in your case would be an instance of the class that has the "gmail" field, i.e. the one I referred to as ClassWithGmailField above
Collection<NamedElement> namedElements = new List<NamedElement>();
for (Field field : instanceWithWebElements.getClass().getDeclaredFields()) {
field.setAccessible(true);
//maybe first check field.isAnnotationPresent(Name.class)
String desc = field.getAnnotation(Name.class).description();
WebElement element = field.getValue(instanceWithWebElements);
namedElements.add(new NamedElement(desc, element));
}
}
}
...
for (NamedElement namedElement : NamedElementExtractor.getNamedElements(instanceWithWebElements))) {
Click.click(namedElement);
}
...
public static void click(NamedElement namedElement) {
try{
namedElement.element.click();
TestReport.addLog(LogStatus.INFO, "Element "+ namedElement.description +" clicked");
} catch (NoSuchElementException e) {
TestReport.addLog(LogStatus.ERROR, "Element "+ namedElement.description +" not found");
}
}
No idea if this is appropriate/usable in your case, but it's food for thought.
My basic question: is there anything built that already does this automatically (doesn't have to be part of a popular library/package)? The main things I'm working with are Spring (MVC) and Jackson2.
I understand there are a few manual ways to do this:
Create a method in each class that serializes its specific properties into property=value& form (kind of stinks because it's a bunch of logic duplication, I feel).
Create a function that accepts an object, and uses reflection to dynamically read all the properties (I guess the getters), and build the string by getting each. I'm assuming this is how Jackson works for serialization/deserialization in general, but I really don't know.
Use some feature of Jackson to customly serialize the object. I've researched custom serializers, but it seems they are specific to a class (so I'd have to create one for each Class I'm trying to serialize), while I was hoping for a generic way. I'm just having trouble understanding how to apply one universally to objects. A few of the links:
http://techtraits.com/Programming/2011/11/20/using-custom-serializers-with-jackson/
http://wiki.fasterxml.com/JacksonHowToCustomSerializers
Use ObjectMapper.convertValue(object, HashMap.class);, iterate over the HashMap's key/value pairs, and build the string (which is what I'm using now, but I feel the conversions are excessive?).
I'm guessing there's others I'm not thinking of.
The main post I've looked into is Java: Getting the properties of a class to construct a string representation
My point is that I have several classes that I want to be able to serialize without having to specify something specific for each. That's why I'm thinking a function using reflection (#2 above) is the only way to handle this (if I have to do it manually).
If it helps, an example of what I mean is with, say, these two classes:
public class C1 {
private String C1prop1;
private String C1prop2;
private String C1prop3;
// Getters and setters for the 3 properties
}
public class C2 {
private String C2prop1;
private String C2prop2;
private String C2prop3;
// Getters and setters for the 3 properties
}
(no, the properties names and conventions are not what my actual app is using, it's just an example)
The results of serializing would be C1prop1=value&C1prop2=value&C1prop3=value and C2prop1=value&C2prop2=value&C2prop3=value, but there's only one place that defines how the serialization happens (already defined somewhere, or created manually by me).
So my idea is that I will have to end up using a form of the following (taken from the post I linked above):
public String toString() {
StringBuilder sb = new StringBuilder();
try {
Class c = Class.forName(this.getClass().getName());
Method m[] = c.getDeclaredMethods();
Object oo;
for (int i = 0; i < m.length; i++)
if (m[i].getName().startsWith("get")) {
oo = m[i].invoke(this, null);
sb.append(m[i].getName().substring(3) + ":"
+ String.valueOf(oo) + "\n");
}
} catch (Throwable e) {
System.err.println(e);
}
return sb.toString();
}
And modify it to accept an object, and change the format of the items appended to the StringBuilder. That works for me, I don't need help modifying this now.
So again, my main question is if there's something that already handles this (potentially simple) serialization instead of me having to (quickly) modify the function above, even if I have to specify how to deal with each property and value and how to combine each?
If it helps, the background of this is that I'm using a RestTemplate (Spring) to make a GET request to a different server, and I want to pass a specific object's properties/values in the URL. I understand I can use something like:
restTemplate.getForObject("URL?C1prop1={C1Prop1}&...", String.class, C1Object);
I believe the properties will be automatically mapped. But like I said, I don't want to have to make a different URL template and method for each object type. I'm hoping to have something like the following:
public String getRequest(String url, Object obj) {
String serializedUri = SERIALIZE_URI(obj);
String response = restTemplate.getForObject("URL?" + serializedUri, String.class);
return response;
}
where SERIALIZE_URI is where I'd handle it. And I could call it like getRequest("whatever", C1Object); and getRequest("whateverElse", C2Object);.
I think, solution number 4 is OK. It is simple to understand and clear.
I propose similar solution in which we can use #JsonAnySetter annotation. Please, see below example:
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonProgram {
public static void main(String[] args) throws Exception {
C1 c1 = new C1();
c1.setProp1("a");
c1.setProp3("c");
User user = new User();
user.setName("Tom");
user.setSurname("Irg");
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.convertValue(c1, UriFormat.class));
System.out.println(mapper.convertValue(user, UriFormat.class));
}
}
class UriFormat {
private StringBuilder builder = new StringBuilder();
#JsonAnySetter
public void addToUri(String name, Object property) {
if (builder.length() > 0) {
builder.append("&");
}
builder.append(name).append("=").append(property);
}
#Override
public String toString() {
return builder.toString();
}
}
Above program prints:
prop1=a&prop2=null&prop3=c
name=Tom&surname=Irg
And your getRequest method could look like this:
public String getRequest(String url, Object obj) {
String serializedUri = mapper.convertValue(obj, UriFormat.class).toString();
String response = restTemplate.getForObject(url + "?" + serializedUri, String.class);
return response;
}
Lets we have c1.
c1.setC1prop1("C1prop1");
c1.setC1prop2("C1prop2");
c1.setC1prop3("C1prop3");
Converts c1 into URI
UriComponentsBuilder.fromHttpUrl("http://test.com")
.queryParams(new ObjectMapper().convertValue(c1, LinkedMultiValueMap.class))
.build()
.toUri());
After we will have
http://test.com?c1prop1=C1prop1&c1prop2=C1prop2&c1prop3=C1prop3
I have a function for a Selenium Test that looks like this.
public static WebElement getElmObject (String locinfo, String loctype) {
try{
return driver.findElement(By.loctype(locinfo));
} catch (Throwable t){
return null;
}
The function is supposed to take in the info string and the type (the name of the method to call in the BY class - like xpath, cssselector, tagname etc.) How do I get Java to evaluate the value of "loctype"?
I come from a ColdFusion background and this is easy to do with CF but I am having a hard time trying to do this in Java. I just get a "cannot resolve method" issue and it won't compile. Is it even possible to do?
You can do this using Reflection.
public static WebElement getElmObject(String locinfo, String loctype) {
try {
Method method = By.class.getMethod(loctype, String.class);
By by = (By) method.invoke(By.class, locinfo);
return driver.findElement(by);
} catch (Throwable t) {
return null;
}
}
However I find this strange and I would recommend using different methods (getElmObjectById, getElmObjectByCss, etc.) or to use an enum (ID, CSS, XPATH, etc.) as parameter instead of the method name. Using the method name as parameter, it makes your caller dependent of the Selenium implementation. If they change the name of a method, your code will not work anymore and you will even not notice this at compile time!
we can also do it with enum like this
other than creating seperate methods for each and every locator like getElmObjectById as LaurentG said we can also achieve it as shown below
public enum avilableLocators
{
CLASS_NAME, CSS_SELECTOR, XPATH
}
and have a method with switch case or if-else if which will have a return type of By
public By locinfo(String locinfo)
{
String locatorValue=null;
switch (locType(locinfo))
{
case XPATH:
locatorValue=locinfo.split(",")[1]/*assuming that you are passing locinfo,locvalue*/
return By.xpath(locator);
}
}
public final avilableLocators locType(String loctype) {
if (loctype.contains("xpath"))
{
return avilableLocators.XPATH;
}
}
so the final usage can be like this
String locDetails="xpath,//*[#id='ComScorePingFile']"
locinfo(locDetails);
Not sure if this is a decent question or not but here it goes. We are trying to implement a UI testing framework (selenium web-driver) and want to use a Page driven design for example
class HomePage {
#FindBy(how = How.Id, id="myPageHeaderID")
private String pageHeader
In the simple example above I need to hard-code the "myPageHeaderID" string literal. One of the requirements proposed is that we be able to pull in the "myPageHeaderID" from a property for both maintenance reasons (no code deploy if something changes) and for internationalization reasons. I have been searching around and probably not doing a proper search but is there any way of doing what I am asking above?
I briefly went down this route, but due to our application it wasn't quite achievable (pages aren't always displayed in the same order once you've visited a page).
public class PageElement implements WebElementAdapter, Locatable {
private How how;
private String using;
private boolean required;
#FindBy(how = How.ID_OR_NAME, using = DEFAULT_LOCATION_STRATEGY)
private WebElement backingElement;
public PageElement(How how, String using using) {
this.how = how;
this.using = using;
this.required = true;
}
/**
* This is how the overriding of the element location is done. I then injected
* these values in a spring configured bean file.
*
* This is needed on your config file:
* default-lazy-init="true" default-init-method="initialize">
*/
public final void initElement() {
if (backingElement == null || isStale() {
backingElement = getDriver().findElement(getLocationStrategy());
}
}
public By getLocationStrategy() {
By by = new ByIdOrName(using.replace(DEFAULT_LOCATION_STRATEGY, using));
switch(how) {
case CLASS_NAME:
by = By.className(using.replace(DEFAULT_LOCATION_STRATEGY, using));
break;
//Do for others
}
return by;
}
public WebElement getBackingElement() {
return backingElement;
}
}
public interface WebElementAdapter {
WebElement getBackingElement();
}
public interface Locatable {
By getLocationStrategy();
}
I then created common widgets in POJOs, and injected these into page objects which were a collection of these widgets.
From there I had a simple test harness which was responsible for taking in strings (which were then executed. Basically it allowed for test cases to be written in SpEL and act on the beans which were injected.
It was what I thought a pretty neat project, but I had to shelf it to get some other things done.
Annotations are essentially metadata. Taking database metadata for example, it would be weird if Oracle database would turn into MySQL, right? Here is the article about Annotation Transformers in TestNG. Didn't try it myself, but I think it could be implemented in some way or another.
AFAIK, you can call a method from the Annotation.
#FindBy(how = How.Id, id=getProp())
private String pageHeader;
private String getProp()
{
String prop = //whatever way you want to get the value
return prop;
}
Doesn't that work?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What are some common, real world examples of using the Builder Pattern? What does it buy you? Why not just use a Factory Pattern?
Below are some reasons arguing for the use of the pattern and example code in Java, but it is an implementation of the Builder Pattern covered by the Gang of Four in Design Patterns. The reasons you would use it in Java are also applicable to other programming languages as well.
As Joshua Bloch states in Effective Java, 2nd Edition:
The builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters.
We've all at some point encountered a class with a list of constructors where each addition adds a new option parameter:
Pizza(int size) { ... }
Pizza(int size, boolean cheese) { ... }
Pizza(int size, boolean cheese, boolean pepperoni) { ... }
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }
This is called the Telescoping Constructor Pattern. The problem with this pattern is that once constructors are 4 or 5 parameters long it becomes difficult to remember the required order of the parameters as well as what particular constructor you might want in a given situation.
One alternative you have to the Telescoping Constructor Pattern is the JavaBean Pattern where you call a constructor with the mandatory parameters and then call any optional setters after:
Pizza pizza = new Pizza(12);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);
The problem here is that because the object is created over several calls it may be in an inconsistent state partway through its construction. This also requires a lot of extra effort to ensure thread safety.
The better alternative is to use the Builder Pattern.
public class Pizza {
private int size;
private boolean cheese;
private boolean pepperoni;
private boolean bacon;
public static class Builder {
//required
private final int size;
//optional
private boolean cheese = false;
private boolean pepperoni = false;
private boolean bacon = false;
public Builder(int size) {
this.size = size;
}
public Builder cheese(boolean value) {
cheese = value;
return this;
}
public Builder pepperoni(boolean value) {
pepperoni = value;
return this;
}
public Builder bacon(boolean value) {
bacon = value;
return this;
}
public Pizza build() {
return new Pizza(this);
}
}
private Pizza(Builder builder) {
size = builder.size;
cheese = builder.cheese;
pepperoni = builder.pepperoni;
bacon = builder.bacon;
}
}
Note that Pizza is immutable and that parameter values are all in a single location. Because the Builder's setter methods return the Builder object they are able to be chained.
Pizza pizza = new Pizza.Builder(12)
.cheese(true)
.pepperoni(true)
.bacon(true)
.build();
This results in code that is easy to write and very easy to read and understand. In this example, the build method could be modified to check parameters after they have been copied from the builder to the Pizza object and throw an IllegalStateException if an invalid parameter value has been supplied. This pattern is flexible and it is easy to add more parameters to it in the future. It is really only useful if you are going to have more than 4 or 5 parameters for a constructor. That said, it might be worthwhile in the first place if you suspect you may be adding more parameters in the future.
I have borrowed heavily on this topic from the book Effective Java, 2nd Edition by Joshua Bloch. To learn more about this pattern and other effective Java practices I highly recommend it.
Consider a restaurant. The creation of "today's meal" is a factory pattern, because you tell the kitchen "get me today's meal" and the kitchen (factory) decides what object to generate, based on hidden criteria.
The builder appears if you order a custom pizza. In this case, the waiter tells the chef (builder) "I need a pizza; add cheese, onions and bacon to it!" Thus, the builder exposes the attributes the generated object should have, but hides how to set them.
The key difference between a builder and factory IMHO, is that a builder is useful when you need to do lots of things to build an object. For example imagine a DOM. You have to create plenty of nodes and attributes to get your final object. A factory is used when the factory can easily create the entire object within one method call.
One example of using a builder is a building an XML document, I've used this model when building HTML fragments for example I might have a Builder for building a specific type of table and it might have the following methods (parameters are not shown):
BuildOrderHeaderRow()
BuildLineItemSubHeaderRow()
BuildOrderRow()
BuildLineItemSubRow()
This builder would then spit out the HTML for me. This is much easier to read than walking through a large procedural method.
Check out Builder Pattern on Wikipedia.
.NET StringBuilder class is a great example of builder pattern. It is mostly used to create a string in a series of steps. The final result you get on doing ToString() is always a string but the creation of that string varies according to what functions in the StringBuilder class were used. To sum up, the basic idea is to build complex objects and hide the implementation details of how it is being built.
I always disliked the Builder pattern as something unwieldy, obtrusive and very often abused by less experienced programmers. Its a pattern which only makes sense if you need to assemble the object from some data which requires a post-initialisation step (i.e. once all the data is collected - do something with it). Instead, in 99% of the time builders are simply used to initialise the class members.
In such cases it is far better to simply declare withXyz(...) type setters inside the class and make them return a reference to itself.
Consider this:
public class Complex {
private String first;
private String second;
private String third;
public String getFirst(){
return first;
}
public void setFirst(String first){
this.first=first;
}
...
public Complex withFirst(String first){
this.first=first;
return this;
}
public Complex withSecond(String second){
this.second=second;
return this;
}
public Complex withThird(String third){
this.third=third;
return this;
}
}
Complex complex = new Complex()
.withFirst("first value")
.withSecond("second value")
.withThird("third value");
Now we have a neat single class that manages its own initialization and does pretty much the same job as the builder, except that its far more elegant.
For a multi-threaded problem, we needed a complex object to be built up for each thread. The object represented the data being processed, and could change depending on the user input.
Could we use a factory instead? Yes
Why didn't we? Builder makes more sense I guess.
Factories are used for creating different types of objects that are the same basic type (implement the same interface or base class).
Builders build the same type of object over and over, but the construction is dynamic so it can be changed at runtime.
You use it when you have lots of options to deal with. Think about things like jmock:
m.expects(once())
.method("testMethod")
.with(eq(1), eq(2))
.returns("someResponse");
It feels a lot more natural and is...possible.
There's also xml building, string building and many other things. Imagine if java.util.Map had put as a builder. You could do stuff like this:
Map<String, Integer> m = new HashMap<String, Integer>()
.put("a", 1)
.put("b", 2)
.put("c", 3);
While going through Microsoft MVC framework, I got a thought about builder pattern. I came across the pattern in the ControllerBuilder class. This class is to return the controller factory class, which is then used to build concrete controller.
Advantage I see in using builder pattern is that, you can create a factory of your own and plug it into the framework.
#Tetha, there can be a restaurant (Framework) run by Italian guy, that serves Pizza. In order to prepare pizza Italian guy (Object Builder) uses Owen (Factory) with a pizza base (base class).
Now Indian guy takes over the restaurant from Italian guy. Indian restaurant (Framework) servers dosa instead of pizza. In order to prepare dosa Indian guy (object builder) uses Frying Pan (Factory) with a Maida (base class)
If you look at scenario, food is different,way food is prepared is different, but in the same restaurant (under same framework). Restaurant should be build in such a way that it can support Chinese, Mexican or any cuisine. Object builder inside framework facilitates to plugin kind of cuisine you want. for example
class RestaurantObjectBuilder
{
IFactory _factory = new DefaultFoodFactory();
//This can be used when you want to plugin the
public void SetFoodFactory(IFactory customFactory)
{
_factory = customFactory;
}
public IFactory GetFoodFactory()
{
return _factory;
}
}
Building on the previous answers (pun intended), an excellent real-world example is Groovy's built in support for Builders.
Creating XML using Groovy's MarkupBuilder
Creating XML using Groovy's StreamingMarkupBuilder
Swing Builder
SwingXBuilder
See Builders in the Groovy Documentation
Another advantage of the builder is that if you have a Factory, there is still some coupling in you code, because for the Factory to work, it has to know all the objects it can possibly create. If you add another object that could be created, you will have to modify the factory class to include him. This happens in the Abstract Factory as well.
With the builder, on the other hand, you just have to create a new concrete builder for this new class. The director class will stay the same, because it receives the builder in the constructor.
Also, there are many flavors of builder. Kamikaze Mercenary`s gives another one.
/// <summary>
/// Builder
/// </summary>
public interface IWebRequestBuilder
{
IWebRequestBuilder BuildHost(string host);
IWebRequestBuilder BuildPort(int port);
IWebRequestBuilder BuildPath(string path);
IWebRequestBuilder BuildQuery(string query);
IWebRequestBuilder BuildScheme(string scheme);
IWebRequestBuilder BuildTimeout(int timeout);
WebRequest Build();
}
/// <summary>
/// ConcreteBuilder #1
/// </summary>
public class HttpWebRequestBuilder : IWebRequestBuilder
{
private string _host;
private string _path = string.Empty;
private string _query = string.Empty;
private string _scheme = "http";
private int _port = 80;
private int _timeout = -1;
public IWebRequestBuilder BuildHost(string host)
{
_host = host;
return this;
}
public IWebRequestBuilder BuildPort(int port)
{
_port = port;
return this;
}
public IWebRequestBuilder BuildPath(string path)
{
_path = path;
return this;
}
public IWebRequestBuilder BuildQuery(string query)
{
_query = query;
return this;
}
public IWebRequestBuilder BuildScheme(string scheme)
{
_scheme = scheme;
return this;
}
public IWebRequestBuilder BuildTimeout(int timeout)
{
_timeout = timeout;
return this;
}
protected virtual void BeforeBuild(HttpWebRequest httpWebRequest) {
}
public WebRequest Build()
{
var uri = _scheme + "://" + _host + ":" + _port + "/" + _path + "?" + _query;
var httpWebRequest = WebRequest.CreateHttp(uri);
httpWebRequest.Timeout = _timeout;
BeforeBuild(httpWebRequest);
return httpWebRequest;
}
}
/// <summary>
/// ConcreteBuilder #2
/// </summary>
public class ProxyHttpWebRequestBuilder : HttpWebRequestBuilder
{
private string _proxy = null;
public ProxyHttpWebRequestBuilder(string proxy)
{
_proxy = proxy;
}
protected override void BeforeBuild(HttpWebRequest httpWebRequest)
{
httpWebRequest.Proxy = new WebProxy(_proxy);
}
}
/// <summary>
/// Director
/// </summary>
public class SearchRequest
{
private IWebRequestBuilder _requestBuilder;
public SearchRequest(IWebRequestBuilder requestBuilder)
{
_requestBuilder = requestBuilder;
}
public WebRequest Construct(string searchQuery)
{
return _requestBuilder
.BuildHost("ajax.googleapis.com")
.BuildPort(80)
.BuildPath("ajax/services/search/web")
.BuildQuery("v=1.0&q=" + HttpUtility.UrlEncode(searchQuery))
.BuildScheme("http")
.BuildTimeout(-1)
.Build();
}
public string GetResults(string searchQuery) {
var request = Construct(searchQuery);
var resp = request.GetResponse();
using (StreamReader stream = new StreamReader(resp.GetResponseStream()))
{
return stream.ReadToEnd();
}
}
}
class Program
{
/// <summary>
/// Inside both requests the same SearchRequest.Construct(string) method is used.
/// But finally different HttpWebRequest objects are built.
/// </summary>
static void Main(string[] args)
{
var request1 = new SearchRequest(new HttpWebRequestBuilder());
var results1 = request1.GetResults("IBM");
Console.WriteLine(results1);
var request2 = new SearchRequest(new ProxyHttpWebRequestBuilder("localhost:80"));
var results2 = request2.GetResults("IBM");
Console.WriteLine(results2);
}
}
I used builder in home-grown messaging library. The library core was receiving data from the wire, collecting it with Builder instance, then, once Builder decided it've got everything it needed to create a Message instance, Builder.GetMessage() was constructing a message instance using the data collected from the wire.
When I wanted to use the standard XMLGregorianCalendar for my XML to object marshalling of DateTime in Java, I heard a lot of comments on how heavy weight and cumbersome it was to use it. I was trying to comtrol the XML fields in the xs:datetime structs to manage timezone, milliseconds, etc.
So I designed a utility to build an XMLGregorian calendar from a GregorianCalendar or java.util.Date.
Because of where I work I'm not allowed to share it online without legal, but here's an example of how a client uses it. It abstracts the details and filters some of the implementation of XMLGregorianCalendar that are less used for xs:datetime.
XMLGregorianCalendarBuilder builder = XMLGregorianCalendarBuilder.newInstance(jdkDate);
XMLGregorianCalendar xmlCalendar = builder.excludeMillis().excludeOffset().build();
Granted this pattern is more of a filter as it sets fields in the xmlCalendar as undefined so they are excluded, it still "builds" it. I've easily added other options to the builder to create an xs:date, and xs:time struct and also to manipulate timezone offsets when needed.
If you've ever seen code that creates and uses XMLGregorianCalendar, you would see how this made it much easier to manipulate.