Package com.asual.summer.core.faces

Source Code of com.asual.summer.core.faces.FacesFunctionMapper

/*
* 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 com.asual.summer.core.faces;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;

import javax.el.FunctionMapper;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
*
* @author Rostislav Hristov
*
*/
public class FacesFunctionMapper extends FunctionMapper {
 
  private final Log logger = LogFactory.getLog(getClass());

  private static HashMap<String, JavaFileObject> classes = new HashMap<String, JavaFileObject>();
 
  private static ClassLoader classLoader = new ClassLoader() {
   
      protected Class<?> findClass(String name) throws ClassNotFoundException {
          if (classes.containsKey(name)) {
              byte[] bytes = ((MemoryJavaFileObject) classes.get(name)).baos.toByteArray();
              return defineClass(name, bytes, 0, bytes.length);
          }
          return Class.forName(name, true, getClass().getClassLoader());
      }
  };
 
  private class JavaObjectFromString extends SimpleJavaFileObject {
   
      private String contents = null;
     
      public JavaObjectFromString(String className, String contents) throws Exception{
          super(new URI(className + Kind.SOURCE.extension), Kind.SOURCE);
          this.contents = contents;
      }
     
      public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
          return contents;
      }
  }
 
  private class MemoryJavaFileObject extends SimpleJavaFileObject {

      ByteArrayOutputStream baos;

      MemoryJavaFileObject(String name, Kind kind) {
          super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), kind);
      }

      public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException, IllegalStateException, UnsupportedOperationException {
          throw new UnsupportedOperationException();
      }

      public InputStream openInputStream() throws IOException, IllegalStateException, UnsupportedOperationException {
          return new ByteArrayInputStream(baos.toByteArray());
      }

      public OutputStream openOutputStream() throws IOException, IllegalStateException, UnsupportedOperationException {
          return baos = new ByteArrayOutputStream();
      }
  }
 
  private class MemoryFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
   
      MemoryFileManager (JavaCompiler compiler){
          super(compiler.getStandardFileManager(null,null,null));
      }
     
      public JavaFileObject getJavaFileForOutput(Location location, String name, Kind kind, FileObject sibling) throws java.io.IOException {
          JavaFileObject jfo = new MemoryJavaFileObject(name, kind);
          classes.put(name, jfo);
          return jfo;
      }
  }
 
  public Method resolveFunction(String namespace, final String fn) {
   
    try {
     
      String className = fn + "Script";
     
      if (!classes.containsKey(className)) {
       
        StringBuilder out = new StringBuilder();
        out.append("public class " + className + " {");
        out.append("  private static String fn = \"" + fn + "\";");
        out.append("  public static Object call(Object... args) throws Exception {");
        out.append("    return Class.forName(\"com.asual.summer.core.util.ScriptUtils\")");
        out.append("      .getDeclaredMethod(\"call\", String.class, Object[].class).invoke(null, fn, args);");
        out.append("  }");
        out.append("}");
       
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        JavaFileManager jfm = new MemoryFileManager(compiler);
        JavaFileObject file = new JavaObjectFromString(className, out.toString());
        compiler.getTask(null, jfm, null, null, null, Arrays.asList(file)).call();       
      }
     
        return Class.forName(className, true, classLoader).getDeclaredMethod("call", Object[].class);
       
    } catch (Exception e) {
     
      logger.error(e.getMessage(), e);
    }
   
    return null;
  }
 
}
TOP

Related Classes of com.asual.summer.core.faces.FacesFunctionMapper

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.