Package org.gocha.jdk

Source Code of org.gocha.jdk.TemplateGenerator$TemplateMapProperties

/*******************************************************************************
blogger-cli Консольные инструменты по работе с blogger.com
(с) Камнев Георгий Павлович 2011 GPLv2

Данная программа является свободным программным обеспечением. Вы вправе
распространять ее и/или модифицировать в соответствии с условиями версии 2
либо по вашему выбору с условиями более поздней версии
Стандартной Общественной Лицензии GNU, опубликованной Free Software Foundation.

Мы распространяем данную программу в надежде на то, что она будет вам полезной,
однако НЕ ПРЕДОСТАВЛЯЕМ НА НЕЕ НИКАКИХ ГАРАНТИЙ,
в том числе ГАРАНТИИ ТОВАРНОГО СОСТОЯНИЯ ПРИ ПРОДАЖЕ
и ПРИГОДНОСТИ ДЛЯ ИСПОЛЬЗОВАНИЯ В КОНКРЕТНЫХ ЦЕЛЯХ.
Для получения более подробной информации ознакомьтесь
со Стандартной Общественной Лицензией GNU.

Вместе с данной программой вы должны были получить экземпляр
Стандартной Общественной Лицензии GNU.
Если вы его не получили, сообщите об этом в Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*******************************************************************************/

package org.gocha.jdk;

import java.io.StringWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.gocha.text.IndentStackWriter;
import org.gocha.text.TextUtil;

/**
* Генератор Java кода - шаблона сообщений.<br/>
*
* Данный генератор, создает исходный код для формирования текстовых сообщений.
* Текстовое сообщение - это некий шаблон в котором указаны куда подставлять значения переменных.<br/><br/>
* Вот пример шаблона: <br/>
* <font face="monospace">Hello <b>{0}</b></font> <br/>
* {0} - Это место куда будет подставлено значение переданной переменной.<br/>
* <br/>
* Так несколько сооблщений объединяются в интерфейс следующего вида:<br/>
* <pre style="color:blue">
* public interface TestMessages
* {
*   &#64;template(def="Hello {0}")
*   String hello(String userName);
* }
* </pre>
* Используя рефлексию генерируется класс-реализация: <br/>
* <pre style="color:blue"> gen = new TemplateGenerator();
* gen.setTemplateInterface(TestMessages.class);
* gen.setClassName("torg.gocha.text.TestMessagesImpl");
*
* TemplateGenerator.GeneratedSource src = gen.generateJavaCode();
* System.out.println(src.getSource());
* </pre>
* Результат генерации выглдит так:
*<pre style="color:blue">package org.gocha.text;
*
import java.util.Map;
import org.gocha.text.TextUtil;

public class TestMessagesImpl
  implements
    org.gocha.jdk.TestMessages
{
  protected Map templates = null;
  public TestMessagesImpl ( Map templates )
  {
    this.templates = templates;
  }
  public String hello ( java.lang.String arg0 )
  {
    if ( templates.containsKey( "hello" ) ){
      Object tmplObj = templates.get( "hello" );
      if( tmplObj!=null ){
        String tmplString = tmplObj.toString();
        return TextUtil.template( tmplString , arg0 );
      }
    }
    return TextUtil.template( "Hello {0}", arg0 );
  }
}</pre>
* <br/>
* Потом что бы использовать этот объект в коде:<br/>
* <pre style="color:blue">
* Map&lt;String,String&gt; templates = new HashMap&lt;String, String&gt;();
* templates.put("hello", "Привет {0}");
*
* TestMessagesImpl tmplateObject = new TestMessagesImpl( templates );
* System.out.println( tmplateObject.hello( "Jhon" ) );
* </pre>
* Для формирования значения из шаблона используется класс org.gocha.text.TextUtil
* @author gocha
* @see org.gocha.text.TextUtil#template(java.lang.String, java.lang.Object[])
*/
public class TemplateGenerator
{
    public TemplateGenerator(){
    }
   
    @java.lang.annotation.Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface template{
        String def() default "";
    }
   
