Friday, February 1, 2013

Fractals

I made a program using java Swing that can easily draw fractals that are generated as the attractors of the math IFS ( Iterated Function Systems). The following is a sample picture. It is a tile of a self-affine tiling of the plane R^2. The IFS consists of 3 functions {f1(x),f2(x), f3(x)}. The 3 functions are defined as follows:
f1(x) = (B^2)^(-1)(x)
f2(x) = (B*w*B)^(-1)(x + B*h)
f3(x) = B^(-1)(x + d)
where B is the matrix {{1, -1},{1,1}}, w is the matrix {{0,-1},{1,0}}, h = {0,1}, and d={1,0}.

Note that the picture consists of 3 pieces that are similar to each other. The 3 pieces do not overlap. They only touch others at the borders. Though the boundary of the whole picture is very complex, we can use similar copies of this shape of different sizes to tile the whole plane without overlapping! And we only need finitely many different sizes of this shape for the tiling.

Friday, January 25, 2013

JAXWS proxy

JDK 6 has the wsimport tool that can be used to generate java classes based on the given wsdl file. Then the webservice client can use those classes to call the web service. The following is the example code:
public void testMyService(){
  MyService service = new MyService();
  port = service.getMyPort();
  port.doSomething();
}
In the above, the class MyService is generated by wsimport. It has many annotations related to web service. It is a subclass of javax.xml.ws.Service. MyService is actually a proxy. The following is from the javadoc of the class Service:

Service objects provide the client view of a Web service.

Service acts as a factory of the following:

  • Proxies for a target service endpoint.
  • Instances of {@link javax.xml.ws.Dispatch} for dynamic message-oriented invocation of a remote operation.
Now the questions are these. How is the proxy actually created in the runtime? How are those annotations used? The following is the stack of the method calls at the point when the proxy is created:
 Thread [Main Thread] (Suspended (breakpoint at line 574 in Proxy)) 
  Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler) line: 574 
  AnnotationParser.annotationForMap(Class, Map) line: 239 
  AnnotationParser.parseAnnotation(ByteBuffer, ConstantPool, Class, boolean) line: 229 
  AnnotationParser.parseAnnotations2(byte[], ConstantPool, Class) line: 69 
  AnnotationParser.parseAnnotations(byte[], ConstantPool, Class) line: 52 
  Class<T>.initAnnotationsIfNecessary() line: 3070 
  Class<T>.getAnnotation(Class<A>) line: 3029 
  AnnotationType.<init>(Class<?>) line: 113 
  AnnotationType.getInstance(Class) line: 66 
  AnnotationParser.parseAnnotation(ByteBuffer, ConstantPool, Class, boolean) line: 202 
  AnnotationParser.parseAnnotations2(byte[], ConstantPool, Class) line: 69 
  AnnotationParser.parseAnnotations(byte[], ConstantPool, Class) line: 52 
  Class<T>.initAnnotationsIfNecessary() line: 3070 
  Class<T>.getAnnotation(Class<A>) line: 3029 
  RuntimeInlineAnnotationReader.getClassAnnotation(Class<A>, Class, Locatable) line: 106 
  RuntimeInlineAnnotationReader.getClassAnnotation(Class, Object, Locatable) line: 57 
  RuntimeModelBuilder(ModelBuilder<T,C,F,M>).getTypeInfo(Ref<T,C>) line: 330 
  JAXBContextImpl.getTypeInfoSet() line: 460 
  JAXBContextImpl.<init>(JAXBContextImpl$JAXBContextBuilder) line: 298 
  JAXBContextImpl.<init>(JAXBContextImpl$JAXBContextBuilder, JAXBContextImpl$1) line: 141 
  JAXBContextImpl$JAXBContextBuilder.build() line: 1163 
  ContextFactory.createContext(Class[], Map) line: 145 
  NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] 
  NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 
  DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 
  Method.invoke(Object, Object...) line: 597 
  ContextFinder.newInstance(Class[], Map, String) line: 202 
  ContextFinder.find(Class[], Map) line: 363 
  JAXBContext.newInstance(Class[], Map) line: 574 
  JAXBContext.newInstance(Class...) line: 522 
  ProviderImpl$2.run() line: 209 
  ProviderImpl$2.run() line: 206 
  ProviderImpl.getEPRJaxbContext() line: 206 [local variables unavailable] 
  ProviderImpl.() line: 77 [local variables unavailable] 
  NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method] 
  NativeConstructorAccessorImpl.newInstance(Object[]) line: 39 
  DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 27 
  Constructor<T>.newInstance(Object...) line: 513 
  Class<T>.newInstance0() line: 355 [local variables unavailable] 
  Class<T>.newInstance() line: 308 [local variables unavailable] 
  FactoryFinder.newInstance(String, ClassLoader) line: 31 
  FactoryFinder.find(String, String) line: 128 
  Provider.provider() line: 83 [local variables unavailable] 
  MyService(Service).<init>(URL, QName) line: 56 
  MyService.<init>() line: 46 
  SimpleClient.testMyService() line: 86 
  SimpleClient.main(String[]) line: 108 
