|
|||||||||||||||||||
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
MetaClassIOASM.java | 100% | 100% | 100% | 100% |
|
1 |
/*
|
|
2 |
* Copyright (C) The MetaClass Group. All rights reserved.
|
|
3 |
*
|
|
4 |
* This software is published under the terms of the Spice
|
|
5 |
* Software License version 1.1, a copy of which has been included
|
|
6 |
* with this distribution in the LICENSE.txt file.
|
|
7 |
*/
|
|
8 |
package org.codehaus.metaclass.io;
|
|
9 |
|
|
10 |
import java.io.File;
|
|
11 |
import java.io.FileInputStream;
|
|
12 |
import java.io.FileOutputStream;
|
|
13 |
import java.io.IOException;
|
|
14 |
import java.io.InputStream;
|
|
15 |
import java.io.OutputStream;
|
|
16 |
import org.objectweb.asm.ClassReader;
|
|
17 |
import org.objectweb.asm.ClassWriter;
|
|
18 |
import org.codehaus.metaclass.introspector.MetaClassException;
|
|
19 |
import org.codehaus.metaclass.model.ClassDescriptor;
|
|
20 |
|
|
21 |
/**
|
|
22 |
* Utility class to do IO on descriptors stored in .class files. Uses the ASM
|
|
23 |
* toolkit for .class reading and writing.
|
|
24 |
*
|
|
25 |
* @author Peter Donald
|
|
26 |
* @version $Revision: 1.1 $ $Date: 2003/12/11 08:41:50 $
|
|
27 |
*/
|
|
28 |
public class MetaClassIOASM |
|
29 |
implements MetaClassIO
|
|
30 |
{ |
|
31 |
/** Constant with instance of MetaClassIO. */
|
|
32 |
public static final MetaClassIOASM IO = new MetaClassIOASM(); |
|
33 |
|
|
34 |
/** Name of Attribute containing MetaClass descriptor. */
|
|
35 |
static final String ATTRIBUTE_NAME = "MetaClassDescriptor"; |
|
36 |
|
|
37 |
/** Extension used to find resource where metadata stored. */
|
|
38 |
private static final String EXTENSION = ".class"; |
|
39 |
|
|
40 |
/**
|
|
41 |
* @see MetaClassIO#getResourceName(String)
|
|
42 |
*/
|
|
43 | 16 |
public String getResourceName( final String classname )
|
44 |
{ |
|
45 | 16 |
return classname.replace( '.', File.separatorChar ) + EXTENSION;
|
46 |
} |
|
47 |
|
|
48 |
/**
|
|
49 |
* @see MetaClassIO#deserializeClass(InputStream)
|
|
50 |
*/
|
|
51 | 8 |
public ClassDescriptor deserializeClass( final InputStream input )
|
52 |
throws Exception
|
|
53 |
{ |
|
54 | 8 |
final ExtractMetaDataVisitor cv = visitClassFile( input ); |
55 | 8 |
final IOException ioe = cv.getIoe(); |
56 | 8 |
final ClassDescriptor descriptor = cv.getClassDescriptor(); |
57 | 8 |
if( null != ioe ) |
58 |
{ |
|
59 | 2 |
throw new MetaClassException( ioe.getMessage(), ioe ); |
60 |
} |
|
61 | 6 |
else if( null == descriptor ) |
62 |
{ |
|
63 | 2 |
final String message = "The .class file does " +
|
64 |
"not define MetaClass Descriptor Attribute.";
|
|
65 | 2 |
throw new MetaClassException( message ); |
66 |
} |
|
67 |
else
|
|
68 |
{ |
|
69 | 4 |
return descriptor;
|
70 |
} |
|
71 |
} |
|
72 |
|
|
73 |
/**
|
|
74 |
* Visit class file specified by input.
|
|
75 |
*
|
|
76 |
* @param input the input
|
|
77 |
* @return the visitor post-visit
|
|
78 |
* @throws IOException if error reading class
|
|
79 |
*/
|
|
80 | 6 |
ExtractMetaDataVisitor visitClassFile( final InputStream input ) |
81 |
throws IOException
|
|
82 |
{ |
|
83 | 6 |
final ClassReader reader = new ClassReader( input );
|
84 | 6 |
final ExtractMetaDataVisitor cv = new ExtractMetaDataVisitor();
|
85 | 6 |
reader.accept( cv, false );
|
86 | 6 |
return cv;
|
87 |
} |
|
88 |
|
|
89 |
/**
|
|
90 |
* @see MetaClassIO#writeDescriptor(File, ClassDescriptor)
|
|
91 |
*/
|
|
92 | 10 |
public void writeDescriptor( final File baseDir, |
93 |
final ClassDescriptor descriptor ) |
|
94 |
throws Exception
|
|
95 |
{ |
|
96 | 10 |
final String filename = getResourceName( descriptor.getName() ); |
97 | 10 |
final File file = new File( baseDir, filename ).getCanonicalFile();
|
98 | 10 |
final File backup = |
99 |
new File( baseDir, filename + ".bak" ).getCanonicalFile(); |
|
100 |
|
|
101 | 10 |
if( !file.exists() || !file.isFile() )
|
102 |
{ |
|
103 | 6 |
final String message = file + " is not a file";
|
104 | 6 |
throw new Exception( message ); |
105 |
} |
|
106 |
|
|
107 | 4 |
backup.delete(); |
108 | 4 |
file.renameTo( backup ); |
109 | 4 |
try
|
110 |
{ |
|
111 | 4 |
serializeDescriptor( file, backup, descriptor ); |
112 | 2 |
backup.delete(); |
113 |
} |
|
114 |
catch( final Exception e )
|
|
115 |
{ |
|
116 | 2 |
file.delete(); |
117 | 2 |
backup.renameTo( file ); |
118 |
} |
|
119 |
} |
|
120 |
|
|
121 |
/**
|
|
122 |
* Serialize class copying from input .class file to output.
|
|
123 |
*
|
|
124 |
* @param input the input .class file
|
|
125 |
* @param output the output .class file
|
|
126 |
* @param descriptor the descriptor
|
|
127 |
* @throws Exception if unable to output descriptor
|
|
128 |
*/
|
|
129 | 6 |
void serializeDescriptor( final File input,
|
130 |
final File output, |
|
131 |
final ClassDescriptor descriptor ) |
|
132 |
throws Exception
|
|
133 |
{ |
|
134 | 6 |
InputStream inputStream = null;
|
135 | 6 |
OutputStream outputStream = null;
|
136 | 6 |
try
|
137 |
{ |
|
138 | 6 |
inputStream = new FileInputStream( output );
|
139 | 4 |
outputStream = new FileOutputStream( input );
|
140 | 4 |
serializeClass( inputStream, outputStream, descriptor ); |
141 |
} |
|
142 |
finally
|
|
143 |
{ |
|
144 | 6 |
if( null != outputStream ) |
145 |
{ |
|
146 | 4 |
outputStream.close(); |
147 |
} |
|
148 | 6 |
if( null != inputStream ) |
149 |
{ |
|
150 | 4 |
inputStream.close(); |
151 |
} |
|
152 |
} |
|
153 |
} |
|
154 |
|
|
155 |
/**
|
|
156 |
* Write a ClassDescriptor to an output stream.
|
|
157 |
*
|
|
158 |
* @param output the stream to write class descriptor out to
|
|
159 |
* @param descriptor the ClassDescriptor to write out
|
|
160 |
* @throws Exception if unable ot write class descriptor
|
|
161 |
*/
|
|
162 | 4 |
public void serializeClass( final InputStream input, |
163 |
final OutputStream output, |
|
164 |
final ClassDescriptor descriptor ) |
|
165 |
throws Exception
|
|
166 |
{ |
|
167 | 4 |
final ClassReader reader = new ClassReader( input );
|
168 | 4 |
final ClassWriter cw = new ClassWriter( true ); |
169 | 4 |
final AddMetaDataAdapter cv = new AddMetaDataAdapter( cw, descriptor );
|
170 | 4 |
reader.accept( cv, false );
|
171 | 4 |
final byte[] bytes = cw.toByteArray();
|
172 | 4 |
output.write( bytes ); |
173 | 4 |
output.flush(); |
174 |
} |
|
175 |
} |
|
176 |
|
|