    // <editor-fold defaultstate="collapsed" desc="templateInterface">
    private Class templateInterface = null;
   
    public Class getInterface() {
        return templateInterface;
    }
   
    public void setInterface(Class templateInterface) {
        this.templateInterface = templateInterface;
    }
    // </editor-fold>
   
    // <editor-fold defaultstate="collapsed" desc="package and class name">
    protected String getPackageName() {
        String _className = getClassName();
        String shortClazzName = _className;
        String pkg = null;
        if (_className.contains(".")) {
            int idx = _className.lastIndexOf(".");
            pkg = _className.substring(0, idx);
            pkg = TextUtil.trimEnd(pkg, ".");
            pkg = TextUtil.trimStart(pkg, ".");
           
            shortClazzName = _className.substring(idx);
            shortClazzName = TextUtil.trimStart(shortClazzName, ".");
        }
        return pkg;
    }
   
    protected String getShortClassName() {
        String _className = getClassName();
        String shortClazzName = _className;
        String pkg = null;
        if (_className.contains(".")) {
            int idx = _className.lastIndexOf(".");
            pkg = _className.substring(0, idx);
            pkg = TextUtil.trimEnd(pkg, ".");
            pkg = TextUtil.trimStart(pkg, ".");
           
            shortClazzName = _className.substring(idx);
            shortClazzName = TextUtil.trimStart(shortClazzName, ".");
        }
        return shortClazzName;
    }// </editor-fold>
   
    // <editor-fold defaultstate="collapsed" desc="className">
    private String className = "className";
   
    public String getClassName() {
        if( className==null )className = "className";
        return className;
    }
   
    public void setClassName(String className) {
        this.className = className;
    }// </editor-fold>
   
    public static class GeneratedSource{
        protected String source = null;
        protected Map<String,String> defaultTemplates = null;
       
        public GeneratedSource(String source,Map<String,String> defTemplates){
            this.source = source;
            this.defaultTemplates = defTemplates;
        }

        public Map<String, String> getDefaultTemplates() {
            return defaultTemplates;
        }

        public String getSource() {
            return source;
        }
    }
   
    private Map<String,String> defTemplates = null;
   
    public GeneratedSource generateJavaCode(){
        Class tmplItf = getInterface();
        if( tmplItf==null )
            throw new IllegalStateException("getTemplateInterface() == null");
       
        StringWriter sw = new StringWriter();
        IndentStackWriter writer = new IndentStackWriter(sw);
        writer.indent("  ");
        writer.level(0);
       
        if( !tmplItf.isInterface() )
            throw new IllegalStateException("getTemplateInterface() is not interface");
       
        defTemplates = new HashMap<String, String>();
        gen(writer);
       
        writer.flush();
       
        GeneratedSource src = new GeneratedSource(sw.toString(), defTemplates);
        return src;
    }
   
    public interface TemplateMapProperties{
        public Map<String,String> getTemplateMap();
    }
   
    private void gen(IndentStackWriter writer){
        Class tmplItf = getInterface();
       
        String shortClazzName = getShortClassName();
        String pkg = getPackageName();
        if( pkg!=null ){
            writer.println("package "+pkg+";");
            writer.println("");
        }
       
        genImport(writer);
       
        writer.println("public class " + shortClazzName);
       
        //implements
        writer.incLevel();
        writer.println("implements ");
        writer.incLevel();
        writer.println(tmplItf.getName());
//        writer.println(", "+TemplateGenerator.class.getName()+".TemplateMapProperties");
        writer.decLevel();
        writer.decLevel();
        //implements end
       
        writer.println("{");
        writer.incLevel();
       
        genFields(writer);
        genConstruct(writer);
//        genImplTemplateMapProperties(writer);
       
        Method[] methods = tmplItf.getMethods();
        for( Method m : methods ){
            genMeth(writer, m);
        }
       
        writer.decLevel();
        writer.println("}");
    }
   
    private void genImport(IndentStackWriter writer){
        writer.println("import java.util.Map;");
        writer.println("import org.gocha.text.TextUtil;");
        writer.println("");
    }
   