This stack gives some clue about how the proxy is created.
  1. MyService is the class generated by wsimport.
  2. The following call to the constructor
         service = new MyService()
    
    calls the constructor of the super class Service. And the following code is executed:
       protected Service(java.net.URL wsdlDocumentLocation, QName serviceName) {
            delegate = Provider.provider().createServiceDelegate(wsdlDocumentLocation,
                    serviceName,
                    this.getClass());
        }
        
    This corresponds to
            MyService(Service).<init>(URL, QName) line: 56 
         
    in the stack.
  3. Now you can see that the Provider picks up the duty and will do all the heavy work. It uses the input parameters wsdlDocumentLocation, serviceName and Class to create the delegate object. The Provider is javax.xml.ws.spi.Provider. My guess is that the Class object this.getClass() contains all the annotation information of the class MyService. The stack shows the process uses the following classes:
    (1)RuntimeInlineAnnotationReader (package: com.sun.xml.bind.v2.model.annotation)
    (2)AnnotationParser (package: sun.reflect.annotation)

  4. These classes process the annotations.

Monday, January 21, 2013

How to set handlers on the JAX-WS client side

In webservice, handlers can be used for logging messages, implmenting security,etc. For a JAX-WS client, there are several ways to set handlers.

Use xml binding

The handlers can be set by binding a handler XML file.
import javax.xml.ws.Service;

@WebServiceClient(name = "MyService", targetNamespace = "...", wsdlLocation = "...")
@HandlerChain(file = "MyService_handler.xml")
public class MyService extends Service{
...
}
MyService_handler.xml:
<?xml version="1.0" encoding="UTF-8"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee">
  <javaee:handler-chain>
    <javaee:handler>
      <javaee:handler-class>com.my.SOAPHandler1</javaee:handler-class>
    </javaee:handler>
    <javaee:handler>
      <javaee:handler-class>com.my.SOAPHandler2</javaee:handler-class>
    </javaee:handler>
  
  </javaee:handler-chain>
</javaee:handler-chains>

Set handlers programmatically

The handlers can also be set programmatically. You can use BindingProvider to set the handlers.
import javax.xml.ws.BindingProvider;

 MyService service = new MyService(wsdlLoc, qName);
 port = service.getXXX();
 BindingProvider bp = (BindingProvider) port;
 Binding binding = bp.getBinding();
 List<Handler> handlerList = binding.getHandlerChain();
 MySOAPHandler myHandler = new MySOAPHandler();
 handlerList.add(myHandler );
 bp.getBinding().setHandlerChain(handlerList);

 port.callXYZ(...);
        
