1 Reply Latest reply on May 3, 2006 10:53 AM by bblfish

    casting problem

    bblfish

      I am having trouble casting the return value of a function call to the correct type of a field. FieldSetEditor.edit calls ClassRewriter.setField
      which returns an Object. I would like the return value to be cast to the correct type. I tried defining setField with generics,

      public <T> T setField(Clazz<T> ....) {
       ...
       return (T)object;
      }
      


      but as generics are not supported, that does not help...

      Also what would happen if someone entered a " in the string that
      I pass in the field?


      package com.sun.labs.rdf;
      
      import com.sun.labs.rdf.annotations.RDF;
      import javassist.*;
      import javassist.expr.ExprEditor;
      import javassist.expr.FieldAccess;
      
      /**
       * @author Henry Story
       */
      public class ClassRewriter {
      
       public static String reverse(String value) {
       int length = value.length();
       StringBuffer buff = new StringBuffer(length);
       for (int i = length - 1; i >= 0; i--) {
       buff.append(value.charAt(i));
       }
       System.out.println("TranslateEditor.reverse returning " + buff);
       return buff.toString();
       }
      
       public static Object setField(Object o,String url, Object value) {
       System.out.println("setting o="+o+" R="+url+" v="+value);
       return value;
       }
      
       public static void main(String[] args) {
       if (args.length != 0) {
       try {
       // set up class loader with translator
       EditorTranslator xtor = new EditorTranslator(new FieldSetEditor());
       ClassPool pool = ClassPool.getDefault();
       Loader loader = new Loader();
       loader.addTranslator(pool, xtor);
      
       // invoke the "main" method of the application class
      
       loader.run(args);
       } catch (Throwable ex) {
       ex.printStackTrace();
       }
       } else {
       System.out.println("Usage: ClassRewriter main-class args...");
       }
       }
      
      
      }
      
      class EditorTranslator implements Translator {
       private ExprEditor m_editor;
      
       EditorTranslator(ExprEditor editor) {
       m_editor = editor;
       }
      
       public void start(ClassPool pool) {
       System.out.println("start pool");
       }
      
      
       public void onLoad(ClassPool pool, String cname)
       throws NotFoundException, CannotCompileException {
       System.out.println("cname(in Onload)=" + cname);
       CtClass clas = pool.get(cname);
       clas.instrument(m_editor);
       }
      }
      
      class FieldSetEditor extends ExprEditor {
      
       FieldSetEditor() {
       }
      
       public void edit(FieldAccess arg) throws CannotCompileException {
       System.out.println("in edit- field=" + arg.getFieldName());
       try {
       String field;
       if ((field=containsRDF(arg.getField().getAnnotations()))!=null) {
       if (arg.isWriter()) {
       StringBuffer code = new StringBuffer();
       code.append("$0.");
       code.append(arg.getFieldName());
      // code.append("=com.sun.labs.rdf.sommer.ClassRewriter.reverse($1);");
       code.append("=($r)com.sun.labs.rdf.sommer.ClassRewriter.setField($0,\""+field+"\",$1);");
       System.out.println("code="+code.toString());
       arg.replace(code.toString());
       }
       }
       } catch (ClassNotFoundException e) {
       e.printStackTrace(); //todo: decide what exception to throw
       } catch (NotFoundException e) {
       e.printStackTrace(); //todo: decide what exception to throw
       }
       }
      
       private String containsRDF(Object[] annotations) {
       for (Object o: annotations) {
       if (o instanceof RDF) return ((RDF)o).value();
       }
       return null;
       }
      }
      


        • 1. Re: casting problem
          bblfish

          Ok. I found the solution. arg.getField().getType().getName()
          gives me the type to cast to, and I add that to the code as shown here:

          StringBuffer code = new StringBuffer();
           code.append("$0.");
           code.append(arg.getFieldName());
           code.append("=(" + arg.getField().getType().getName() + ")" +
           "com.sun.labs.rdf.sommer.ClassRewriter.setField("
           + "$type,$0,\"" + field + "\",$1);");
          arg.replace(code.toString());
          

          which ends up producing code like this:
          $0.m_b=(java.lang.String)com.sun.labs.rdf.sommer.ClassRewriter.setField($type,$0,"http://eg.com/bean/b",$1);