4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * BonYong Lee <bonyong.lee@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
25 package org.tizen.common;
27 import static org.tizen.common.util.IOUtil.getBytes;
28 import static org.tizen.common.util.IOUtil.tryClose;
30 import java.io.ByteArrayInputStream;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.lang.instrument.ClassFileTransformer;
36 import java.lang.instrument.IllegalClassFormatException;
37 import java.util.ArrayList;
38 import java.util.Arrays;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42 import org.tizen.common.util.IOUtil;
49 * Classloader for untestable class
51 * FIXME add {@link Package} info and {@link #getResource(String)}, {@link #getResourceAsStream(String)}, {@link #getResources(String)}
54 * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
61 * Logger for this instance
63 protected final Logger logger = LoggerFactory.getLogger( getClass() );
68 protected final ClassLoader parent;
70 protected ClassFileTransformer transformer = new Transformer();
73 * {@link ClassSource}s providing class contents
75 protected final ArrayList<ClassSource> sources = new ArrayList<ClassSource>();
78 * Constructor with {@link ClassSource}s
83 final ClassSource... source
90 * Constructor with parent class loader and class source
92 * @param parent {@link ClassLoader}
93 * @param sources {@link ClassSource}s
97 final ClassLoader parent,
98 final ClassSource... sources
101 this.parent = parent;
102 this.sources.addAll( Arrays.asList( sources ) );
106 * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
109 synchronized protected
113 final boolean resolve
115 throws ClassNotFoundException
117 // First, check if the class has already been loaded
118 Class<?> c = findLoadedClass( name );
121 if ( name.startsWith( "java." ) )
123 return ClassLoader.getSystemClassLoader().loadClass( name );
127 c = findClass( name );
128 } catch (ClassNotFoundException e) {
129 if ( null != parent )
131 c = parent.loadClass( name );
135 throw new ClassNotFoundException();
147 * @see java.lang.ClassLoader#findClass(java.lang.String)
155 throws ClassNotFoundException
157 logger.trace( "Class name :{}", name );
158 final String path = name.replace( '.', '/' ) + ".class";
159 for ( final ClassSource source : sources )
161 logger.trace( "Source :{}", source );
162 InputStream in = null;;
165 in = source.getResource( path );
166 final Class<?> clazz = define( name, in );
172 catch ( final IOException e )
181 // final ClassLoader loader = getClass().getClassLoader();
183 // final InputStream in = loader.getResourceAsStream( path );
186 // final Class<?> clazz = define( name, in );
187 // if ( null != clazz )
197 throw new ClassNotFoundException();
201 protected Class<?> define(
211 byte[] bytes = getBytes( in );
212 final String qn = name.replace( '.', '/' );
213 bytes = transformer.transform( this, qn, null, null, bytes );
214 logger.trace( "{} bytes read", bytes.length );
215 return defineClass( name, bytes, 0, bytes.length );
216 } catch ( final IOException e )
218 } catch ( final IllegalClassFormatException e )
226 * Write log file about converted class
228 * @param path file path to write
229 * @param bytes class contents
231 * @throws IOException If file can't be write
241 FileOutputStream fileOut = null;
244 File logFile = new File( "test/log/" + path );
245 logFile.getParentFile().mkdirs();
246 fileOut = new FileOutputStream( logFile );
247 IOUtil.redirect( new ByteArrayInputStream( bytes ), fileOut );