Pages

Tuesday, September 17, 2013

How to print 3 PowerPoint slides with notes on one sheet

Quite popular problem with power point is to print multiple slides one sheet of paper, and when you want print them with notes then you have only one option - one slide per sheet.

In this post I show you the trick and prepare documents with 3 slides on one sheet with notes and without exporting it to word! To do this you will need the virtual PDF printer (I am using the Bullzip PDF Printer here) and Acrobat Reader.

UPDATE: Now I would recommend doPDF as the virtual printer software. It has not only more features but you are able to define custom paper size in its Advanced settings. There is no need to perform the first step described here.  

Let's start. I am using PP 2010 so in other version it may look differently. First what we need to do is to define new printing page size. To do so go: 

Control Panel ->  Device and Printers  

now click any of your printer. After this you will see the Print server properties at the top of the window. Click it, then select A4 page check the Create a new form and name the new form Half A4. In boxes Width and Height set 3.94in 8.15in. You should see on your screen something like this:

Click OK. And open your presentation. The first thing what you need to do is set your new printing page. Open the File -> Print ->  Print Properties. Now you need to set your page page size to Half A4. It depends on what printer you use. In my case this is virtual printer Bullzip PDF Printer and my settings looks like this:


OK, now you see on the print preview that your page doesn't look good. Especially when you select the Notes Pages. To correct the layout open View -> Notes Master: 
   
Fix the layout look like this below:
Close the view, add you notes to your slides. And we may start printing. The first step is to print to PDF, that is why I use the virtual printer. Just print your slides with notes to PDF one per sheet. When you open your this PDF in Acrobat Reader you should see your slides with notes each printed on wide envelope sheet: 

And the last step is printing this 3 pages on one A4 sheet. Open Adobe Reader's printing panel and set Page Scaling to Multiple Pages per sheet, then set Pages per sheet to Custom 1 by 3. 


And you can print your document. Three slides with notes on one sheet of paper.

Thursday, May 30, 2013

SOAP client on Android using JiBX

Android has no native support for SOAP web services or even XML binding. Sometimes however, your application may be required to utilize web services. In this post I will show you how to consume SOAP web service using JiBX on Android device. First what we need is JiBX (link). You need to download core library and jibx-ws.

Next step is to generate classes form schema (xsd file) of service with witch you want comunicate. You may find the link to schema in WSDL file or you may be required to extract the schema from WSDL file. Now we can use the code generator which you can find in jibx/lib directory of downloaded achieves. Copy schema.xsd extracted from the service definition file (WSDL) to the jibx/lib directory and run the following command:
java -cp jibx-tools.jar org.jibx.schema.codegen.CodeGen schema.xsd
The generated code will appear. Next you need to compile those files. You may do this using javac compiler or import it into your IDE. The last thing is to add binding information to those class. Generator besides the java source code was generate the binding.xml file. Copy this file to the root of your compilation output folder (where the *.class files are). Open this location in command window and run the command:
[pathToYourClassOutputFolder]>java -jar [pathToJiBXlib]\lib\jibx-bind.jar binding.xml
That's it. You are ready to start developing your android application. The above instructions requires the less configuration of all the known to me methods of creating the bindings with JiBX and doesn't bind to any IDE. You can find more information here and here.
Let's return to Android app. You need to add the binded classes to your project (don't add source java files if you not going to add step to run the binding operation with every compilation). You need also add the following jars (and only them) to your project library:
jibx-run.jar from jibx core
jibx-ws.jar from jibx-ws
The last step is the activity code. Lets assume that the QueryRequest is a class representing the root of one of the operation (it comes from classes generated from schema) and QueryResponse is the class representing the root of response to QueryRequest.
public class MyActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        new RunWSCommand().execute();
    }

    private class RunWSCommand extends AsyncTask {        

        @Override
        protected Object doInBackground(Object... objects) {
            IBindingFactory fact = null;
            try {
                fact = BindingDirectory.getFactory(QueryRequest.class);
                Client client = new SoapClient("http://web.adress.to.web.service.com/", fact); //client will build the SOAP envelope for us
                QueryRequest query=new QueryRequest();
                query.setName("Mike"); // add the parameter to request.
                return (QueryResponse) client.call(query);
            } catch (Exception e) {
                e.printStackTrace(); 
                return null;
            }
        }
    }
}
No network operation can be run in main thread hence I use the AsyncTask here. The INTERNET permission request must also be find in AndroidManifest.xml file to run this code.

