Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source.
   *
   * Copyright 2012 Red Hat, Inc.
   *
   * 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.jboss.classfilewriter;
 
 import java.util.List;
 import java.util.Set;
 

Author(s):
Stuart Douglas
 
 public class ClassFile implements WritableEntry {
 
     private final String name;
 
     private final String superclass;
 
     private final int accessFlags;
 
     private final int version;
 
     private final ConstPool constPool = new ConstPool();
 
     private final List<Stringinterfaces = new ArrayList<String>();
 
     private final Set<ClassFieldfields = new HashSet<ClassField>();
 
     private final Set<ClassMethodmethods = new HashSet<ClassMethod>();
 
     private byte[] bytecode;
 
     private final List<Attributeattributes = new ArrayList<Attribute>();
 
 
     public ClassFile(String nameString superclassString... interfaces) {
         this. = .;
         this. = name.replace('/''.'); // store the name in . form
         this. = superclass;
         this. = AccessFlag.of(..);
         this..addAll(Arrays.asList(interfaces));
     }
 
     public void addInterface(String iface) {
         this..add(iface);
     }
 
     // fields
     
Adds a field with the given name and descriptor.
 
     public ClassField addField(int accessFlagsString nameString descriptor) {
         return addField(accessFlagsnamedescriptornull);
     }
 
     public ClassField addField(int accessFlagsString nameString descriptorString signature) {
         ClassField field = new ClassField((shortaccessFlagsnamedescriptorthis);
         if (.contains(field)) {
             throw new DuplicateMemberException("Field  already exists. Field: " + name + " Descriptor:" + signature);
         }
        .add(field);
        field.setSignature(signature);
        return field;
    }
    public ClassField addField(int accessFlagsString nameClass<?> type) {
        return addField(accessFlagsname, DescriptorUtils.makeDescriptor(type));
    }
    public ClassField addField(int accessFlagsString nameClass<?> typeString genericSignature) {
        return addField(accessFlagsname, DescriptorUtils.makeDescriptor(type), genericSignature);
    }
    public ClassField addField(Field field) {
        ClassField classField = addField((shortfield.getModifiers(), field.getName(), field.getType(), null);
        for (Annotation annotation : field.getDeclaredAnnotations()) {
            classField.getRuntimeVisibleAnnotationsAttribute().addAnnotation(
                    AnnotationBuilder.createAnnotation(annotation));
        }
        return classField;
    }
    // methods
    public ClassMethod addMethod(int accessFlagsString nameString returnTypeString... parameters) {
        ClassMethod method = new ClassMethod(namereturnTypeparametersaccessFlagsthis);
        if (.contains(method)) {
            throw new DuplicateMemberException("Method  already exists. Method: " + name + " Parameters:"
                    + Arrays.toString(parameters) + " Return Type: " + returnType);
        }
        .add(method);
        return method;
    }

    
Adds a method with the same signiture as the given method, including exception types

The new method will have the same modifier as the original method, except that the abstract and native flags will be stripped.

TODO: annotations and signiture attribute

    public ClassMethod addMethod(Method method) {
        ClassMethod classMethod = addMethod(method.getModifiers() & (~.) & (~.), method
                .getName(), DescriptorUtils.makeDescriptor(method.getReturnType()), DescriptorUtils.parameterDescriptors(method
                .getParameterTypes()));
        for (Class<?> e : method.getExceptionTypes()) {
            classMethod.addCheckedExceptions((Class<? extends Exception>) e);
        }
        for (Annotation annotation : method.getDeclaredAnnotations()) {
            classMethod.getRuntimeVisibleAnnotationsAttribute().addAnnotation(
                    AnnotationBuilder.createAnnotation(annotation));
        }
        int count = 0;
        for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
            for (Annotation annotation : parameterAnnotations) {
                classMethod.getRuntimeVisibleParameterAnnotationsAttribute().addAnnotation(count,
                        AnnotationBuilder.createAnnotation(annotation));
            }
            count++;
        }
        return classMethod;
    }

    
Adds a constructor with the same signiture as the given constrcutor, including exception types

TODO: annotations and signiture attribute

    public ClassMethod addConstructor(Constructor<?> method) {
        ClassMethod classMethod = addMethod(method.getModifiers(), "<init>""V", DescriptorUtils.parameterDescriptors(method
                .getParameterTypes()));
        for (Class<?> e : method.getExceptionTypes()) {
            classMethod.addCheckedExceptions((Class<? extends Exception>) e);
        }
        for (Annotation annotation : method.getDeclaredAnnotations()) {
            classMethod.getRuntimeVisibleAnnotationsAttribute().addAnnotation(
                    AnnotationBuilder.createAnnotation(annotation));
        }
        int count = 0;
        for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
            for (Annotation annotation : parameterAnnotations) {
                classMethod.getRuntimeVisibleParameterAnnotationsAttribute().addAnnotation(count,
                        AnnotationBuilder.createAnnotation(annotation));
            }
            count++;
        }
        return classMethod;
    }
    public void write(ByteArrayDataOutputStream streamthrows IOException {
        // first make sure everything we need is in the const pool
        short nameIndex = .addClassEntry();
        short superClassIndex = .addClassEntry();
        List<ShortinterfaceIndexes = new ArrayList<Short>(.size());
        for (String i : ) {
            interfaceIndexes.add(.addClassEntry(i));
        }
        stream.writeInt(0xCAFEBABE);// magic
        stream.writeInt();
        .write(stream);
        stream.writeShort();
        stream.writeShort(nameIndex);
        stream.writeShort(superClassIndex);
        stream.writeShort(interfaceIndexes.size()); // interface count
        for (short i : interfaceIndexes) {
            stream.writeShort(i);
        }
        stream.writeShort(.size()); // field count
        for (ClassField field : ) {
            field.write(stream);
        }
        stream.writeShort(.size()); // method count
        for (ClassMethod method : ) {
            method.write(stream);
        }
        stream.writeShort(.size()); // attribute count
        for (Attribute attribute : ) {
            attribute.write(stream);
        }
    }
    private static java.lang.reflect.Method defineClass1defineClass2;
    static {
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                public Object run() throws Exception {
                    Class<?> cl = Class.forName("java.lang.ClassLoader"falsenull);
                     = cl.getDeclaredMethod("defineClass"new Class[] { String.classbyte[].classint.class,
                            int.class });
                    .setAccessible(true);
                     = cl.getDeclaredMethod("defineClass"new Class[] { String.classbyte[].classint.class,
                            int.classProtectionDomain.class });
                    .setAccessible(true);
                    return null;
                }
            });
        } catch (PrivilegedActionException pae) {
            throw new RuntimeException("cannot initialize ClassFile"pae.getException());
        }
    }
    public Class<?> define(ClassLoader loader) {
        return define(loadernull);
    }

    
