Package org.apache.ws.jaxme.js.pattern

Source Code of org.apache.ws.jaxme.js.pattern.ChainGenerator$ProxyInterfaceGenerator

/*
* Copyright 2003, 2004  The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.

*/
package org.apache.ws.jaxme.js.pattern;

import java.util.ArrayList;
import java.util.List;

import org.apache.ws.jaxme.js.JavaConstructor;
import org.apache.ws.jaxme.js.JavaField;
import org.apache.ws.jaxme.js.JavaMethod;
import org.apache.ws.jaxme.js.JavaQName;
import org.apache.ws.jaxme.js.JavaQNameImpl;
import org.apache.ws.jaxme.js.JavaSource;
import org.apache.ws.jaxme.js.JavaSourceFactory;
import org.apache.ws.jaxme.js.Parameter;


/** <p>This class generates so-called event chains. A chain is an
* interface and an object implementing the interface. Internally
* the implementation is using a list of chained objects, which
* you can assume to implement the same interface.</p>
* <p>Any event is passed to the first object in the list. The object
* may decide to resolve the event immediately and return. It may
* also call pass the event to the next object, take the returned
* value, possibly modify it and return the result. Finally, the
* chained object may decide to emit another event (which is passed
* along the same chain), and use the returned value.</p>
*
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class ChainGenerator {
   private Class controllerInterface;
   private JavaQName chainInterface, proxyClass, implClass;

   /** <p>Sets the controller interface name. If the given class can
    * be resolved using <code>Class.forName(pInterfaceName)</code>
    * or <code>Thread.currentThread().getContextClassLoader().loadClass(pInterfaceName)</code>,
    * then the method <code>setChainInterface()</code> is invoked.
    * Otherwise a {@link ClassNotFoundException} is thrown.</p>
    */
   public void setControllerInterfaceName(String pInterfaceName) throws ClassNotFoundException {
      ClassNotFoundException ex = null;
      Class c = null;
      try {
         c = Class.forName(pInterfaceName);
      } catch (ClassNotFoundException e) {
         ex = e;
      }
      if (c == null) {
         try {
            c = Thread.currentThread().getContextClassLoader().loadClass(pInterfaceName);
         } catch (ClassNotFoundException e) {
            if (ex == null) { e = ex; }
         }
      }
      if (c == null) {
         if (ex == null) { ex = new ClassNotFoundException("Failed to load class: " + pInterfaceName); }
         throw ex;
      } else {
         setControllerInterface(c);
      }
   }

   /** <p>Sets the controller interface.</p>
    */
   public void setControllerInterface(Class pInterface) {
      if (!pInterface.isInterface()) {
         throw new ClassCastException("The controller must be an interface.");
      }
      controllerInterface = pInterface;
   }

   /** <p>Returns the controller interface.</p>
    */
   public Class getControllerInterface() {
      return controllerInterface;
   }

   /** <p>Sets the interface name being generated for the chain objects.</p>
    */
   public void setChainInterfaceName(String pInterfaceName) {
      JavaQName qName = JavaQNameImpl.getInstance(pInterfaceName, true);
      setChainInterface(qName);
   }

   /** <p>Sets the interface being generated for the chain objects.</p>
    */
   public void setChainInterface(JavaQName pInterface) {
      chainInterface = pInterface;
   }

   /** <p>Returns the interface being generated for the chain objects.</p>
    */
   public JavaQName getChainInterface() {
      return chainInterface;
   }

   /** <p>Sets the class name being generated for the chain objects.</p>
    */
   public void setProxyClassName(String pClassName) {
      JavaQName qName = JavaQNameImpl.getInstance(pClassName, true);
      setProxyClass(qName);
   }

   /** <p>Sets the class being generated for the chain objects.</p>
    */
   public void setProxyClass(JavaQName pClassName) {
      proxyClass = pClassName;
   }

   /** <p>Returns the class being generated for the chain objects. Defaults
    * to <code>getChainInterface() + "Impl"</code>.</p>
    */
   public JavaQName getProxyClass() {
      if (proxyClass == null) {
         JavaQName chainClass = getChainInterface();
         if (chainClass == null) {
            return null;
         } else {
            return JavaQNameImpl.getInstance(chainClass.getPackageName(),
                                                             chainClass.getClassName() + "Impl");
         }
      } else {
         return proxyClass;
      }
   }

   /** <p>Sets the name of the chain implementation class.</p>
    */
   public void setImplementationClassName(String pClassName) {
      setImplementationClass(JavaQNameImpl.getInstance(pClassName, true));
   }

   /** <p>Sets the chain implementation class.</p>
    */
   public void setImplementationClass(JavaQName pClassName) {
      implClass = pClassName;
   }

   /** <p>Returns the chain implementation classes name. Defaults to
    * <code>getControllerInterface() + "Impl"</code>.</p>
    */
   public JavaQName getImplementationClass() {
      if (implClass == null) {
         if (controllerInterface == null) {
            return null;
         } else {
            JavaQName controllerClass = JavaQNameImpl.getInstance(controllerInterface);
            return JavaQNameImpl.getInstance(controllerClass.getPackageName(),
                                              controllerClass.getClassName() + "Impl");
         }
      } else {
         return implClass;
      }
   }

   public void finish() {
      if (controllerInterface == null) {
         throw new NullPointerException("A controller interface must be given.");
      }
      if (chainInterface == null) {
         throw new NullPointerException("A chain interface must be given.");
      }
   }

   private class ProxyInterfaceGenerator extends ProxyGenerator {
     public JavaMethod getInterfaceMethod(JavaSource pSource,
                     ProxyGenerator.InterfaceDescription pDescription,
                     java.lang.reflect.Method pMethod) {
       JavaMethod jm = pSource.newJavaMethod(pMethod);
       Parameter[] parameters = jm.getParams();
       JavaQName controllerInterfaceQName = JavaQNameImpl.getInstance(getControllerInterface());
       jm.clearParams();
       jm.addParam(controllerInterfaceQName, "pController");
       for (int i = 0;  i < parameters.length;  i++) {
         jm.addParam(parameters[i]);
       }
       return jm;
     }
     public JavaSource generate(JavaSourceFactory pInterfaceFactory,
                 JavaQName pTargetClass,
                 ProxyGenerator.InterfaceDescription[] pDescription) {
       JavaSource result = super.generate(pInterfaceFactory, pTargetClass,
           pDescription);
       result.clearImplements();
       return result;
     }
   }

   private class ProxyImplementationGenerator extends ProxyGenerator {
     protected JavaField getBackingObjectField(JavaSource pJs, InterfaceDescription[] pInterfaces) {
       return pJs.newJavaField("backingObject", getChainInterface(), JavaSource.PRIVATE);
     }
     protected JavaConstructor getConstructor(JavaSource pJs,
                       InterfaceDescription[] pInterfaces) {
       JavaConstructor jcon = pJs.newJavaConstructor(JavaSource.PROTECTED);
       jcon.addParam(getChainInterface(), "o");
       jcon.addIf("o == null");
       jcon.addThrowNew(NullPointerException.class,
           JavaSource.getQuoted("The supplied object must not be null."));
       jcon.addEndIf();
       jcon.addLine("backingObject = o;");
       return jcon;
     }

     public JavaMethod getInterfaceMethod(JavaSource pSource,
                     ProxyGenerator.InterfaceDescription pDescription,
                     java.lang.reflect.Method pMethod) {
       JavaMethod jm = pSource.newJavaMethod(pMethod);
       Parameter[] parameters = jm.getParams();
       JavaQName controllerInterfaceQName = JavaQNameImpl.getInstance(getControllerInterface());
       jm.clearParams();
       jm.addParam(controllerInterfaceQName, "pController");
       for (int i = 0;  i < parameters.length;  i++) {
         jm.addParam(parameters[i]);
       }
       List callParameters = new ArrayList();
       callParameters.add("pController");
       for (int i = 0;  i < parameters.length;  i++) {
         Parameter parameter = parameters[i];
         callParameters.add(", ");
         callParameters.add(parameter.getName());
       }
       jm.addLine((Void.TYPE.equals(pMethod.getReturnType()) ? "" : " return "),
           "backingObject.",
           pMethod.getName(), "(", callParameters, ");");
       return jm;
     }
     public JavaSource generate(JavaSourceFactory pImplementationFactory,
                 JavaQName pTargetClass,
                 ProxyGenerator.InterfaceDescription[] pDescription) {
       JavaSource result = super.generate(pImplementationFactory, pTargetClass, pDescription);
       result.clearImplements();
       result.addImplements(getChainInterface());
       return result;
     }
   }

   private class ControllerImplementationGenerator extends ProxyGenerator {
     protected JavaField getBackingObjectField(JavaSource pJs, InterfaceDescription[] pInterfaces) {
       return pJs.newJavaField("backingObject", getChainInterface(), JavaSource.PRIVATE);
     }
     protected JavaConstructor getConstructor(JavaSource pJs,
                       InterfaceDescription[] pInterfaces) {
       JavaConstructor jcon = pJs.newJavaConstructor(JavaSource.PUBLIC);
       jcon.addParam(getChainInterface(), "o");
       jcon.addIf("o == null");
       jcon.addThrowNew(NullPointerException.class,
           JavaSource.getQuoted("The supplied object must not be null."));
       jcon.addEndIf();
       jcon.addLine("backingObject = o;");
       return jcon;
     }
     public JavaMethod getInterfaceMethod(JavaSource pSource,
                     ProxyGenerator.InterfaceDescription pDescription,
                     java.lang.reflect.Method pMethod) {
       JavaMethod jm = pSource.newJavaMethod(pMethod);
       Parameter[] parameters = jm.getParams();
       List callParameters = new ArrayList();
       callParameters.add("this");
       for (int i = 0;  i < parameters.length;  i++) {
         Parameter parameter = parameters[i];
         callParameters.add(", ");
         callParameters.add(parameter.getName());
       }
       jm.addLine((Void.TYPE.equals(pMethod.getReturnType()) ? "" : " return "),
           "backingObject.",
           pMethod.getName(), "(", callParameters, ");");
       return jm;
     }
     protected JavaMethod getGetHeadOfChainMethod(JavaSource pSource) {
       JavaMethod jm = pSource.newJavaMethod("getHeadOfChain",
           getChainInterface(),
           JavaSource.PUBLIC);
       jm.addLine("return backingObject;");
       return jm;
     }
     public JavaSource generate(JavaSourceFactory pImplementationFactory,
                 JavaQName pTargetClass,
                 ProxyGenerator.InterfaceDescription[] pDescription) {
       JavaSource result = super.generate(pImplementationFactory, pTargetClass, pDescription);
       getGetHeadOfChainMethod(result);
       return result;
     }
   }

   public JavaSource[] generate(JavaSourceFactory pFactory) {
      ProxyGenerator.InterfaceDescription controllerDescription =
        new ProxyGenerator.InterfaceDescription();

      controllerInterface = getControllerInterface();
      controllerDescription.setInterface(controllerInterface);
      controllerDescription.setMandatory(true);
      ProxyGenerator.InterfaceDescription[] interfaces =
        new ProxyGenerator.InterfaceDescription[]{controllerDescription};

      ProxyGenerator proxyInterfaceGenerator = new ProxyInterfaceGenerator();
      JavaSource proxyInterface = proxyInterfaceGenerator.generate(pFactory, getChainInterface(), interfaces);
      proxyInterface.setType(JavaSource.INTERFACE);

      ProxyGenerator proxyImpGenerator = new ProxyImplementationGenerator();
      JavaSource proxyImplementation = proxyImpGenerator.generate(pFactory, getProxyClass(), interfaces);

      ProxyGenerator controllerImplementationGenerator = new ControllerImplementationGenerator();
      JavaSource controllerImplementation = controllerImplementationGenerator.generate(pFactory, getImplementationClass(), interfaces);

      return new JavaSource[]{controllerImplementation, proxyInterface, proxyImplementation};
   }
}
TOP

Related Classes of org.apache.ws.jaxme.js.pattern.ChainGenerator$ProxyInterfaceGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.