Saturday, March 30, 2013

Using WS-Adressing in JAX-WS 2.x client

This is quick code example presented how to setup WS-Addressing policy in JAX-WS applications.

Let's start form server side code. The addressing is enabled by default, so if client will send the message with addresing header the sever will reply correctly, but the policy is not included into generated WSDL. To explicite enable the support of WS-Addressing you need to annoted your service implementation bean (SIB) wih @Addressing. So example webservice implementation code may looks like this:
@WebService
@Addressing(required = true)
public class HelloWorld {

  @WebMethod
  public String sayHelloWorldFrom(String from) {
    String result = "Hello, world, from " + from;
    return result;
  }
}
And that is all. The binding element of JAX-WS generated WSDL will have UsingAddressing element:
<definitions xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
....
name="HelloWorldService">

<!--types, messages, portType are ommited for readability-->
    <binding name="HelloWorldPortBinding" type="tns:HelloWorld">
        <wsaw:UsingAddressing required="true"/>
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
        <operation name="sayHelloWorldFrom">
            <soap:operation soapAction=""></soap:operation>
            <input>
                <soap:body use="literal"></soap:body>
            </input>
            <output>
                <soap:body use="literal"></soap:body>
            </output>
        </operation>
    </binding>
    <service name="HelloWorldService">
        <port name="HelloWorldPort" binding="tns:HelloWorldPortBinding">
            <soap:address location="http://127.0.0.1:9000/HelloWorldService"></soap:address>
        </port>
    </service>
</definitions>
Now, what need you to do enable addressing feature on client? It depends if you use the wsimport service and port artifacts then the answer is: absolutly nothing! Even if you generate it from WSDL without UsingAddresing element as there is no changes in JAXB classes. Only runtime artifacts are affected. Here is the client code:
public class JaxWsClient {
    public static void main(String[] args){
        HelloWorldService service=new HelloWorldService();
        HelloWorld port=service.getHelloWorldPort();
        System.out.println(port.sayHelloWorldFrom("JaxWxClient"));
    }
}
After running it the following messages will be exchanged:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <To xmlns="http://www.w3.org/2005/08/addressing">http://127.0.0.1:9000/HelloWorld</To>
        <Action xmlns="http://www.w3.org/2005/08/addressing">http://example/HelloWorld/sayHelloWorldFromRequest</Action>
        <ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
            <Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
        </ReplyTo>
        <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:d54cb478-fdd1-4495-84df-2fde515a4591</MessageID>
    </S:Header>
    <S:Body>
        <ns2:sayHelloWorldFrom xmlns:ns2="http://example/">
            <arg0>JaxWxClient</arg0>
        </ns2:sayHelloWorldFrom>
    </S:Body>
</S:Envelope>
and response:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
        <Action xmlns="http://www.w3.org/2005/08/addressing">http://example/HelloWorld/sayHelloWorldFromResponse</Action>
        <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:a95c9cff-7b9f-4f23-9608-fe1ca9ce1d75</MessageID>
        <RelatesTo xmlns="http://www.w3.org/2005/08/addressing">uuid:d54cb478-fdd1-4495-84df-2fde515a4591</RelatesTo>
    </S:Header>
    <S:Body>
        <ns2:sayHelloWorldFromResponse xmlns:ns2="http://example/">
            <return>Hello, world, from JaxWxClient</return>
        </ns2:sayHelloWorldFromResponse>
    </S:Body>
</S:Envelope>

