Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* glassfish/bootstrap/legal/CDDLv1.0.txt or
* https://glassfish.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
* add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your
* own identifying information: Portions Copyright [yyyy]
* [name of copyright owner]
*/
// Copyright (c) 2005, 2006, Oracle. All rights reserved.
package oracle.toplink.essentials.internal.weaving;
// J2SE imports
import java.lang.instrument.*;
import java.io.FileOutputStream;
import java.security.ProtectionDomain;
import java.util.Map;
import java.util.StringTokenizer;
import java.io.File;
import javax.persistence.spi.ClassTransformer;
// ASM imports
import oracle.toplink.libraries.asm.*;
import oracle.toplink.libraries.asm.attrs.Attributes;
// TopLink imports
import oracle.toplink.essentials.logging.SessionLog;
import oracle.toplink.essentials.sessions.Session;
/**
* INTERNAL:
* This class performs dynamic bytecode weaving: for each attribute
* mapped with One To One mapping with Basic Indirection it substitutes the
* original attribute's type for ValueHolderInterface.
*/
public class TopLinkWeaver implements ClassTransformer {
public static final String WEAVING_OUTPUT_PATH = "toplink.weaving.output.path";
public static final String WEAVING_SHOULD_OVERWRITE = "toplink.weaving.overwrite.existing";
public static final String WEAVER_NOT_OVERWRITING = "weaver_not_overwriting";
public static final String WEAVER_COULD_NOT_WRITE = "weaver_could_not_write";
protected Session session; // for logging
// Map where the key is className in JVM '/' format
protected Map classDetailsMap;
public TopLinkWeaver(Session session, Map classDetailsMap) {
this.session = session;
this.classDetailsMap = classDetailsMap;
}
public Map getClassDetailsMap() {
return classDetailsMap;
}
// @Override: well, not precisely. I wanted the code to be 1.4 compatible,
// so the method is written without any Generic type 's in the signature
public byte[] transform(ClassLoader loader, String className,
Class classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
/*
* The ClassFileTransformer callback - when called by the JVM's
* Instrumentation implementation - is invoked for every class loaded.
* Thus, we must check the classDetailsMap to see if we are 'interested'
* in the class.
*
* Note: when invoked by the OC4J wrapper class
* oracle.toplink.essentials.internal.ejb.cmp3.oc4j.OC4JClassTransformer,
* callbacks are made only for the 'interesting' classes
*/
ClassDetails classDetails = (ClassDetails)classDetailsMap.get(className);
if (classDetails != null) {
ClassReader cr = new ClassReader(classfileBuffer);
ClassWriter cw = new ClassWriter(true, true);
TopLinkClassWeaver tcw = new TopLinkClassWeaver(cw, classDetails);
cr.accept(tcw, Attributes.getDefaultAttributes(), false);
if (tcw.alreadyWeaved) {
return null;
}
byte[] bytes = cw.toByteArray();
String outputPath = System.getProperty(WEAVING_OUTPUT_PATH, "");
if (!outputPath.equals("")) {
outputFile(className, bytes, outputPath);
}
if (tcw.weavedVH) {
return bytes;
}
}
return null; // returning null means 'use existing class bytes'
}
protected void outputFile(String className, byte[] classBytes, String outputPath){
StringBuffer directoryName = new StringBuffer();;
StringTokenizer tokenizer = new StringTokenizer(className, "\n\\/");
String token = null;
while (tokenizer.hasMoreTokens()){
token = tokenizer.nextToken();
if (tokenizer.hasMoreTokens()){
directoryName.append(token + File.separator);
}
}
try{
String usedOutputPath = outputPath;
if (!outputPath.endsWith(File.separator)){
usedOutputPath = outputPath + File.separator;
}
File file = new File(usedOutputPath + directoryName);
file.mkdirs();
file = new File(file, token + ".class");
if (!file.exists()){
file.createNewFile();
} else {
if (!System.getProperty(WEAVING_SHOULD_OVERWRITE, "false").equalsIgnoreCase("true")){
((oracle.toplink.essentials.internal.sessions.AbstractSession)session).log(
SessionLog.WARNING, SessionLog.WEAVER, WEAVER_NOT_OVERWRITING, className);
return;
}
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(classBytes);
fos.close();
} catch (Exception e){
((oracle.toplink.essentials.internal.sessions.AbstractSession)session).log(
SessionLog.WARNING, SessionLog.WEAVER, WEAVER_COULD_NOT_WRITE, className, e);
}
}
// same as in oracle.toplink.essentials.internal.helper.Helper, but uses
// '/' slash as delimiter, not '.'
protected static String getShortName(String name) {
int pos = name.lastIndexOf('/');
if (pos >= 0) {
name = name.substring(pos+1);
if (name.endsWith(";")) {
name = name.substring(0, name.length()-1);
}
return name;
}
return "";
}
}