You can also use HandlerResolver to set handlers.

    import javax.xml.ws.handler.Handler;
    import javax.xml.ws.handler.HandlerResolver;
    import javax.xml.ws.handler.PortInfo;

        MyService service = new MyService(wsdlLoc, qName);
       
        service.setHandlerResolver(new HandlerResolver() {
        @Override public List getHandlerChain(PortInfo portInfo) { 
         List<Handler> handlerChain = new ArrayList<Handler>(); 
         handlerChain.add(new MySOAPHandler()); 
         return handlerChain; 
       } 
     });
     
      port = service.getXXX();
      port.callXYZ(...);
But be careful that the code "port = service.getXXX()" must be put after service.setHandlerResolver(...). If it is put before the call setHandlerResolver(...), the code won't work.

References

  1. http://www.javaworld.com/javaworld/jw-02-2007/jw-02-handler.html
  2. http://jax-ws.java.net/nonav/2.2.7/docs/index.html

Monday, September 17, 2012

Blog Three Year Anniversary

I just checked the date. Today is September 17, 2012. This blog site was created on September 12, 2009. So I just passed the three year anniversary by 5 days. Time flies ! The weather is good. Last week it was around 80F with little rain in Pittsburgh. Leaves have turned yellow or red a bit. This week it is getting a little cool. The temperature is around 70F.

Thursday, July 26, 2012

Various Ways for Navigation in JSF 2(draft)

The example is taken from the Icefaces 3 turorial http://wiki.icesoft.org/display/ICE/Getting+Started+with+ICEfaces+3 The file job-applicant.xhtml uses several navigation mechanisms.
  • Use the following:
     <h: button outcome="xyz" .../>
    The web will go directly xyz.xhtml. The URL in the browser is changed to something like ***/xyz.jsf
  • Use the following:
    <h:commandButton action="xyz" ... />
    Go to faces-config.xml to look for the <from-outcome> match for this page. The value in the <to-view-id> tag will be used and the the URL will be changed accordingly.
  • Use the following:
    <h:commandButton action="#{bean.method}" ... />
    Invoke the method of the bean. The return value is a string.
    1. The returned result is the following "abc?faces-redirect=true". In this case, the web will go to abc.xhtml. The URL is changed.
    2. The returned result is the following "abc". In this case, the web will show the content of abc.xhtml. But the URL will not change. So if the current page is xyz.xhtml, the new URL will still be xyz.xhtml instead of abc.xhtml.
    Note that this case of using bean method for the 'action' attribute in h:commandButton is syntactically the same as the case of using string literal for the 'action' attribute in h:commandButton. So maybe the navigation rule is the same. The navigation will first look for the match in faces-config.xml. If a match is not found, then it will just use the value of the 'action' attribute as the page name. It will either redirect to it or forward to it depending on the redirect flag.
  • <h:commandButton listener="#{bean.method}" ... />
    or
    <h:commandButton actionListener="#{bean.method}" ... />
    In these cases, the method returns void. So by default, the page submits to itself. The URL does not change.

Friday, July 13, 2012

Servet, JSF, Weblogic Standards Compliance

The question is can JSF 2 be used in weblogic 10?

The current version of JSF is 2. I think JSF is a layer on top of servlet. So between JSF and the application server, the common ground is the servlet version used. According to this link "http://javaserverfaces.java.net/presentations/20090520-jsf2-datasheet.pdf", JSF 2.0 is compatible with JavaEE 5 application servers, or any server implementing Servlet 2.5. For weblogic 10.3, it has a list of supported standards. From the link "http://docs.oracle.com/cd/E12840_01/wls/docs103/notes/new.html", it supports Java EE version 5.0 and Java EE servlet version 2.5, 2.4, 2.3, and 2.2. So here the common ground is servlet version 2.5, and it should be OK to use JSF 2 in weblogic 10.3.

The following information from wikipedia http://en.wikipedia.org/wiki/Oracle_WebLogic_Server is also helpful.

The table below lists major standards supported by WebLogic Server product version.

