org.eclipse.persistence.tools.weaving.jpa.StaticWeaveClassTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction 180e602
/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
* 04/01/2011-2.3 Guy Pelletier
* - 337323: Multi-tenant with shared schema support (part 2)
******************************************************************************/
package org.eclipse.persistence.tools.weaving.jpa;
import java.io.IOException;
import java.io.Writer;
import java.lang.instrument.IllegalClassFormatException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipException;
import javax.persistence.spi.ClassTransformer;
import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
import org.eclipse.persistence.internal.jpa.StaticWeaveInfo;
import org.eclipse.persistence.internal.jpa.deployment.ArchiveFactoryImpl;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.exceptions.StaticWeaveException;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.jpa.Archive;
/**
*
* Description: This class provides the implementation of class transformer by leveraging on the following existing APIs,
*
* - PersistenceUnitProcessor.processORMetadata() - get class descriptor.
*
- PersistenceUnitProcessor.buildEntityList() - get entity classes lsit.
*
- TransformerFactory.createTransformerAndModifyProject - get class transformer.
*
*
* Responsibilities:
*
* - Create the classtransformer for each persistence unit individually and store them into the list.
*
- Provide class transfom method to perform weaving function.
*
*/
public class StaticWeaveClassTransformer {
private ArrayList classTransformers;
StaticWeaveInfo info;
private ClassLoader aClassLoader;
/**
* Constructs an instance of StaticWeaveClassTransformer.
*/
public StaticWeaveClassTransformer(URL inputArchiveURL,ClassLoader aclassloader) throws Exception {
this(inputArchiveURL,null, aclassloader,null,SessionLog.OFF);
}
/**
* Constructs an instance of StaticWeaveClassTransformer.
*/
public StaticWeaveClassTransformer(URL inputArchiveURL, String persistenceXMLLocation, ClassLoader aclassloader, Writer logWriter, int loglevel) throws URISyntaxException,IOException {
this.aClassLoader = aclassloader;
this.info = new StaticWeaveInfo(logWriter, loglevel);
buildClassTransformers(inputArchiveURL, persistenceXMLLocation, aclassloader);
}
/**
* The method performs weaving function on the given class.
* @return the converted(woven) class
*/
public byte[] transform(String originalClassName, Class originalClass, byte[] originalClassBytes)throws IllegalClassFormatException{
byte[] newClassBytes = null;
for(ClassTransformer transformer : classTransformers){
newClassBytes=transformer.transform(aClassLoader, originalClassName, originalClass, null, originalClassBytes);
if(newClassBytes!=null) {
break;
};
}
return newClassBytes;
}
/**
* The method creates classtransformer list corresponding to each persistence unit.
*/
private void buildClassTransformers(URL inputArchiveURL, String persistenceXMLLocation, ClassLoader aclassloader) throws URISyntaxException,IOException{
if (classTransformers!=null) {
return ;
} else {
classTransformers = new ArrayList();
}
Archive archive = null;
try {
archive = (new ArchiveFactoryImpl()).createArchive(inputArchiveURL, persistenceXMLLocation == null ? PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML_DEFAULT : persistenceXMLLocation, null);
List persistenceUnitsList =
PersistenceUnitProcessor.processPersistenceArchive(archive, aclassloader);
if (persistenceUnitsList==null) {
throw PersistenceUnitLoadingException.couldNotGetUnitInfoFromUrl(inputArchiveURL);
}
Map emptyMap = new HashMap(0);
Iterator persistenceUnitsIterator = persistenceUnitsList.iterator();
while (persistenceUnitsIterator.hasNext()) {
SEPersistenceUnitInfo unitInfo = persistenceUnitsIterator.next();
//build class transformer.
String puName = unitInfo.getPersistenceUnitName();
String sessionName = (String)unitInfo.getProperties().get(PersistenceUnitProperties.SESSION_NAME);
if (sessionName == null) {
sessionName = puName;
}
EntityManagerSetupImpl emSetupImpl = new EntityManagerSetupImpl(puName, sessionName);
//indicates that predeploy is used for static weaving, also passes logging parameters
emSetupImpl.setStaticWeaveInfo(this.info);
ClassTransformer transformer = emSetupImpl.predeploy(unitInfo, emptyMap);
if (transformer != null) {
classTransformers.add(transformer);
}
}
} catch (ZipException e) {
throw StaticWeaveException.exceptionOpeningArchive(inputArchiveURL,e);
} finally {
if (archive != null) {
archive.close();
}
}
}
}