Definines the class using the given ClassLoader and ProtectionDomain
    public Class<?> define(ClassLoader loaderProtectionDomain domain) {
        try {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                final int index = .lastIndexOf('.');
                final String packageName;
                if(index == -1 ) {
                    packageName = "";
                } else {
                    packageName = .substring(0, index);
                }
                RuntimePermission permission = new RuntimePermission("defineClassInPackage." + packageName);
                sm.checkPermission(permission);
            }
            byte[] b = toBytecode();
            java.lang.reflect.Method method;
            Object[] args;
            if (domain == null) {
                method = ;
                args = new Object[] { .replace('/''.'), bnew Integer(0), new Integer(b.length) };
            } else {
                method = ;
                args = new Object[] { .replace('/''.'), bnew Integer(0), new Integer(b.length), domain };
            }
            Class<?> clazz = (Class<?>) method.invoke(loaderargs);
            return clazz;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public byte[] toBytecode() {
        // TODO: throw illegal state exception if the class file is modified after writing
        if ( == null) {
            try {
                ByteArrayDataOutputStream out = new ByteArrayDataOutputStream();
                write(out);
                 = out.getBytes();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return ;
    }
    public ConstPool getConstPool() {
        return ;
    }

    
returns the type descriptor for the class

Returns:
    public String getDescriptor() {
        return 'L' +  + ';';
    }
        return ;
    }

    
Returns the generated class name

Returns:
The generated class name
    public String getName() {
        return ;
    }

    

Returns:
The generated superclass name
    public String getSuperclass() {
        return ;
    }

    

Returns:
The interfaces implemented by this class
    public List<StringgetInterfaces() {
        return Collections.unmodifiableList();
    }

    

Returns:
This class's fields
    public Set<ClassFieldgetFields() {
        return Collections.unmodifiableSet();
    }

    

Returns:
This classes methods
    public Set<ClassMethodgetMethods() {
        return Collections.unmodifiableSet();
    }
New to GrepCode? Check out our FAQ X