Standard WLS 7.0 WLS 8.1 WLS 9.0 WLS 10.0 WLS 10.3 WLS 12c
Java 1.3 1.4 5 5 6 (7 in 10.3.6+) 7
Java EE 1.3 1.3 1.4 5 5 6
Servlet 1.2 2.3 2.4 2.5 2.5 3.0
JSP 1.2 1.2 2.0 2.1 2.1 2.2
EJB 2.0 2.0 2.1 3.0 3.0 3.1
JDBC 2.0 2.0 3.0 3.0 3.0 4.0

Thursday, June 14, 2012

The Different Ways To Specify the Converter and the Validator In JSF

When writing JSP pages in JSF, you can use different ways to specify the converter and/or the validator for an input. If the customer converter/validator does not need any parameters, then the task is easy. But if the customer converter/validator needs to take any parameter, the thing will be more involved.

The Customer Converter

The Customer Converter Without Parameters

In the following, we use the conventional prefix "f" and "h" for the JSF core and html tag libraries respectively. We also assume that there is a customer converter with the ID com.sample.customer.converter.id and the class name com.sample.CustomerConverter. Furthermore, we assume that this converter is used to do the conversion between a string and the object of the class com.sample.CustomerObject.
Method 1
Use the converter ID. The converter ID is declared in the faces-config.xml file.
<h:inputText value="#{someBean.someVar}">
  <f:converter converterId="com.sample.customer.converter.id"/>
</h:inputText>
Method 2
Use the converter attribute:
<h:inputText value="#{someBean.someVar}" converter="com.sample.customer.converter.id" />
Method 3
Implements a method in the back bean to return a converter:
   <h:inputText value="#{someBean.somevar}" converter="#{backBean.converter}" />
Here the backBean class must implement the following method:
  public Converter getConverter(){...}
Method 4
If the converter class CustomerConverter is used for all the conversions between the String and the object of the class CustomerObject, you can specify CustomerConverter as the default for the CustomerOjbect class in faces-config.xml. And that is it. No other things in JSP pages are needed.

In faces-config.xml, do the following:

    <converter>
       <converter-for-class>com.sample.CustomerObject</converter-for-class>
       <converter-class>com.sample.CustomerConverter</converter-class>
    </converter>
In the JSP file, you simply write
<h:inputText value="#{someBean.someVar}" />
Note that here the type of the variable someVar must be the class CustomerObject.

The Customer Converter With Parameters

In this case, you will need to implement the converter class and the tag handler class for the converter. The tag handler class should extend the JSF class ConverterELTag. It should have the method createConverter() that returns an instance of the converter class. You also need to create the customer TLD file for your tag classes.

Note that there is also a way so you can have a customer converter that needs parameters but you do not need to create the tag handler class and TLD files. You can just as simply use the methods described in the section "The Customer Converter Without Parameters". The trick is to pass the parameter to the back bean and get the value of that parameter from the bean when the customer converter does the conversion. The following is an example.

  <h:outputText value="#{someBean.someVar}">
     <f:converter converterId="myConverterId" />
     <f:attribute name="myConverterParameterName" value="someValue" />
  </h:outputText>
Then in the converter, you can get the parameter value as follows:
     parameterValue = component.getAttributes().get("myCoverterParameterName");


The Customer Validator

The Customer Validator Without Parameters

Mehtod 1
   <h:inputText .... >
      <f:validator validatorId="..." />
   </h:inputText>
Method 2
   <h:inputText value="#{someBean.someVar}" validator="#{someBean.validatingMethod}" />
Notice here that the method in the "validator" attribute does not return an object of the validator class. Instead, its return type is void. This is different from the converter case where the corresponding method returns an object of the customer converter class. Here the validation method validates the data and throws a ValidatorException( a Runtime exception ) if it finds any error.

The Customer Validator With Parameters

In this case, you will need to implement the validator class and the tag handler class for the validator. The tag handler class should extend the JSF class ValidatorELTag. It should have the method createValidator() that returns an instance of the validator class. You also need to create the customer TLD file for your tag classes.

References

1. Core JavaServer Faces by David Geary and Cay Horstmann