However if you try to develop dynamic client using dispacher, for example:
public class JaxWsClient {
    public static void main(String[] args) throws SOAPException {
        QName serviceName=new QName("http://example/","HelloWorldService");
        QName portName=new QName("http://example/","HelloWorldPortBinding");
        Service service = Service.create(serviceName);
        service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING,"http://localhost:9000/HelloWorld");
        Dispatch dispatch = service.createDispatch(portName,SOAPMessage.class,Service.Mode.MESSAGE);
        MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
        SOAPMessage request = mf.createMessage();
        SOAPPart part = request.getSOAPPart();
        SOAPEnvelope env = part.getEnvelope();
        SOAPBody body = env.getBody();
        SOAPBodyElement element = body.addBodyElement(new QName("http://example/","sayHelloWorldFrom"));
        SOAPElement arg=element.addChildElement(new QName("http://example/","arg"));
        arg.addTextNode("JaxWxClient");
        request.saveChanges();
        SOAPMessage response=dispatch.invoke(request);
    }
}
Then when you try to run it you will receive the SOAP fault:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <FaultDetail xmlns="http://www.w3.org/2005/08/addressing">
            <ProblemHeaderQName>{http://www.w3.org/2005/08/addressing}Action</ProblemHeaderQName>
        </FaultDetail>
        <To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
        <Action xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/fault</Action>
        <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:713f84a8-2dbf-44a7-936c-d445bfb890df</MessageID>
    </S:Header>
    <S:Body>
        <SOAP-ENV:Fault xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
            <faultcode xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                       xmlns:ns0="http://www.w3.org/2005/08/addressing" xmlns="">ns0:InvalidCardinality</faultcode>
            <faultstring xmlns="">A header representing a Message Addressing Property 
                is not valid and the message cannot be processed</faultstring>
        </SOAP-ENV:Fault>
    </S:Body>
</S:Envelope>
It is required to enable the addressing support on created dispatcher and set required correct SOAPAction. To do this you need to change the client code to:
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,SOAPMessage.class,Service.Mode.MESSAGE,new AddressingFeature());
and add:
dispatch.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY,true);
dispatch.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY,"http://example/HelloWorld/sayHelloWorldFromRequest");
The value of Action used here is the default one which is created in case of absence the custom one. It is build by appending together: target namspace, service name and operation name and string "Response" or "Request". You may find it in WSDL in Action attribute of the input/output/fault element in binding section. After those changes the request will look like the previously presented. You not required to create the address header by yourself. But wait a moment! SOAPAction HTTP Header and WS-Addressing Action header are two different things! Yes, they are. Moreover SOAPAction is set for the operation, and WSA Action may be different for each message in that specific operation. But when it comes to request where we use the SOAPAction and WSA Action then the recommendation requires that both of them are equal or SOAPAction was set to empty string - "". 


Float to double conversion in Java

The first thing what we learn about representation of real number in computer systems is that it is only an approximation. Some of the real numbers cannot be expressed as floating point number (see this converter). How accurate our approximation is depends how many bytes we use to represent it. That is why you may be surprised about the result of the flowing code:
float fvar=0.1f;
double dvar=(double)fvar;
System.out.print("Are these number equal? ");
System.out.println(dvar==fvar);
System.out.println("Really?");
System.out.println("Float: "+fvar);
System.out.println("Double: "+dvar);
Are these number equal? true
Really?
Float: 0.1
Double: 0.10000000149011612
So if you need to convert some floats number to double and you would like to be sure that you won't scare your customer by charging her $99.99999998989 (quite easy to miss the dot) you need to convert floats to doubles by other means.

There are a three popular ways of doing this:
float fvar=0.1f;

//1. Convert float variable to string and then parse it as a double 
Double.parseDouble(new Float(fvar).toString());

//2. Use FloatingDecimal class
new sun.misc.FloatingDecimal(fvar).doubleValue();

//3. Use BigDecimal class 
new BigDecimal(String.valueOf(fvar)).doubleValue();
All of them do the work. The question is which one is the fastest? I've used the Brent Boyer's microbenchmark to answer this question. Here is the result. As you can see the method uses the FloatingDecimal class is the quickest one.