    private void genFields(IndentStackWriter writer){
        writer.println("protected Map templates = null;");
    }
   
//    private void genImplTemplateMapProperties(IndentStackWriter writer){
//        writer.println("public Map<String,String> getTemplateMap()");
//        writer.println("{");
//        writer.incLevel();
//        writer.println("return this.templates;");
//        writer.decLevel();
//        writer.println("}");
//    }
   
    private void genConstruct(IndentStackWriter writer){
        String clazzName = getShortClassName();
        writer.println("public "+clazzName+" ( Map templates )");
        writer.println("{");
        writer.incLevel();
        writer.println("this.templates = templates;");
        writer.decLevel();
        writer.println("}");
    }
   
    private void genMeth(IndentStackWriter writer,Method m){
        int mod = m.getModifiers();
        if( Modifier.isStatic(mod) )return;
       
        Class retType = m.getReturnType();
        if( !retType.equals(String.class) )return;
       
        Class[] mThrows = m.getExceptionTypes();
        if( mThrows.length>0 )return;
       
        String defTempl = null;
        TemplateGenerator.template tmpl =
        m.getAnnotation(TemplateGenerator.template.class);
        if( tmpl!=null && tmpl.def()!=null && tmpl.def().length()>0 )
            defTempl = tmpl.def();
       
//        Type[] genParams = m.getGenericParameterTypes();
//        Type[] genThrows = m.getGenericExceptionTypes();
//        Type genRet = m.getGenericReturnType();
//        genParams[0].getClass().
//        if( genParams.length>0 )return;
//        if( genThrows.length>0 )return;
//        if( genRet!=null )return;
       
        Class[] mParams = m.getParameterTypes();
        String methodName = m.getName();
       
        writer.print("public ");
        writer.print("String ");
        writer.print(methodName);
        writer.print(" ( ");
        int idx = -1;
        for(Class paramClass:mParams){
            idx++;
            if( idx>0 )writer.print(", ");
            writer.print(paramClass.getName());
            writer.print(" ");
            writer.print("arg");
            writer.print(idx);
        }
        writer.println(" )");
        writer.println("{");
        writer.incLevel();
       
        // body
        writer.println("Object[] args = new Object[]{");
        for( int i=0; i<mParams.length; i++ ){
            if( i>0 )writer.print(", ");
            writer.println("arg"+i);
        }
        writer.println("};");
       
        writer.println("if ( templates.containsKey( \""+methodName+"\" ) ){");
        writer.incLevel();
        writer.println("Object tmplObj = templates.get( \""+methodName+"\" );");
        writer.println("if( tmplObj!=null ){");
        writer.incLevel();
        writer.println("String tmplString = tmplObj.toString();");
//        writer.println("String tmpl = templates.get( \""+methodName+"\" );");
        writer.print("return TextUtil.template( tmplString ");
//        for( int i=0; i<mParams.length; i++ ){
//            writer.print(", arg"+i);
//        }
        writer.print( ", args" );
        writer.println(" );");
        writer.decLevel();
        writer.println("}");
        writer.decLevel();
        writer.println("}");

        writer.print("return TextUtil.template( ");
       
        if( defTempl!=null ){
            writer.print(TextUtil.encodeStringConstant(defTempl));
            defTemplates.put(methodName, defTempl);
        }else{
            // generate template by args
            StringBuilder t = new StringBuilder();
            t.append(methodName);
            t.append("(");
            for( int i=0; i<mParams.length; i++ ){
                if( i>0 )t.append(", ");
                t.append("{");
                t.append(i);
                t.append("}");
            }
            t.append(")");
            writer.print(TextUtil.encodeStringConstant(t.toString()));
            defTemplates.put(methodName, t.toString());
        }
       
//        for( int i=0; i<mParams.length; i++ ){
//            writer.print(", arg"+i);
//        }
        writer.print(", args");
        writer.println(" );");
        // body end
       
        writer.decLevel();
        writer.println("}");
    }
}
TOP

Related Classes of org.gocha.jdk.TemplateGenerator$TemplateMapProperties

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.