/*
* Copyright 2004-2015 the Seasar Foundation and the Others.
*
* 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.seasar.framework.jpa.util;
import java.util.List;
import java.util.Set;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitInfo;
import org.seasar.framework.jpa.PersistenceClassTransformer;
import org.seasar.framework.util.tiger.CollectionsUtil;
/**
* 未ロードのクラスをトランスフォームし、トランスフォーム後のクラスのクラスを適切なクラスローダーにロードするクラスローダです。
*
* @author taedium
*/
public class TransformClassLoader extends AbstractClassLoader {
/** 永続クラスのトランスフォーマ */
protected PersistenceClassTransformer persistenceClassTransformer;
/** 永続ユニット情報 */
protected PersistenceUnitInfo persistenceUnitInfo;
/** クラストランスフォーマのリスト */
protected List<ClassTransformer> transformers = CollectionsUtil
.newArrayList();
/**
* インスタンスを構築します。
* <p>
* コンテキストクラスローダからロードされるクラス及び、<code>java.</code>または<code>javax.</code>で始まるクラスを除いて
* 親クラスローダに委譲せず、{@link PersistenceClassTransformer#transform(PersistenceUnitInfo, String, byte[])}
* を呼び出してロードするように構成します。
* </p>
*
*/
public TransformClassLoader() {
this(Thread.currentThread().getContextClassLoader());
}
/**
* インスタンスを構築します。
* <p>
* ブートストラップクラスローダからロードされるクラス及び、<code>java.</code>または<code>javax.</code>で始まるクラスを除いて
* 親クラスローダに委譲せず、{@link PersistenceClassTransformer#transform(PersistenceUnitInfo, String, byte[])}
* を呼び出してロードするように構成します。
* </p>
*
* @param parent
* 親クラスローダ
*/
public TransformClassLoader(ClassLoader parent) {
super(parent);
}
/**
* インスタンスを構築します。
* <p>
* <code>includedNames</code>に含まれる名前のクラスのみ、 親クラスローダに委譲せず、
* {@link PersistenceClassTransformer#transform(PersistenceUnitInfo, String, byte[])}を呼び出してロードするように構成します。
* ただし、ブートストラップクラスローダからロードされるクラス及び、 <code>java.</code>または<code>javax.</code>で始まるクラスを除きます。
* </p>
*
* @param parent
* 親クラスローダ
* @param includedNames
* 親より先にロードする対象となるクラス名のセット
*/
public TransformClassLoader(final ClassLoader parent,
final Set<String> includedNames) {
super(parent, includedNames);
}
/**
* 永続クラスのトランスフォーマを登録します。
*
* @param persistenceClassTransformer
* 永続クラスのトランスフォーマ
*/
public void registerPersistenceClassTransformer(
final PersistenceClassTransformer persistenceClassTransformer) {
this.persistenceClassTransformer = persistenceClassTransformer;
}
/**
* 永続ユニット情報を登録します。
*
* @param persistenceUnitInfo
* 永続ユニット情報
*/
public void registerPersistenceUnitInfo(
final PersistenceUnitInfo persistenceUnitInfo) {
this.persistenceUnitInfo = persistenceUnitInfo;
}
/**
* クラストランスフォーマを登録します。
*
* @param transformer
* クラストランスフォーマ
*/
public void addTransformer(final ClassTransformer transformer) {
transformers.add(transformer);
}
@Override
protected Class<?> doDefineClass(String className, byte[] bytes) {
return persistenceClassTransformer.transform(persistenceUnitInfo,
className, bytes);
}
}