Hibernate SVN: r16071 - validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report.
by hibernate-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-03-04 05:40:54 -0500 (Wed, 04 Mar 2009)
New Revision: 16071
Modified:
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
Log:
added colour key, configurable unimplemented test groups
Modified: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
===================================================================
--- validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 07:56:48 UTC (rev 16070)
+++ validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 10:40:54 UTC (rev 16071)
@@ -8,8 +8,10 @@
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -34,6 +36,11 @@
private static final Pattern PATTERN_BOLD = Pattern.compile("([_][^_]*[_])");
private static final Pattern PATTERN_STRIKETHROUGH = Pattern.compile("([~][^~]*[~])");
private static final String REPORT_FILE_NAME = "coverage.html";
+
+ private static final String COLOUR_SHADE_GREEN = "#ddffdd";
+ private static final String COLOUR_SHADE_RED = "#ffdddd";
+ private static final String COLOUR_SHADE_BLUE = "#80d1ff";
+ private static final String COLOUR_SHADE_ORANGE = "#ffcc33";
/*
* References to the spec assertions made by the tck tests
@@ -55,6 +62,7 @@
private int failThreshold;
private int passThreshold;
+ private Set<String> unimplementedTestGroups;
public CoverageReport(List<SpecReference> references, AuditParser auditParser, File imageSrcDir) {
this.references = new HashMap<String, List<SpecReference>>();
@@ -89,6 +97,20 @@
passThreshold = this.properties.getIntValue("pass_threshold", 75, false);
failThreshold = this.properties.getIntValue("fail_threshold", 50, false);
+
+ String unimplemented = this.properties.getStringValue("unimplemented_test_groups", null, false);
+ if (unimplemented != null)
+ {
+ String[] parts = unimplemented.split(",");
+ unimplementedTestGroups = new HashSet<String>();
+ for (String part : parts)
+ {
+ if (!"".equals(part.trim()))
+ {
+ unimplementedTestGroups.add(part.trim());
+ }
+ }
+ }
}
catch (Exception ex)
{
@@ -109,7 +131,6 @@
calculateUnmatched();
writeHeader(out);
writeContents(out);
- //writeMasterSummary(out);
writeChapterSummary(out);
writeSectionSummary(out);
writeCoverage(out);
@@ -200,25 +221,25 @@
sb.append(" border-bottom: 1px solid #488c41;\n");
sb.append(" padding-bottom: 1px;\n");
sb.append(" margin-bottom: 2px;\n");
- sb.append(" background-color: #dfd; }\n");
+ sb.append(" background-color: " + COLOUR_SHADE_GREEN + "; }\n");
sb.append(" .fail {\n");
sb.append(" border-top: 1px solid #ab2020;\n");
sb.append(" border-bottom: 1px solid #ab2020;\n");
sb.append(" padding-bottom: 1px;\n");
sb.append(" margin-bottom: 2px;\n");
- sb.append(" background-color: #fdd; }\n");
+ sb.append(" background-color: " + COLOUR_SHADE_RED + "; }\n");
sb.append(" .skip {\n");
sb.append(" border-top: 1px solid #ff9900;\n");
sb.append(" border-bottom: 1px solid #ff9900;\n");
sb.append(" padding-bottom: 1px;\n");
sb.append(" margin-bottom: 2px;\n");
- sb.append(" background-color: #ffcc33; }\n");
+ sb.append(" background-color: " + COLOUR_SHADE_ORANGE + "; }\n");
sb.append(" .untestable {\n");
sb.append(" padding-bottom: 16px;\n");
sb.append(" margin-bottom: 2px;\n");
sb.append(" border-top: 1px solid #317ba6;\n");
sb.append(" border-bottom: 1px solid #317ba6;\n");
- sb.append(" background-color: #80d1ff; }\n");
+ sb.append(" background-color: " + COLOUR_SHADE_BLUE + "; }\n");
sb.append("</style>\n");
@@ -254,7 +275,7 @@
sb.append("<th align=\"left\">Chapter</th>");
sb.append("<th>Assertions</th>");
sb.append("<th>Testable</th>");
- sb.append("<th>Tested<br /> (implemented and unimplemented)</th>");
+ sb.append("<th>Total Tested</th>");
sb.append("<th>Tested<br /> (unimplemented)</th>");
sb.append("<th>Tested<br /> (implemented)</th>");
sb.append("<th>Coverage %</th>");
@@ -457,7 +478,7 @@
sb.append("<th align=\"left\">Section</th>");
sb.append("<th>Assertions</th>");
sb.append("<th>Testable</th>");
- sb.append("<th>Tested<br /> (implemented and unimplemented)</th>");
+ sb.append("<th>Total Tested</th>");
sb.append("<th>Tested<br /> (unimplemented)</th>");
sb.append("<th>Tested<br /> (implemented)</th>");
sb.append("<th>Coverage %</th>");
@@ -552,11 +573,21 @@
sb.append("</table>");
out.write(sb.toString().getBytes());
}
-
+
private void writeCoverage(OutputStream out) throws IOException {
out.write("<h3 id=\"coverageDetail\">Coverage Detail</h3>\n".getBytes());
-
+
+ StringBuilder key = new StringBuilder();
+ key.append("<table>");
+ key.append("<tr><th style=\"background-color:#dddddd\">Colour Key</th></tr>");
+ key.append("<tr><td style=\"background-color:" + COLOUR_SHADE_GREEN + ";text-align:center\">Assertion is covered</td></tr>");
+ key.append("<tr><td style=\"background-color:" + COLOUR_SHADE_RED + ";text-align:center\">Assertion is not covered</td></tr>");
+ key.append("<tr><td style=\"background-color:" + COLOUR_SHADE_ORANGE + ";text-align:center\">Assertion test is unimplemented</td></tr>");
+ key.append("<tr><td style=\"background-color:" + COLOUR_SHADE_BLUE + ";text-align:center\">Assertion is untestable</td></tr>");
+ key.append("</table>");
+ out.write(key.toString().getBytes());
+
for (String sectionId : auditParser.getSectionIds()) {
List<AuditAssertion> sectionAssertions = auditParser.getAssertionsForSection(sectionId);
@@ -807,7 +838,12 @@
private boolean isImplemented(List<String> groups)
{
- return !groups.contains("stub") && !groups.contains("broken");
+ for (String group : groups)
+ {
+ if (unimplementedTestGroups.contains(group)) return false;
+ }
+
+ return true;
}
private void writeFooter(OutputStream out) throws IOException {
15 years, 10 months
Hibernate SVN: r16070 - validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report.
by hibernate-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-03-04 02:56:48 -0500 (Wed, 04 Mar 2009)
New Revision: 16070
Modified:
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
Log:
minor
Modified: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
===================================================================
--- validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 07:43:57 UTC (rev 16069)
+++ validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 07:56:48 UTC (rev 16070)
@@ -397,7 +397,7 @@
}
else
{
- sb.append("<tr style=\"font-weight: bold\">");
+ sb.append("<tr style=\"font-weight: bold;background-color:#dddddd\">");
}
sb.append("<td>");
15 years, 10 months
Hibernate SVN: r16069 - validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report.
by hibernate-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-03-04 02:43:57 -0500 (Wed, 04 Mar 2009)
New Revision: 16069
Modified:
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageProcessor.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
Log:
support for inline images
Modified: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageProcessor.java
===================================================================
--- validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageProcessor.java 2009-03-04 02:20:50 UTC (rev 16068)
+++ validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageProcessor.java 2009-03-04 07:43:57 UTC (rev 16069)
@@ -40,7 +40,6 @@
public class CoverageProcessor extends AbstractProcessor {
private static final String OUTDIR_OPTION_FLAG = "outputDir";
private static final String AUDITFILE_OPTION_KEY = "auditXml";
- private static final String REPORT_FILE_NAME = "coverage.html";
private static final String DEFAULT_AUDIT_FILE_NAME = "tck-audit.xml";
@@ -75,31 +74,40 @@
private InputStream getAuditFileInputStream() {
InputStream in;
- String auditFileName = processingEnv.getOptions().get(AUDITFILE_OPTION_KEY);
-
- if (auditFileName == null || auditFileName.length() == 0) {
- auditFileName = getCurrentWorkingDirectory() + DEFAULT_AUDIT_FILE_NAME;
- System.out.println(
- "No audit file specified. Trying default: " + auditFileName
- );
- }
- else
- {
- System.out.println(
- "Reading spec assertions from audit file: " + auditFileName);
- }
try {
- in = new FileInputStream(auditFileName);
+ in = new FileInputStream(getAuditFile());
}
catch (IOException ex) {
- System.err.println("Unable to open audit file - " + auditFileName);
+ System.err.println("Unable to open audit file - " + getAuditFile().getAbsolutePath());
System.err.println("No report generated");
- return null;
+ return null;
}
return in;
}
+
+ private File getAuditFile()
+ {
+ String auditFileName = processingEnv.getOptions().get(AUDITFILE_OPTION_KEY);
+
+ if (auditFileName == null || auditFileName.length() == 0) {
+ auditFileName = getCurrentWorkingDirectory() + DEFAULT_AUDIT_FILE_NAME;
+ System.out.println(
+ "No audit file specified. Trying default: " + auditFileName
+ );
+ }
+ else
+ {
+ System.out.println(
+ "Reading spec assertions from audit file: " + auditFileName);
+ }
+
+ return new File(auditFileName);
+ }
+
+ private File getImagesDir() {
+ return new File(getAuditFile().getParentFile(), "/images");
+ }
-
private void createOutputDir() {
String baseDirName = processingEnv.getOptions().get(OUTDIR_OPTION_FLAG);
@@ -136,7 +144,14 @@
}
if (roundEnvironment.processingOver()) {
- new CoverageReport(references, auditParser).writeToFile(new File(baseDir, REPORT_FILE_NAME));
+ try
+ {
+ new CoverageReport(references, auditParser, getImagesDir()).generate(baseDir);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
}
return false;
}
Modified: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
===================================================================
--- validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 02:20:50 UTC (rev 16068)
+++ validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 07:43:57 UTC (rev 16069)
@@ -1,9 +1,11 @@
package org.hibernate.tck.report;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -31,6 +33,7 @@
private static final Pattern PATTERN_BOLD = Pattern.compile("([_][^_]*[_])");
private static final Pattern PATTERN_STRIKETHROUGH = Pattern.compile("([~][^~]*[~])");
+ private static final String REPORT_FILE_NAME = "coverage.html";
/*
* References to the spec assertions made by the tck tests
@@ -38,6 +41,9 @@
private final Map<String, List<SpecReference>> references;
private AuditParser auditParser;
+
+ private File imageSrcDir;
+ private File imageTargetDir;
private RuntimeProperties properties;
@@ -50,7 +56,7 @@
private int failThreshold;
private int passThreshold;
- public CoverageReport(List<SpecReference> references, AuditParser auditParser) {
+ public CoverageReport(List<SpecReference> references, AuditParser auditParser, File imageSrcDir) {
this.references = new HashMap<String, List<SpecReference>>();
for (SpecReference ref : references) {
@@ -62,7 +68,7 @@
}
this.auditParser = auditParser;
-
+ this.imageSrcDir = imageSrcDir;
this.properties = new RuntimeProperties();
try
@@ -90,7 +96,16 @@
}
}
- public void generate(OutputStream out) throws IOException {
+ public void generate(File outputDir) throws IOException {
+ File coverageFile = new File(outputDir, REPORT_FILE_NAME);
+ FileOutputStream out = new FileOutputStream(coverageFile);
+
+ imageTargetDir = new File(outputDir, "/images");
+ if (!imageTargetDir.exists())
+ {
+ imageTargetDir.mkdirs();
+ }
+
calculateUnmatched();
writeHeader(out);
writeContents(out);
@@ -155,6 +170,12 @@
sb.append(" color: #999999;\n");
sb.append(" font-size: 9px;\n");
sb.append(" font-weight: bold; }\n");
+ sb.append(" .embeddedImage {\n");
+ sb.append(" margin: 6px;\n");
+ sb.append(" border: 1px solid black;\n");
+ sb.append(" float: right; }\n");
+ sb.append(" .coverage {\n");
+ sb.append(" clear: both; }\n");
sb.append(" .noCoverage {\n");
sb.append(" margin-top: 2px;\n");
sb.append(" margin-bottom: 2px;\n");
@@ -351,7 +372,9 @@
if (coveragePercent >= 0)
{
- String bgColor = coveragePercent < 60 ? "#ffaaaa" : coveragePercent < 80 ? "#ffffaa" : coveragePercent > 100 ? "#FF00CC" : "#aaffaa" ;
+ String bgColor = coveragePercent < failThreshold ? "#ffaaaa" :
+ coveragePercent < passThreshold ? "#ffffaa" :
+ coveragePercent > 100 ? "#FF00CC" : "#aaffaa" ;
sb.append("<td align=\"center\" style=\"background-color:" + bgColor + "\">");
sb.append(String.format("%.2f%%", coveragePercent));
@@ -405,7 +428,8 @@
if (totalCoveragePercent >= 0)
{
- String bgColor = totalCoveragePercent < 60 ? "#ffaaaa" : totalCoveragePercent < 80 ? "#ffffaa" : "#aaffaa" ;
+ String bgColor = totalCoveragePercent < failThreshold ? "#ffaaaa" :
+ totalCoveragePercent < passThreshold ? "#ffffaa" : "#aaffaa" ;
sb.append("<td align=\"center\" style=\"background-color:" + bgColor + "\">");
sb.append(String.format("%.2f%%", totalCoveragePercent));
@@ -510,7 +534,8 @@
if (coveragePercent >= 0)
{
- String bgColor = coveragePercent < 60 ? "#ffaaaa" : coveragePercent < 80 ? "#ffffaa" : coveragePercent > 100 ? "#FF00CC" : "#aaffaa" ;
+ String bgColor = coveragePercent < failThreshold ? "#ffaaaa" :
+ coveragePercent < passThreshold ? "#ffffaa" : coveragePercent > 100 ? "#FF00CC" : "#aaffaa" ;
sb.append("<td align=\"center\" style=\"background-color:" + bgColor + "\">");
sb.append(String.format("%.2f%%", coveragePercent));
@@ -582,12 +607,25 @@
sb.append("</span>\n");
sb.append(" <div class=\"results\">");
+
+
sb.append("<p class=\"description\">");
+ String imageFilename = sectionId + "." + assertion.getId() + ".png";
+ File imageFile = new File(imageSrcDir, imageFilename);
- String assertionText = parseStrikethrough(parseBold(assertion.getText()));
+ if (imageFile.exists())
+ {
+ sb.append("<img src=\"images/" + imageFile.getName() + "\" class=\"embeddedImage\"/>");
+ copyFile(imageFile, new File(imageTargetDir, imageFilename));
+ }
+
+ String assertionText = parseStrikethrough(parseBold(assertion.getText()));
+
if (!Strings.isEmpty(assertion.getNote()))
{
- sb.append("<a title=\"" + assertion.getNote() + "\">").append(assertionText).append("</a>");
+ sb.append("<a title=\"" + assertion.getNote() + "\">");
+ sb.append(assertionText);
+ sb.append("</a>");
}
else
{
@@ -776,16 +814,21 @@
out.write("</table>".getBytes());
out.write("</body></html>".getBytes());
}
-
- public void writeToFile(File file) {
- try {
- FileOutputStream out = new FileOutputStream(file);
- generate(out);
- out.flush();
- out.close();
- }
- catch (IOException ex) {
- throw new RuntimeException("Error generating report file", ex);
- }
+
+ private void copyFile(File sourceFile, File targetFile) throws IOException
+ {
+ FileChannel inChannel = new FileInputStream(sourceFile).getChannel();
+ FileChannel outChannel = new FileOutputStream(targetFile).getChannel();
+ try {
+ inChannel.transferTo(0, inChannel.size(),
+ outChannel);
+ }
+ catch (IOException e) {
+ throw e;
}
+ finally {
+ if (inChannel != null) inChannel.close();
+ if (outChannel != null) outChannel.close();
+ }
+}
}
15 years, 10 months
Hibernate SVN: r16068 - in core/branches/Branch_3_3: core/src/main/java/org/hibernate/bytecode and 11 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-03-03 21:20:50 -0500 (Tue, 03 Mar 2009)
New Revision: 16068
Added:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java
core/branches/Branch_3_3/hibernate-maven-plugin/
core/branches/Branch_3_3/hibernate-maven-plugin/pom.xml
core/branches/Branch_3_3/hibernate-maven-plugin/src/
core/branches/Branch_3_3/hibernate-maven-plugin/src/main/
core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/
core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/
core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/hibernate/
core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/hibernate/maven/
core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
core/branches/Branch_3_3/pom.xml
Log:
HHH-3279 : maven plugin (initial work)
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,443 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+import java.util.zip.CRC32;
+import java.io.File;
+import java.io.DataInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+
+import org.hibernate.bytecode.util.ByteCodeHelper;
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.FieldFilter;
+import org.hibernate.bytecode.ClassTransformer;
+
+/**
+ * Provides the basic templating of how instrumentation should occur.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractInstrumenter implements Instrumenter {
+ private static final int ZIP_MAGIC = 0x504B0304;
+ private static final int CLASS_MAGIC = 0xCAFEBABE;
+
+ protected final Logger logger;
+ protected final Options options;
+
+ /**
+ * Creates the basic instrumentation strategy.
+ *
+ * @param logger The bridge to the environment's logging system.
+ * @param options User-supplied options.
+ */
+ public AbstractInstrumenter(Logger logger, Options options) {
+ this.logger = logger;
+ this.options = options;
+ }
+
+ /**
+ * Given the bytecode of a java class, retrieve the descriptor for that class.
+ *
+ * @param byecode The class bytecode.
+ *
+ * @return The class's descriptor
+ *
+ * @throws Exception Indicates problems access the bytecode.
+ */
+ protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception;
+
+ /**
+ * Create class transformer for the class.
+ *
+ * @param descriptor The descriptor of the class to be instrumented.
+ * @param classNames The names of all classes to be instrumented; the "pipeline" if you will.
+ *
+ * @return The transformer for the given class; may return null to indicate that transformation should
+ * be skipped (ala already instrumented).
+ */
+ protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames);
+
+ /**
+ * The main instrumentation entry point. Given a set of files, perform instrumentation on each discovered class
+ * file.
+ *
+ * @param files The files.
+ */
+ public void execute(Set files) {
+ Set classNames = new HashSet();
+
+ if ( options.performExtendedInstrumentation() ) {
+ logger.debug( "collecting class names for extended instrumentation determination" );
+ try {
+ Iterator itr = files.iterator();
+ while ( itr.hasNext() ) {
+ final File file = ( File ) itr.next();
+ collectClassNames( file, classNames );
+ }
+ }
+ catch ( ExecutionException ee ) {
+ throw ee;
+ }
+ catch ( Exception e ) {
+ throw new ExecutionException( e );
+ }
+ }
+
+ logger.info( "starting instrumentation" );
+ try {
+ Iterator itr = files.iterator();
+ while ( itr.hasNext() ) {
+ final File file = ( File ) itr.next();
+ processFile( file, classNames );
+ }
+ }
+ catch ( ExecutionException ee ) {
+ throw ee;
+ }
+ catch ( Exception e ) {
+ throw new ExecutionException( e );
+ }
+ }
+
+ /**
+ * Extract the names of classes from file, addding them to the classNames collection.
+ * <p/>
+ * IMPL NOTE : file here may be either a class file or a jar. If a jar, all entries in the jar file are
+ * processed.
+ *
+ * @param file The file from which to extract class metadata (descriptor).
+ * @param classNames The collected class name collection.
+ *
+ * @throws Exception indicates problems accessing the file or its contents.
+ */
+ private void collectClassNames(File file, final Set classNames) throws Exception {
+ if ( isClassFile( file ) ) {
+ byte[] bytes = ByteCodeHelper.readByteCode( file );
+ ClassDescriptor descriptor = getClassDescriptor( bytes );
+ classNames.add( descriptor.getName() );
+ }
+ else if ( isJarFile( file ) ) {
+ ZipEntryHandler collector = new ZipEntryHandler() {
+ public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
+ if ( !entry.isDirectory() ) {
+ // see if the entry represents a class file
+ DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
+ if ( din.readInt() == CLASS_MAGIC ) {
+ classNames.add( getClassDescriptor( byteCode ).getName() );
+ }
+ }
+ }
+ };
+ ZipFileProcessor processor = new ZipFileProcessor( collector );
+ processor.process( file );
+ }
+ }
+
+ /**
+ * Does this file represent a compiled class?
+ *
+ * @param file The file to check.
+ *
+ * @return True if the file is a class; false otherwise.
+ *
+ * @throws IOException Indicates problem access the file.
+ */
+ protected final boolean isClassFile(File file) throws IOException {
+ return checkMagic( file, CLASS_MAGIC );
+ }
+
+ /**
+ * Does this file represent a zip file of some format?
+ *
+ * @param file The file to check.
+ *
+ * @return True if the file is n archive; false otherwise.
+ *
+ * @throws IOException Indicates problem access the file.
+ */
+ protected final boolean isJarFile(File file) throws IOException {
+ return checkMagic(file, ZIP_MAGIC);
+ }
+
+ protected final boolean checkMagic(File file, long magic) throws IOException {
+ DataInputStream in = new DataInputStream( new FileInputStream( file ) );
+ try {
+ int m = in.readInt();
+ return magic == m;
+ }
+ finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Actually process the file by applying instrumentation transformations to any classes it contains.
+ * <p/>
+ * Again, just like with {@link #collectClassNames} this method can handle both class and archive files.
+ *
+ * @param file The file to process.
+ * @param classNames The 'pipeline' of classes to be processed. Only actually populated when the user
+ * specifies to perform {@link Options#performExtendedInstrumentation() extended} instrumentation.
+ *
+ * @throws Exception Indicates an issue either access files or applying the transformations.
+ */
+ protected void processFile(File file, Set classNames) throws Exception {
+ if ( isClassFile( file ) ) {
+ logger.debug( "processing class file : " + file.getAbsolutePath() );
+ processClassFile( file, classNames );
+ }
+ else if ( isJarFile( file ) ) {
+ logger.debug( "processing jar file : " + file.getAbsolutePath() );
+ processJarFile( file, classNames );
+ }
+ else {
+ logger.debug( "ignoring file : " + file.getAbsolutePath() );
+ }
+ }
+
+ /**
+ * Process a class file. Delegated to from {@link #processFile} in the case of a class file.
+ *
+ * @param file The class file to process.
+ * @param classNames The 'pipeline' of classes to be processed. Only actually populated when the user
+ * specifies to perform {@link Options#performExtendedInstrumentation() extended} instrumentation.
+ *
+ * @throws Exception Indicates an issue either access files or applying the transformations.
+ */
+ protected void processClassFile(File file, Set classNames) throws Exception {
+ byte[] bytes = ByteCodeHelper.readByteCode( file );
+ ClassDescriptor descriptor = getClassDescriptor( bytes );
+ ClassTransformer transformer = getClassTransformer( descriptor, classNames );
+ if ( transformer == null ) {
+ logger.debug( "no trasformer for class file : " + file.getAbsolutePath() );
+ return;
+ }
+
+ logger.info( "processing class : " + descriptor.getName() + "; file = " + file.getAbsolutePath() );
+ byte[] transformedBytes = transformer.transform(
+ getClass().getClassLoader(),
+ descriptor.getName(),
+ null,
+ null,
+ descriptor.getBytes()
+ );
+
+ OutputStream out = new FileOutputStream( file );
+ try {
+ out.write( transformedBytes );
+ out.flush();
+ }
+ finally {
+ try {
+ out.close();
+ }
+ catch ( IOException ignore) {
+ // intentionally empty
+ }
+ }
+ }
+
+ /**
+ * Process an archive file. Delegated to from {@link #processFile} in the case of an archive file.
+ *
+ * @param file The archive file to process.
+ * @param classNames The 'pipeline' of classes to be processed. Only actually populated when the user
+ * specifies to perform {@link Options#performExtendedInstrumentation() extended} instrumentation.
+ *
+ * @throws Exception Indicates an issue either access files or applying the transformations.
+ */
+ protected void processJarFile(final File file, final Set classNames) throws Exception {
+ File tempFile = File.createTempFile(
+ file.getName(),
+ null,
+ new File( file.getAbsoluteFile().getParent() )
+ );
+
+ try {
+ FileOutputStream fout = new FileOutputStream( tempFile, false );
+ try {
+ final ZipOutputStream out = new ZipOutputStream( fout );
+ ZipEntryHandler transformer = new ZipEntryHandler() {
+ public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
+ logger.debug( "starting zip entry : " + entry.toString() );
+ if ( !entry.isDirectory() ) {
+ // see if the entry represents a class file
+ DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
+ if ( din.readInt() == CLASS_MAGIC ) {
+ ClassDescriptor descriptor = getClassDescriptor( byteCode );
+ ClassTransformer transformer = getClassTransformer( descriptor, classNames );
+ if ( transformer == null ) {
+ logger.debug( "no transformer for zip entry : " + entry.toString() );
+ }
+ else {
+ logger.info( "processing class : " + descriptor.getName() + "; entry = " + file.getAbsolutePath() );
+ byteCode = transformer.transform(
+ getClass().getClassLoader(),
+ descriptor.getName(),
+ null,
+ null,
+ descriptor.getBytes()
+ );
+ }
+ }
+ else {
+ logger.debug( "ignoring zip entry : " + entry.toString() );
+ }
+ }
+
+ ZipEntry outEntry = new ZipEntry( entry.getName() );
+ outEntry.setMethod( entry.getMethod() );
+ outEntry.setComment( entry.getComment() );
+ outEntry.setSize( byteCode.length );
+
+ if ( outEntry.getMethod() == ZipEntry.STORED ){
+ CRC32 crc = new CRC32();
+ crc.update( byteCode );
+ outEntry.setCrc( crc.getValue() );
+ outEntry.setCompressedSize( byteCode.length );
+ }
+ out.putNextEntry( outEntry );
+ out.write( byteCode );
+ out.closeEntry();
+ }
+ };
+ ZipFileProcessor processor = new ZipFileProcessor( transformer );
+ processor.process( file );
+ out.close();
+ }
+ finally{
+ fout.close();
+ }
+
+ if ( file.delete() ) {
+ File newFile = new File( tempFile.getAbsolutePath() );
+ if( !newFile.renameTo( file ) ) {
+ throw new IOException( "can not rename " + tempFile + " to " + file );
+ }
+ }
+ else {
+ throw new IOException( "can not delete " + file );
+ }
+ }
+ finally {
+ if ( ! tempFile.delete() ) {
+ logger.info( "Unable to cleanup temporary jar file : " + tempFile.getAbsolutePath() );
+ }
+ }
+ }
+
+ /**
+ * Allows control over what exacctly to transform.
+ */
+ protected class CustomFieldFilter implements FieldFilter {
+ private final ClassDescriptor descriptor;
+ private final Set classNames;
+
+ public CustomFieldFilter(ClassDescriptor descriptor, Set classNames) {
+ this.descriptor = descriptor;
+ this.classNames = classNames;
+ }
+
+ public boolean shouldInstrumentField(String className, String fieldName) {
+ if ( descriptor.getName().equals( className ) ) {
+ logger.trace( "accepting transformation of field [" + className + "." + fieldName + "]" );
+ return true;
+ }
+ else {
+ logger.trace( "rejecting transformation of field [" + className + "." + fieldName + "]" );
+ return false;
+ }
+ }
+
+ public boolean shouldTransformFieldAccess(
+ String transformingClassName,
+ String fieldOwnerClassName,
+ String fieldName) {
+ if ( descriptor.getName().equals( fieldOwnerClassName ) ) {
+ logger.trace( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
+ return true;
+ }
+ else if ( options.performExtendedInstrumentation() && classNames.contains( fieldOwnerClassName ) ) {
+ logger.trace( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
+ return true;
+ }
+ else {
+ logger.trace( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName );
+ return false;
+ }
+ }
+ }
+
+ /**
+ * General strategy contract for handling entries in an archive file.
+ */
+ private static interface ZipEntryHandler {
+ /**
+ * Apply strategy to the given archive entry.
+ *
+ * @param entry The archive file entry.
+ * @param byteCode
+ *
+ * @throws Exception
+ */
+ public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception;
+ }
+
+ /**
+ * Applies {@link ZipEntryHandler} strategies to the entries of an archive file.
+ */
+ private static class ZipFileProcessor {
+ private final ZipEntryHandler entryHandler;
+
+ public ZipFileProcessor(ZipEntryHandler entryHandler) {
+ this.entryHandler = entryHandler;
+ }
+
+ public void process(File file) throws Exception {
+ ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) );
+
+ try {
+ ZipEntry entry;
+ while ( (entry = zip.getNextEntry()) != null ) {
+ byte bytes[] = ByteCodeHelper.readByteCode( zip );
+ entryHandler.handleEntry( entry, bytes );
+ zip.closeEntry();
+ }
+ }
+ finally {
+ zip.close();
+ }
+ }
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,100 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Set;
+import java.io.ByteArrayInputStream;
+
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.BasicClassFilter;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
+import org.hibernate.repackage.cglib.asm.ClassReader;
+import org.hibernate.repackage.cglib.core.ClassNameReader;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
+
+/**
+ * Strategy for performing build-time instrumentation of persistent classes in order to enable
+ * field-level interception using CGLIB.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public class CGLIBInstrumenter extends AbstractInstrumenter {
+ private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
+
+ private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
+
+ public CGLIBInstrumenter(Logger logger, Options options) {
+ super( logger, options );
+ }
+
+ protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
+ return new CustomClassDescriptor( byecode );
+ }
+
+ protected ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames) {
+ if ( descriptor.isInstrumented() ) {
+ logger.debug( "class [" + descriptor.getName() + "] already instrumented" );
+ return null;
+ }
+ else {
+ return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor, classNames ) );
+ }
+ }
+
+ private static class CustomClassDescriptor implements ClassDescriptor {
+ private final byte[] bytecode;
+ private final String name;
+ private final boolean isInstrumented;
+
+ public CustomClassDescriptor(byte[] bytecode) throws Exception {
+ this.bytecode = bytecode;
+ ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
+ String[] names = ClassNameReader.getClassInfo( reader );
+ this.name = names[0];
+ boolean instrumented = false;
+ for ( int i = 1; i < names.length; i++ ) {
+ if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
+ instrumented = true;
+ break;
+ }
+ }
+ this.isInstrumented = instrumented;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isInstrumented() {
+ return isInstrumented;
+ }
+
+ public byte[] getBytes() {
+ return bytecode;
+ }
+ }
+
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+/**
+ * Indicates problem performing the instrumentation execution.
+ *
+ * @author Steve Ebersole
+ */
+public class ExecutionException extends RuntimeException {
+ public ExecutionException(String message) {
+ super( message );
+ }
+
+ public ExecutionException(Throwable cause) {
+ super( cause );
+ }
+
+ public ExecutionException(String message, Throwable cause) {
+ super( message, cause );
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Set;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface Instrumenter {
+ public void execute(Set files);
+
+ public static interface Options {
+ public boolean performExtendedInstrumentation();
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,98 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Set;
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.ByteArrayInputStream;
+
+import javassist.bytecode.ClassFile;
+
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.BasicClassFilter;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
+import org.hibernate.bytecode.javassist.FieldHandled;
+
+/**
+ * Strategy for performing build-time instrumentation of persistent classes in order to enable
+ * field-level interception using Javassist.
+ *
+ * @author Steve Ebersole
+ * @author Muga Nishizawa
+ */
+public class JavassistInstrumenter extends AbstractInstrumenter {
+
+ private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
+
+ private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
+
+ public JavassistInstrumenter(Logger logger, Options options) {
+ super( logger, options );
+ }
+
+ protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException {
+ return new CustomClassDescriptor( bytecode );
+ }
+
+ protected ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames) {
+ if ( descriptor.isInstrumented() ) {
+ logger.debug( "class [" + descriptor.getName() + "] already instrumented" );
+ return null;
+ }
+ else {
+ return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor, classNames ) );
+ }
+ }
+
+ private static class CustomClassDescriptor implements ClassDescriptor {
+ private final byte[] bytes;
+ private final ClassFile classFile;
+
+ public CustomClassDescriptor(byte[] bytes) throws IOException {
+ this.bytes = bytes;
+ this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) );
+ }
+
+ public String getName() {
+ return classFile.getName();
+ }
+
+ public boolean isInstrumented() {
+ String[] intfs = classFile.getInterfaces();
+ for ( int i = 0; i < intfs.length; i++ ) {
+ if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public byte[] getBytes() {
+ return bytes;
+ }
+ }
+
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+/**
+ * Provides an abstraction for how instrumentation does logging because it is usually run in environments (Ant/Maven)
+ * with their own logging infrastructure. This abstraction allows proper bridging.
+ *
+ * @author Steve Ebersole
+ */
+public interface Logger {
+ public void trace(String message);
+
+ public void debug(String message);
+
+ public void info(String message);
+
+ public void warn(String message);
+
+ public void error(String message);
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java 2009-03-04 02:19:29 UTC (rev 16067)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.tool.instrument;
@@ -29,43 +28,31 @@
import org.apache.tools.ant.Project;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.util.ByteCodeHelper;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
+
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.CRC32;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.DataInputStream;
-import java.io.ByteArrayInputStream;
/**
- * Super class for all Hibernate instrumentation tasks. Provides the basic
- * templating of how instrumentation should occur.
+ * Super class for all Hibernate instrumentation tasks. Provides the basic templating of how instrumentation
+ * should occur; subclasses simply plug in to that process appropriately for the given bytecode provider.
*
* @author Steve Ebersole
*/
-public abstract class BasicInstrumentationTask extends Task {
+public abstract class BasicInstrumentationTask extends Task implements Instrumenter.Options {
- private static final int ZIP_MAGIC = 0x504B0304;
- private static final int CLASS_MAGIC = 0xCAFEBABE;
+ private final LoggerBridge logger = new LoggerBridge();
- protected final Logger logger = new Logger();
private List filesets = new ArrayList();
- private Set classNames = new HashSet();
private boolean extended;
+
+ // deprecated option...
private boolean verbose;
public void addFileset(FileSet set) {
@@ -92,32 +79,24 @@
this.verbose = verbose;
}
+ public final boolean performExtendedInstrumentation() {
+ return isExtended();
+ }
+
+ protected abstract Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options);
+
public void execute() throws BuildException {
- if ( isExtended() ) {
- collectClassNames();
+ try {
+ buildInstrumenter( logger, this )
+ .execute( collectSpecifiedFiles() );
}
- logger.info( "starting instrumentation" );
- Project project = getProject();
- Iterator filesets = filesets();
- while ( filesets.hasNext() ) {
- FileSet fs = ( FileSet ) filesets.next();
- DirectoryScanner ds = fs.getDirectoryScanner( project );
- String[] includedFiles = ds.getIncludedFiles();
- File d = fs.getDir( project );
- for ( int i = 0; i < includedFiles.length; ++i ) {
- File file = new File( d, includedFiles[i] );
- try {
- processFile( file );
- }
- catch ( Exception e ) {
- throw new BuildException( e );
- }
- }
+ catch ( Throwable t ) {
+ throw new BuildException( t );
}
}
- private void collectClassNames() {
- logger.info( "collecting class names for extended instrumentation determination" );
+ private Set collectSpecifiedFiles() {
+ HashSet files = new HashSet();
Project project = getProject();
Iterator filesets = filesets();
while ( filesets.hasNext() ) {
@@ -126,239 +105,14 @@
String[] includedFiles = ds.getIncludedFiles();
File d = fs.getDir( project );
for ( int i = 0; i < includedFiles.length; ++i ) {
- File file = new File( d, includedFiles[i] );
- try {
- collectClassNames( file );
- }
- catch ( Exception e ) {
- throw new BuildException( e );
- }
+ files.add( new File( d, includedFiles[i] ) );
}
}
- logger.info( classNames.size() + " class(es) being checked" );
+ return files;
}
- private void collectClassNames(File file) throws Exception {
- if ( isClassFile( file ) ) {
- byte[] bytes = ByteCodeHelper.readByteCode( file );
- ClassDescriptor descriptor = getClassDescriptor( bytes );
- classNames.add( descriptor.getName() );
- }
- else if ( isJarFile( file ) ) {
- ZipEntryHandler collector = new ZipEntryHandler() {
- public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
- if ( !entry.isDirectory() ) {
- // see if the entry represents a class file
- DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
- if ( din.readInt() == CLASS_MAGIC ) {
- classNames.add( getClassDescriptor( byteCode ).getName() );
- }
- }
- }
- };
- ZipFileProcessor processor = new ZipFileProcessor( collector );
- processor.process( file );
- }
- }
-
- protected void processFile(File file) throws Exception {
- logger.verbose( "processing file : " + file.toURL() );
- if ( isClassFile( file ) ) {
- processClassFile(file);
- }
- else if ( isJarFile( file ) ) {
- processJarFile(file);
- }
- else {
- logger.verbose( "ignoring " + file.toURL() );
-
- }
- }
-
- protected final boolean isClassFile(File file) throws IOException {
- return checkMagic( file, CLASS_MAGIC );
- }
-
- protected final boolean isJarFile(File file) throws IOException {
- return checkMagic(file, ZIP_MAGIC);
- }
-
- protected final boolean checkMagic(File file, long magic) throws IOException {
- DataInputStream in = new DataInputStream( new FileInputStream( file ) );
- try {
- int m = in.readInt();
- return magic == m;
- }
- finally {
- in.close();
- }
- }
-
- protected void processClassFile(File file) throws Exception {
- logger.verbose( "Starting class file : " + file.toURL() );
- byte[] bytes = ByteCodeHelper.readByteCode( file );
- ClassDescriptor descriptor = getClassDescriptor( bytes );
- ClassTransformer transformer = getClassTransformer( descriptor );
- if ( transformer == null ) {
- logger.verbose( "skipping file : " + file.toURL() );
- return;
- }
-
- logger.info( "processing class [" + descriptor.getName() + "]; file = " + file.toURL() );
- byte[] transformedBytes = transformer.transform(
- getClass().getClassLoader(),
- descriptor.getName(),
- null,
- null,
- descriptor.getBytes()
- );
-
- OutputStream out = new FileOutputStream( file );
- try {
- out.write( transformedBytes );
- out.flush();
- }
- finally {
- try {
- out.close();
- }
- catch ( IOException ignore) {
- // intentionally empty
- }
- }
- }
-
- protected void processJarFile(final File file) throws Exception {
- logger.verbose( "starting jar file : " + file.toURL() );
-
- File tempFile = File.createTempFile(
- file.getName(),
- null,
- new File( file.getAbsoluteFile().getParent() )
- );
-
- try {
- FileOutputStream fout = new FileOutputStream( tempFile, false );
- try {
- final ZipOutputStream out = new ZipOutputStream( fout );
- ZipEntryHandler transformer = new ZipEntryHandler() {
- public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
- logger.verbose( "starting entry : " + entry.toString() );
- if ( !entry.isDirectory() ) {
- // see if the entry represents a class file
- DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
- if ( din.readInt() == CLASS_MAGIC ) {
- ClassDescriptor descriptor = getClassDescriptor( byteCode );
- ClassTransformer transformer = getClassTransformer( descriptor );
- if ( transformer == null ) {
- logger.verbose( "skipping entry : " + entry.toString() );
- }
- else {
- logger.info( "processing class [" + descriptor.getName() + "]; entry = " + file.toURL() );
- byteCode = transformer.transform(
- getClass().getClassLoader(),
- descriptor.getName(),
- null,
- null,
- descriptor.getBytes()
- );
- }
- }
- else {
- logger.verbose( "ignoring zip entry : " + entry.toString() );
- }
- }
-
- ZipEntry outEntry = new ZipEntry( entry.getName() );
- outEntry.setMethod( entry.getMethod() );
- outEntry.setComment( entry.getComment() );
- outEntry.setSize( byteCode.length );
-
- if ( outEntry.getMethod() == ZipEntry.STORED ){
- CRC32 crc = new CRC32();
- crc.update( byteCode );
- outEntry.setCrc( crc.getValue() );
- outEntry.setCompressedSize( byteCode.length );
- }
- out.putNextEntry( outEntry );
- out.write( byteCode );
- out.closeEntry();
- }
- };
- ZipFileProcessor processor = new ZipFileProcessor( transformer );
- processor.process( file );
- out.close();
- }
- finally{
- fout.close();
- }
-
- if ( file.delete() ) {
- File newFile = new File( tempFile.getAbsolutePath() );
- if( !newFile.renameTo( file ) ) {
- throw new IOException( "can not rename " + tempFile + " to " + file );
- }
- }
- else {
- throw new IOException("can not delete " + file);
- }
- }
- finally {
- tempFile.delete();
- }
- }
-
- protected boolean isBeingIntrumented(String className) {
- logger.verbose( "checking to see if class [" + className + "] is set to be instrumented" );
- return classNames.contains( className );
- }
-
- protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception;
-
- protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor);
-
- protected class CustomFieldFilter implements FieldFilter {
- private final ClassDescriptor descriptor;
-
- public CustomFieldFilter(ClassDescriptor descriptor) {
- this.descriptor = descriptor;
- }
-
- public boolean shouldInstrumentField(String className, String fieldName) {
- if ( descriptor.getName().equals( className ) ) {
- logger.verbose( "accepting transformation of field [" + className + "." + fieldName + "]" );
- return true;
- }
- else {
- logger.verbose( "rejecting transformation of field [" + className + "." + fieldName + "]" );
- return false;
- }
- }
-
- public boolean shouldTransformFieldAccess(
- String transformingClassName,
- String fieldOwnerClassName,
- String fieldName) {
- if ( descriptor.getName().equals( fieldOwnerClassName ) ) {
- logger.verbose( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
- return true;
- }
- else if ( isExtended() && isBeingIntrumented( fieldOwnerClassName ) ) {
- logger.verbose( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
- return true;
- }
- else {
- logger.verbose( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName );
- return false;
- }
- }
- }
-
- protected class Logger {
- public void verbose(String message) {
- if ( verbose ) {
- System.out.println( message );
- }
+ protected class LoggerBridge implements Logger {
+ public void trace(String message) {
log( message, Project.MSG_VERBOSE );
}
@@ -373,34 +127,10 @@
public void warn(String message) {
log( message, Project.MSG_WARN );
}
- }
-
- private static interface ZipEntryHandler {
- public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception;
- }
-
- private static class ZipFileProcessor {
- private final ZipEntryHandler entryHandler;
-
- public ZipFileProcessor(ZipEntryHandler entryHandler) {
- this.entryHandler = entryHandler;
+ public void error(String message) {
+ log( message, Project.MSG_ERR );
}
-
- public void process(File file) throws Exception {
- ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) );
-
- try {
- ZipEntry entry;
- while ( (entry = zip.getNextEntry()) != null ) {
- byte bytes[] = ByteCodeHelper.readByteCode( zip );
- entryHandler.handleEntry( entry, bytes );
- zip.closeEntry();
- }
- }
- finally {
- zip.close();
- }
- }
}
+
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java 2009-03-04 02:19:29 UTC (rev 16067)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -24,18 +24,11 @@
*/
package org.hibernate.tool.instrument.cglib;
-import org.hibernate.bytecode.util.BasicClassFilter;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
-import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.buildtime.CGLIBInstrumenter;
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.hibernate.repackage.cglib.asm.ClassReader;
-import java.io.ByteArrayInputStream;
-
-import org.hibernate.repackage.cglib.core.ClassNameReader;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
-
/**
* An Ant task for instrumenting persistent classes in order to enable
* field-level interception using CGLIB.
@@ -50,7 +43,7 @@
* required Hibernate and CGLIB libraries.
* <p/>
* And then use it like:<pre>
- * <instrument verbose="true">
+ * <instrument>
* <fileset dir="${testclasses.dir}/org/hibernate/test">
* <include name="yadda/yadda/**"/>
* ...
@@ -62,7 +55,7 @@
* <p/>
* Optionally you can chose to enable "Extended Instrumentation" if desired
* by specifying the extended attriubute on the task:<pre>
- * <instrument verbose="true" extended="true">
+ * <instrument extended="true">
* ...
* </instrument>
* </pre>
@@ -72,58 +65,7 @@
* @author Steve Ebersole
*/
public class InstrumentTask extends BasicInstrumentationTask {
-
- private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
-
- private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
-
-
- protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
- return new CustomClassDescriptor( byecode );
+ protected Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options) {
+ return new CGLIBInstrumenter( logger, options );
}
-
- protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
- if ( descriptor.isInstrumented() ) {
- logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
- return null;
- }
- else {
- return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
- }
- }
-
- private static class CustomClassDescriptor implements ClassDescriptor {
- private final byte[] bytecode;
- private final String name;
- private final boolean isInstrumented;
-
- public CustomClassDescriptor(byte[] bytecode) throws Exception {
- this.bytecode = bytecode;
- ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
- String[] names = ClassNameReader.getClassInfo( reader );
- this.name = names[0];
- boolean instrumented = false;
- for ( int i = 1; i < names.length; i++ ) {
- if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
- instrumented = true;
- break;
- }
- }
- this.isInstrumented = instrumented;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean isInstrumented() {
- return isInstrumented;
- }
-
- public byte[] getBytes() {
- return bytecode;
- }
- }
-
-
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java 2009-03-04 02:19:29 UTC (rev 16067)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -24,18 +24,10 @@
*/
package org.hibernate.tool.instrument.javassist;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.ByteArrayInputStream;
-
-import javassist.bytecode.ClassFile;
-
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.JavassistInstrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.util.BasicClassFilter;
-import org.hibernate.bytecode.ClassTransformer;
-import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
-import org.hibernate.bytecode.javassist.FieldHandled;
/**
* An Ant task for instrumenting persistent classes in order to enable
@@ -73,51 +65,7 @@
* @author Steve Ebersole
*/
public class InstrumentTask extends BasicInstrumentationTask {
-
- private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
-
- private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
-
- protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException {
- return new CustomClassDescriptor( bytecode );
+ protected Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options) {
+ return new JavassistInstrumenter( logger, options );
}
-
- protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
- if ( descriptor.isInstrumented() ) {
- logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
- return null;
- }
- else {
- return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
- }
- }
-
- private static class CustomClassDescriptor implements ClassDescriptor {
- private final byte[] bytes;
- private final ClassFile classFile;
-
- public CustomClassDescriptor(byte[] bytes) throws IOException {
- this.bytes = bytes;
- this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) );
- }
-
- public String getName() {
- return classFile.getName();
- }
-
- public boolean isInstrumented() {
- String[] intfs = classFile.getInterfaces();
- for ( int i = 0; i < intfs.length; i++ ) {
- if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
- return true;
- }
- }
- return false;
- }
-
- public byte[] getBytes() {
- return bytes;
- }
- }
-
}
Property changes on: core/branches/Branch_3_3/hibernate-maven-plugin
___________________________________________________________________
Name: svn:ignore
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
Added: core/branches/Branch_3_3/hibernate-maven-plugin/pom.xml
===================================================================
--- core/branches/Branch_3_3/hibernate-maven-plugin/pom.xml (rev 0)
+++ core/branches/Branch_3_3/hibernate-maven-plugin/pom.xml 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>hibernate-parent</artifactId>
+ <groupId>org.hibernate</groupId>
+ <version>3.3.2-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-maven-plugin</artifactId>
+ <packaging>mojo</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>${version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.9</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
Added: core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java
===================================================================
--- core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java (rev 0)
+++ core/branches/Branch_3_3/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java 2009-03-04 02:20:50 UTC (rev 16068)
@@ -0,0 +1,175 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.maven;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.io.File;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.DirectoryScanner;
+
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
+import org.hibernate.bytecode.buildtime.JavassistInstrumenter;
+import org.hibernate.bytecode.buildtime.CGLIBInstrumenter;
+
+/**
+ * @goal instrument
+ * @phase process-classes
+ * @requiresDependencyResolution
+ *
+ * @author Steve Ebersole
+ */
+public class InstrumentationMojo extends AbstractMojo implements Instrumenter.Options {
+ /**
+ * INTERNAL : The Maven Project to which we are attached
+ *
+ * @parameter expression="${project}"
+ * @required
+ */
+ private MavenProject project;
+
+ /**
+ * Specifies the directory containing the classes to be instrumented. By default we use the
+ * project's output directory, which in turn defaults to <samp>${basedir}/target/classes</samp>.
+ *
+ * @parameter expression="${project.build.outputDirectory}"
+ * @required
+ */
+ private File instrumentationDirectory;
+
+ /**
+ * @parameter
+ */
+ private boolean extended;
+
+ /**
+ * @parameter
+ */
+ private String provider;
+
+ public boolean performExtendedInstrumentation() {
+ return extended;
+ }
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ // first, lets determine whether to apply cglib or javassist based instrumentation...
+ if ( provider == null ) {
+ provider = determineProvider();
+ if ( provider == null ) {
+ throw new MojoExecutionException( "Unable to determine provider to use" );
+ }
+ }
+
+ Instrumenter instrumenter = resolveInstrumenter( provider, new LoggingBridge() );
+ try {
+ instrumenter.execute( collectFilesToProcess() );
+ }
+ catch ( Throwable t ) {
+ throw new MojoExecutionException( "Error executing instrumentation", t );
+ }
+ }
+
+ private Set collectFilesToProcess() {
+ DirectoryScanner scanner = new DirectoryScanner();
+ scanner.setBasedir( instrumentationDirectory );
+ scanner.setIncludes( new String[] { "**/*.class" } );
+ scanner.addDefaultExcludes();
+ scanner.scan();
+ String[] includedFiles = scanner.getIncludedFiles();
+ HashSet fileSet = new HashSet( includedFiles.length + (int)(.75*includedFiles.length) + 1 );
+ fileSet.addAll( Arrays.asList( includedFiles ) );
+ return fileSet;
+ }
+
+ private Instrumenter resolveInstrumenter(String provider, Logger logger) throws MojoExecutionException {
+ if ( "javassist".equals( provider ) ) {
+ return new JavassistInstrumenter( logger, this );
+ }
+ else if ( "cglib".equals( provider ) ) {
+ return new CGLIBInstrumenter( logger, this );
+ }
+ else {
+ throw new MojoExecutionException( "Unable to resolve provider [" + provider + "] to appropriate instrumenter" );
+ }
+ }
+
+ /**
+ * Determine the provider to use. Called in the cases where the user did not explicitly specify; so we look
+ * through the dependencies for the project and decide which provider should be applied.
+ * <p/>
+ * NOTE: this impl prefers javassist.
+ *
+ * @return The provider determined from project's dependencies.
+ */
+ private String determineProvider() {
+ if ( project.getCompileArtifacts() != null ) {
+ boolean foundCglib = false;
+ Iterator itr = project.getCompileArtifacts().iterator();
+ while ( itr.hasNext() ) {
+ final Artifact artifact = ( Artifact ) itr.next();
+ if ( "javassist".equals( artifact.getGroupId() ) && "javassist".equals( artifact.getArtifactId() ) ) {
+ return "javassist";
+ }
+ else if ( "org.hibernate".equals( artifact.getGroupId() )
+ && "hibernate-cglib-repack".equals( artifact.getArtifactId() ) ) {
+ foundCglib = true;
+ }
+ }
+ if ( foundCglib ) {
+ return "cglib";
+ }
+ }
+ return null;
+ }
+
+ private class LoggingBridge implements Logger {
+ public void trace(String message) {
+ getLog().debug( message );
+ }
+
+ public void debug(String message) {
+ getLog().debug( message );
+ }
+
+ public void info(String message) {
+ getLog().info( message );
+ }
+
+ public void warn(String message) {
+ getLog().warn( message );
+ }
+
+ public void error(String message) {
+ getLog().error( message );
+ }
+ }
+}
Modified: core/branches/Branch_3_3/pom.xml
===================================================================
--- core/branches/Branch_3_3/pom.xml 2009-03-04 02:19:29 UTC (rev 16067)
+++ core/branches/Branch_3_3/pom.xml 2009-03-04 02:20:50 UTC (rev 16068)
@@ -57,7 +57,8 @@
<module>testing</module>
<module>testsuite</module>
<module>tutorials</module>
-<!--
+ <module>hibernate-maven-plugin</module>
+ <!--
Need to scope bytecode providers first...
<module>bytecode-cglib</module>
<module>bytecode-javassist</module>
15 years, 10 months
Hibernate SVN: r16067 - in core/trunk: cache-ehcache and 23 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-03-03 21:19:29 -0500 (Tue, 03 Mar 2009)
New Revision: 16067
Modified:
core/trunk/
core/trunk/cache-ehcache/
core/trunk/cache-jbosscache/
core/trunk/cache-jbosscache2/
core/trunk/cache-oscache/
core/trunk/cache-swarmcache/
core/trunk/commons-annotations/
core/trunk/connection-c3p0/
core/trunk/connection-proxool/
core/trunk/core/
core/trunk/distribution/
core/trunk/documentation/
core/trunk/documentation/envers/
core/trunk/documentation/manual/
core/trunk/documentation/releasenotes/
core/trunk/entitymanager/
core/trunk/envers/
core/trunk/hibernate-maven-plugin/
core/trunk/jmx/
core/trunk/parent/
core/trunk/testing/
core/trunk/testsuite/
core/trunk/tutorials/
core/trunk/tutorials/eg/
core/trunk/tutorials/web/
Log:
added .settings for eclipse to svn:ignore lists
Property changes on: core/trunk
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/cache-ehcache
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/cache-jbosscache
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/cache-jbosscache2
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
.settings
bin
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
.settings
bin
Property changes on: core/trunk/cache-oscache
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/cache-swarmcache
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/commons-annotations
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/connection-c3p0
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/connection-proxool
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/core
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/distribution
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/documentation
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/documentation/envers
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/documentation/manual
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/documentation/releasenotes
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/entitymanager
___________________________________________________________________
Name: svn:ignore
- target
test_output
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
test_output
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/envers
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/hibernate-maven-plugin
___________________________________________________________________
Name: svn:ignore
- target
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/jmx
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/parent
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/testing
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/testsuite
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/tutorials
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/tutorials/eg
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
Property changes on: core/trunk/tutorials/web
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover
15 years, 10 months
Hibernate SVN: r16066 - validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report.
by hibernate-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-03-03 21:10:38 -0500 (Tue, 03 Mar 2009)
New Revision: 16066
Modified:
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
Log:
removed master summary, added highlighting and strikethrough
Modified: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
===================================================================
--- validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-03 23:07:49 UTC (rev 16065)
+++ validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java 2009-03-04 02:10:38 UTC (rev 16066)
@@ -8,6 +8,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.hibernate.tck.config.RuntimeProperties;
import org.hibernate.tck.config.Strings;
@@ -26,6 +28,9 @@
public static final String FISHEYE_BASE_URL_PROPERTY = "fisheye_base_url";
public static final String SVN_BASE_URL_PROPERTY = "svn_base_url";
+
+ private static final Pattern PATTERN_BOLD = Pattern.compile("([_][^_]*[_])");
+ private static final Pattern PATTERN_STRIKETHROUGH = Pattern.compile("([~][^~]*[~])");
/*
* References to the spec assertions made by the tck tests
@@ -163,6 +168,8 @@
sb.append(" margin-bottom: 2px; }\n");
sb.append(" .coverageMethod {\n");
sb.append(" font-style: italic; }\n");
+ sb.append(" .highlight {\n");
+ sb.append(" background-color: #ffff00; }\n");
sb.append(" .implied {\n");
sb.append(" color: #fff;\n");
sb.append(" font-weight: bold;\n");
@@ -207,7 +214,6 @@
StringBuilder sb = new StringBuilder();
sb.append("<h3>Contents</h3>");
- sb.append("<div><a href=\"#masterSummary\">Master Summary</a></div>");
sb.append("<div><a href=\"#chapterSummary\">Chapter Summary</a></div>");
sb.append("<div><a href=\"#sectionSummary\">Section Summary</a></div>");
sb.append("<div><a href=\"#coverageDetail\">Coverage Detail</a></div>");
@@ -216,86 +222,6 @@
out.write(sb.toString().getBytes());
}
- private void writeMasterSummary(OutputStream out) throws IOException {
- StringBuilder sb = new StringBuilder();
-
- sb.append("<h3 id=\"masterSummary\">Master Summary</h3>\n");
-
- sb.append("<table border=\"0\">");
-
- sb.append("<tr>");
- sb.append("<td>Total number of assertions</td>");
- sb.append("<td>");
-
- int assertionTotal = 0;
- int testableAssertionTotal = 0;
-
- for (List<AuditAssertion> assertions : auditParser.getAssertions().values())
- {
- assertionTotal += assertions.size();
-
- for (AuditAssertion a : assertions)
- {
- if (a.isTestable()) testableAssertionTotal++;
- }
- }
-
- double untestablePercent = assertionTotal > 0 ? (((assertionTotal - testableAssertionTotal) * 1.0) / assertionTotal) * 100 : 100;
-
- sb.append(assertionTotal);
- sb.append("</td>");
- sb.append("</tr>");
-
- sb.append("<tr>");
- sb.append("<td>Total number of untestable assertions</td>");
- sb.append("<td>");
- sb.append(assertionTotal - testableAssertionTotal).append(" (").append(String.format("%.2f%%", untestablePercent)).append(")");
- sb.append("</td>");
- sb.append("</tr>");
-
- int coverage = 0;
-
- for (String sectionId : auditParser.getSectionIds())
- {
- for (AuditAssertion assertion : auditParser.getAssertionsForSection(sectionId))
- {
- if (!getCoverageForAssertion(sectionId, assertion.getId()).isEmpty())
- {
- coverage++;
- }
- }
- }
-
- double coveragePercent = testableAssertionTotal > 0 ? ((coverage * 1.0) / testableAssertionTotal) * 100 : 100;
- String bgColor = coveragePercent < failThreshold ? "#ffaaaa" :
- coveragePercent < passThreshold ? "#ffffaa" : "#aaffaa";
-
- sb.append("<tr style=\"background-color:" + bgColor + "; border-color: " + bgColor + "\">");
-
- sb.append("<td style=\"background-color:" + bgColor + "; border-color: " + bgColor + "\">Total number of tested assertions</td>");
- sb.append("<td align=\"center\" style=\"background-color:" + bgColor + "; border-color: " + bgColor + "\">");
-
- sb.append(coverage).append(" (");
-
- sb.append(String.format("%.2f%%", coveragePercent));
- sb.append(")</td>");
-
- sb.append("</tr>");
-
- sb.append("<tr>");
- sb.append("<td>Total number of unmatched tests</td>");
-
- sb.append("<td>");
- sb.append(unmatched.size());
- sb.append("</td>");
-
- sb.append("</tr>");
-
- sb.append("</table>");
-
- out.write(sb.toString().getBytes());
- }
-
private void writeChapterSummary(OutputStream out) throws IOException {
StringBuilder sb = new StringBuilder();
@@ -657,13 +583,15 @@
sb.append(" <div class=\"results\">");
sb.append("<p class=\"description\">");
+
+ String assertionText = parseStrikethrough(parseBold(assertion.getText()));
if (!Strings.isEmpty(assertion.getNote()))
{
- sb.append("<a title=\"" + assertion.getNote() + "\">").append(assertion.getText()).append("</a>");
+ sb.append("<a title=\"" + assertion.getNote() + "\">").append(assertionText).append("</a>");
}
else
{
- sb.append(assertion.getText());
+ sb.append(assertionText);
}
sb.append("</p>\n");
@@ -737,6 +665,34 @@
}
}
}
+
+ private String parseBold(String text)
+ {
+ Matcher m = PATTERN_BOLD.matcher(text);
+
+ String result = text;
+ while (m.find())
+ {
+ String replacement = "<span class=\"highlight\">" + m.group().substring(1, m.group().length() - 1) + "</span>";
+ result = m.replaceFirst(replacement);
+ m.reset(result);
+ }
+ return result;
+ }
+
+ private String parseStrikethrough(String text)
+ {
+ Matcher m = PATTERN_STRIKETHROUGH.matcher(text);
+
+ String result = text;
+ while (m.find())
+ {
+ String replacement = "<del>" + m.group().substring(1, m.group().length() - 1) + "</del>";
+ result = m.replaceFirst(replacement);
+ m.reset(result);
+ }
+ return result;
+ }
private void writeUnmatched(OutputStream out) throws IOException {
if (unmatched.isEmpty()) return;
15 years, 10 months
Hibernate SVN: r16065 - in core/trunk: hibernate-maven-plugin and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-03-03 18:07:49 -0500 (Tue, 03 Mar 2009)
New Revision: 16065
Added:
core/trunk/hibernate-maven-plugin/
core/trunk/hibernate-maven-plugin/pom.xml
core/trunk/hibernate-maven-plugin/src/
core/trunk/hibernate-maven-plugin/src/main/
core/trunk/hibernate-maven-plugin/src/main/java/
core/trunk/hibernate-maven-plugin/src/main/java/org/
core/trunk/hibernate-maven-plugin/src/main/java/org/hibernate/
core/trunk/hibernate-maven-plugin/src/main/java/org/hibernate/maven/
core/trunk/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java
Log:
HHH-3279 : maven plugin
Property changes on: core/trunk/hibernate-maven-plugin
___________________________________________________________________
Name: svn:ignore
+ target
Added: core/trunk/hibernate-maven-plugin/pom.xml
===================================================================
--- core/trunk/hibernate-maven-plugin/pom.xml (rev 0)
+++ core/trunk/hibernate-maven-plugin/pom.xml 2009-03-03 23:07:49 UTC (rev 16065)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>hibernate-parent</artifactId>
+ <groupId>org.hibernate</groupId>
+ <version>3.5.0-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+
+ <name>Hibernate Maven Plugin</name>
+ <description>Maven plugin for various Hibernate-tools</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>${version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.9</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added: core/trunk/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java
===================================================================
--- core/trunk/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java (rev 0)
+++ core/trunk/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java 2009-03-03 23:07:49 UTC (rev 16065)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.maven;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.io.File;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.DirectoryScanner;
+
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
+import org.hibernate.bytecode.buildtime.JavassistInstrumenter;
+import org.hibernate.bytecode.buildtime.CGLIBInstrumenter;
+
+/**
+ * @goal instrument
+ * @phase process-classes
+ * @requiresDependencyResolution
+ *
+ * @author Steve Ebersole
+ */
+public class InstrumentationMojo extends AbstractMojo implements Instrumenter.Options {
+ /**
+ * INTERNAL : The Maven Project to which we are attached
+ *
+ * @parameter expression="${project}"
+ * @required
+ */
+ private MavenProject project;
+
+ /**
+ * Specifies the directory containing the classes to be instrumented. By default we use the
+ * project's output directory, which in turn defaults to <samp>${basedir}/target/classes</samp>.
+ *
+ * @parameter expression="${project.build.outputDirectory}"
+ * @required
+ */
+ private File instrumentationDirectory;
+
+ /**
+ * @parameter
+ */
+ private boolean extended;
+
+ /**
+ * @parameter
+ */
+ private String provider;
+
+ public boolean performExtendedInstrumentation() {
+ return extended;
+ }
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ // first, lets determine whether to apply cglib or javassist based instrumentation...
+ if ( provider == null ) {
+ provider = determineProvider();
+ if ( provider == null ) {
+ throw new MojoExecutionException( "Unable to determine provider to use" );
+ }
+ }
+
+ Instrumenter instrumenter = resolveInstrumenter( provider, new LoggingBridge() );
+ try {
+ instrumenter.execute( collectFilesToProcess() );
+ }
+ catch ( Throwable t ) {
+ throw new MojoExecutionException( "Error executing instrumentation", t );
+ }
+ }
+
+ private Set collectFilesToProcess() {
+ DirectoryScanner scanner = new DirectoryScanner();
+ scanner.setBasedir( instrumentationDirectory );
+ scanner.setIncludes( new String[] { "**/*.class" } );
+ scanner.addDefaultExcludes();
+ scanner.scan();
+ String[] includedFiles = scanner.getIncludedFiles();
+ HashSet fileSet = new HashSet( includedFiles.length + (int)(.75*includedFiles.length) + 1 );
+ fileSet.addAll( Arrays.asList( includedFiles ) );
+ return fileSet;
+ }
+
+ private Instrumenter resolveInstrumenter(String provider, Logger logger) throws MojoExecutionException {
+ if ( "javassist".equals( provider ) ) {
+ return new JavassistInstrumenter( logger, this );
+ }
+ else if ( "cglib".equals( provider ) ) {
+ return new CGLIBInstrumenter( logger, this );
+ }
+ else {
+ throw new MojoExecutionException( "Unable to resolve provider [" + provider + "] to appropriate instrumenter" );
+ }
+ }
+
+ /**
+ * Determine the provider to use. Called in the cases where the user did not explicitly specify; so we look
+ * through the dependencies for the project and decide which provider should be applied.
+ * <p/>
+ * NOTE: this impl prefers javassist.
+ *
+ * @return The provider determined from project's dependencies.
+ */
+ private String determineProvider() {
+ if ( project.getCompileArtifacts() != null ) {
+ boolean foundCglib = false;
+ Iterator itr = project.getCompileArtifacts().iterator();
+ while ( itr.hasNext() ) {
+ final Artifact artifact = ( Artifact ) itr.next();
+ if ( "javassist".equals( artifact.getGroupId() ) && "javassist".equals( artifact.getArtifactId() ) ) {
+ return "javassist";
+ }
+ else if ( "org.hibernate".equals( artifact.getGroupId() )
+ && "hibernate-cglib-repack".equals( artifact.getArtifactId() ) ) {
+ foundCglib = true;
+ }
+ }
+ if ( foundCglib ) {
+ return "cglib";
+ }
+ }
+ return null;
+ }
+
+ private class LoggingBridge implements Logger {
+ public void trace(String message) {
+ getLog().debug( message );
+ }
+
+ public void debug(String message) {
+ getLog().debug( message );
+ }
+
+ public void info(String message) {
+ getLog().info( message );
+ }
+
+ public void warn(String message) {
+ getLog().warn( message );
+ }
+
+ public void error(String message) {
+ getLog().error( message );
+ }
+ }
+}
15 years, 10 months
Hibernate SVN: r16064 - in core/trunk: core/src/main/java/org/hibernate/bytecode and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-03-03 17:57:50 -0500 (Tue, 03 Mar 2009)
New Revision: 16064
Added:
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java
core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java
Modified:
core/trunk/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
core/trunk/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
core/trunk/core/src/main/java/org/hibernate/util/StringHelper.java
core/trunk/parent/pom.xml
core/trunk/pom.xml
Log:
HHH-3279: create series of maven plugins offering functionality of the ant tools
Added: core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/AbstractInstrumenter.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -0,0 +1,443 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+import java.util.zip.CRC32;
+import java.io.File;
+import java.io.DataInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+
+import org.hibernate.bytecode.util.ByteCodeHelper;
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.FieldFilter;
+import org.hibernate.bytecode.ClassTransformer;
+
+/**
+ * Provides the basic templating of how instrumentation should occur.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractInstrumenter implements Instrumenter {
+ private static final int ZIP_MAGIC = 0x504B0304;
+ private static final int CLASS_MAGIC = 0xCAFEBABE;
+
+ protected final Logger logger;
+ protected final Options options;
+
+ /**
+ * Creates the basic instrumentation strategy.
+ *
+ * @param logger The bridge to the environment's logging system.
+ * @param options User-supplied options.
+ */
+ public AbstractInstrumenter(Logger logger, Options options) {
+ this.logger = logger;
+ this.options = options;
+ }
+
+ /**
+ * Given the bytecode of a java class, retrieve the descriptor for that class.
+ *
+ * @param byecode The class bytecode.
+ *
+ * @return The class's descriptor
+ *
+ * @throws Exception Indicates problems access the bytecode.
+ */
+ protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception;
+
+ /**
+ * Create class transformer for the class.
+ *
+ * @param descriptor The descriptor of the class to be instrumented.
+ * @param classNames The names of all classes to be instrumented; the "pipeline" if you will.
+ *
+ * @return The transformer for the given class; may return null to indicate that transformation should
+ * be skipped (ala already instrumented).
+ */
+ protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames);
+
+ /**
+ * The main instrumentation entry point. Given a set of files, perform instrumentation on each discovered class
+ * file.
+ *
+ * @param files The files.
+ */
+ public void execute(Set files) {
+ Set classNames = new HashSet();
+
+ if ( options.performExtendedInstrumentation() ) {
+ logger.debug( "collecting class names for extended instrumentation determination" );
+ try {
+ Iterator itr = files.iterator();
+ while ( itr.hasNext() ) {
+ final File file = ( File ) itr.next();
+ collectClassNames( file, classNames );
+ }
+ }
+ catch ( ExecutionException ee ) {
+ throw ee;
+ }
+ catch ( Exception e ) {
+ throw new ExecutionException( e );
+ }
+ }
+
+ logger.info( "starting instrumentation" );
+ try {
+ Iterator itr = files.iterator();
+ while ( itr.hasNext() ) {
+ final File file = ( File ) itr.next();
+ processFile( file, classNames );
+ }
+ }
+ catch ( ExecutionException ee ) {
+ throw ee;
+ }
+ catch ( Exception e ) {
+ throw new ExecutionException( e );
+ }
+ }
+
+ /**
+ * Extract the names of classes from file, addding them to the classNames collection.
+ * <p/>
+ * IMPL NOTE : file here may be either a class file or a jar. If a jar, all entries in the jar file are
+ * processed.
+ *
+ * @param file The file from which to extract class metadata (descriptor).
+ * @param classNames The collected class name collection.
+ *
+ * @throws Exception indicates problems accessing the file or its contents.
+ */
+ private void collectClassNames(File file, final Set classNames) throws Exception {
+ if ( isClassFile( file ) ) {
+ byte[] bytes = ByteCodeHelper.readByteCode( file );
+ ClassDescriptor descriptor = getClassDescriptor( bytes );
+ classNames.add( descriptor.getName() );
+ }
+ else if ( isJarFile( file ) ) {
+ ZipEntryHandler collector = new ZipEntryHandler() {
+ public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
+ if ( !entry.isDirectory() ) {
+ // see if the entry represents a class file
+ DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
+ if ( din.readInt() == CLASS_MAGIC ) {
+ classNames.add( getClassDescriptor( byteCode ).getName() );
+ }
+ }
+ }
+ };
+ ZipFileProcessor processor = new ZipFileProcessor( collector );
+ processor.process( file );
+ }
+ }
+
+ /**
+ * Does this file represent a compiled class?
+ *
+ * @param file The file to check.
+ *
+ * @return True if the file is a class; false otherwise.
+ *
+ * @throws IOException Indicates problem access the file.
+ */
+ protected final boolean isClassFile(File file) throws IOException {
+ return checkMagic( file, CLASS_MAGIC );
+ }
+
+ /**
+ * Does this file represent a zip file of some format?
+ *
+ * @param file The file to check.
+ *
+ * @return True if the file is n archive; false otherwise.
+ *
+ * @throws IOException Indicates problem access the file.
+ */
+ protected final boolean isJarFile(File file) throws IOException {
+ return checkMagic(file, ZIP_MAGIC);
+ }
+
+ protected final boolean checkMagic(File file, long magic) throws IOException {
+ DataInputStream in = new DataInputStream( new FileInputStream( file ) );
+ try {
+ int m = in.readInt();
+ return magic == m;
+ }
+ finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Actually process the file by applying instrumentation transformations to any classes it contains.
+ * <p/>
+ * Again, just like with {@link #collectClassNames} this method can handle both class and archive files.
+ *
+ * @param file The file to process.
+ * @param classNames The 'pipeline' of classes to be processed. Only actually populated when the user
+ * specifies to perform {@link Options#performExtendedInstrumentation() extended} instrumentation.
+ *
+ * @throws Exception Indicates an issue either access files or applying the transformations.
+ */
+ protected void processFile(File file, Set classNames) throws Exception {
+ if ( isClassFile( file ) ) {
+ logger.debug( "processing class file : " + file.getAbsolutePath() );
+ processClassFile( file, classNames );
+ }
+ else if ( isJarFile( file ) ) {
+ logger.debug( "processing jar file : " + file.getAbsolutePath() );
+ processJarFile( file, classNames );
+ }
+ else {
+ logger.debug( "ignoring file : " + file.getAbsolutePath() );
+ }
+ }
+
+ /**
+ * Process a class file. Delegated to from {@link #processFile} in the case of a class file.
+ *
+ * @param file The class file to process.
+ * @param classNames The 'pipeline' of classes to be processed. Only actually populated when the user
+ * specifies to perform {@link Options#performExtendedInstrumentation() extended} instrumentation.
+ *
+ * @throws Exception Indicates an issue either access files or applying the transformations.
+ */
+ protected void processClassFile(File file, Set classNames) throws Exception {
+ byte[] bytes = ByteCodeHelper.readByteCode( file );
+ ClassDescriptor descriptor = getClassDescriptor( bytes );
+ ClassTransformer transformer = getClassTransformer( descriptor, classNames );
+ if ( transformer == null ) {
+ logger.debug( "no trasformer for class file : " + file.getAbsolutePath() );
+ return;
+ }
+
+ logger.info( "processing class : " + descriptor.getName() + "; file = " + file.getAbsolutePath() );
+ byte[] transformedBytes = transformer.transform(
+ getClass().getClassLoader(),
+ descriptor.getName(),
+ null,
+ null,
+ descriptor.getBytes()
+ );
+
+ OutputStream out = new FileOutputStream( file );
+ try {
+ out.write( transformedBytes );
+ out.flush();
+ }
+ finally {
+ try {
+ out.close();
+ }
+ catch ( IOException ignore) {
+ // intentionally empty
+ }
+ }
+ }
+
+ /**
+ * Process an archive file. Delegated to from {@link #processFile} in the case of an archive file.
+ *
+ * @param file The archive file to process.
+ * @param classNames The 'pipeline' of classes to be processed. Only actually populated when the user
+ * specifies to perform {@link Options#performExtendedInstrumentation() extended} instrumentation.
+ *
+ * @throws Exception Indicates an issue either access files or applying the transformations.
+ */
+ protected void processJarFile(final File file, final Set classNames) throws Exception {
+ File tempFile = File.createTempFile(
+ file.getName(),
+ null,
+ new File( file.getAbsoluteFile().getParent() )
+ );
+
+ try {
+ FileOutputStream fout = new FileOutputStream( tempFile, false );
+ try {
+ final ZipOutputStream out = new ZipOutputStream( fout );
+ ZipEntryHandler transformer = new ZipEntryHandler() {
+ public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
+ logger.debug( "starting zip entry : " + entry.toString() );
+ if ( !entry.isDirectory() ) {
+ // see if the entry represents a class file
+ DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
+ if ( din.readInt() == CLASS_MAGIC ) {
+ ClassDescriptor descriptor = getClassDescriptor( byteCode );
+ ClassTransformer transformer = getClassTransformer( descriptor, classNames );
+ if ( transformer == null ) {
+ logger.debug( "no transformer for zip entry : " + entry.toString() );
+ }
+ else {
+ logger.info( "processing class : " + descriptor.getName() + "; entry = " + file.getAbsolutePath() );
+ byteCode = transformer.transform(
+ getClass().getClassLoader(),
+ descriptor.getName(),
+ null,
+ null,
+ descriptor.getBytes()
+ );
+ }
+ }
+ else {
+ logger.debug( "ignoring zip entry : " + entry.toString() );
+ }
+ }
+
+ ZipEntry outEntry = new ZipEntry( entry.getName() );
+ outEntry.setMethod( entry.getMethod() );
+ outEntry.setComment( entry.getComment() );
+ outEntry.setSize( byteCode.length );
+
+ if ( outEntry.getMethod() == ZipEntry.STORED ){
+ CRC32 crc = new CRC32();
+ crc.update( byteCode );
+ outEntry.setCrc( crc.getValue() );
+ outEntry.setCompressedSize( byteCode.length );
+ }
+ out.putNextEntry( outEntry );
+ out.write( byteCode );
+ out.closeEntry();
+ }
+ };
+ ZipFileProcessor processor = new ZipFileProcessor( transformer );
+ processor.process( file );
+ out.close();
+ }
+ finally{
+ fout.close();
+ }
+
+ if ( file.delete() ) {
+ File newFile = new File( tempFile.getAbsolutePath() );
+ if( !newFile.renameTo( file ) ) {
+ throw new IOException( "can not rename " + tempFile + " to " + file );
+ }
+ }
+ else {
+ throw new IOException( "can not delete " + file );
+ }
+ }
+ finally {
+ if ( ! tempFile.delete() ) {
+ logger.info( "Unable to cleanup temporary jar file : " + tempFile.getAbsolutePath() );
+ }
+ }
+ }
+
+ /**
+ * Allows control over what exacctly to transform.
+ */
+ protected class CustomFieldFilter implements FieldFilter {
+ private final ClassDescriptor descriptor;
+ private final Set classNames;
+
+ public CustomFieldFilter(ClassDescriptor descriptor, Set classNames) {
+ this.descriptor = descriptor;
+ this.classNames = classNames;
+ }
+
+ public boolean shouldInstrumentField(String className, String fieldName) {
+ if ( descriptor.getName().equals( className ) ) {
+ logger.trace( "accepting transformation of field [" + className + "." + fieldName + "]" );
+ return true;
+ }
+ else {
+ logger.trace( "rejecting transformation of field [" + className + "." + fieldName + "]" );
+ return false;
+ }
+ }
+
+ public boolean shouldTransformFieldAccess(
+ String transformingClassName,
+ String fieldOwnerClassName,
+ String fieldName) {
+ if ( descriptor.getName().equals( fieldOwnerClassName ) ) {
+ logger.trace( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
+ return true;
+ }
+ else if ( options.performExtendedInstrumentation() && classNames.contains( fieldOwnerClassName ) ) {
+ logger.trace( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
+ return true;
+ }
+ else {
+ logger.trace( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName );
+ return false;
+ }
+ }
+ }
+
+ /**
+ * General strategy contract for handling entries in an archive file.
+ */
+ private static interface ZipEntryHandler {
+ /**
+ * Apply strategy to the given archive entry.
+ *
+ * @param entry The archive file entry.
+ * @param byteCode
+ *
+ * @throws Exception
+ */
+ public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception;
+ }
+
+ /**
+ * Applies {@link ZipEntryHandler} strategies to the entries of an archive file.
+ */
+ private static class ZipFileProcessor {
+ private final ZipEntryHandler entryHandler;
+
+ public ZipFileProcessor(ZipEntryHandler entryHandler) {
+ this.entryHandler = entryHandler;
+ }
+
+ public void process(File file) throws Exception {
+ ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) );
+
+ try {
+ ZipEntry entry;
+ while ( (entry = zip.getNextEntry()) != null ) {
+ byte bytes[] = ByteCodeHelper.readByteCode( zip );
+ entryHandler.handleEntry( entry, bytes );
+ zip.closeEntry();
+ }
+ }
+ finally {
+ zip.close();
+ }
+ }
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/CGLIBInstrumenter.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -0,0 +1,100 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Set;
+import java.io.ByteArrayInputStream;
+
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.BasicClassFilter;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
+import org.hibernate.repackage.cglib.asm.ClassReader;
+import org.hibernate.repackage.cglib.core.ClassNameReader;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
+
+/**
+ * Strategy for performing build-time instrumentation of persistent classes in order to enable
+ * field-level interception using CGLIB.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public class CGLIBInstrumenter extends AbstractInstrumenter {
+ private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
+
+ private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
+
+ public CGLIBInstrumenter(Logger logger, Options options) {
+ super( logger, options );
+ }
+
+ protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
+ return new CustomClassDescriptor( byecode );
+ }
+
+ protected ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames) {
+ if ( descriptor.isInstrumented() ) {
+ logger.debug( "class [" + descriptor.getName() + "] already instrumented" );
+ return null;
+ }
+ else {
+ return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor, classNames ) );
+ }
+ }
+
+ private static class CustomClassDescriptor implements ClassDescriptor {
+ private final byte[] bytecode;
+ private final String name;
+ private final boolean isInstrumented;
+
+ public CustomClassDescriptor(byte[] bytecode) throws Exception {
+ this.bytecode = bytecode;
+ ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
+ String[] names = ClassNameReader.getClassInfo( reader );
+ this.name = names[0];
+ boolean instrumented = false;
+ for ( int i = 1; i < names.length; i++ ) {
+ if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
+ instrumented = true;
+ break;
+ }
+ }
+ this.isInstrumented = instrumented;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isInstrumented() {
+ return isInstrumented;
+ }
+
+ public byte[] getBytes() {
+ return bytecode;
+ }
+ }
+
+}
Added: core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/ExecutionException.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+/**
+ * Indicates problem performing the instrumentation execution.
+ *
+ * @author Steve Ebersole
+ */
+public class ExecutionException extends RuntimeException {
+ public ExecutionException(String message) {
+ super( message );
+ }
+
+ public ExecutionException(Throwable cause) {
+ super( cause );
+ }
+
+ public ExecutionException(String message, Throwable cause) {
+ super( message, cause );
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Instrumenter.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Set;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface Instrumenter {
+ public void execute(Set files);
+
+ public static interface Options {
+ public boolean performExtendedInstrumentation();
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/JavassistInstrumenter.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -0,0 +1,98 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+import java.util.Set;
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.ByteArrayInputStream;
+
+import javassist.bytecode.ClassFile;
+
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.BasicClassFilter;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
+import org.hibernate.bytecode.javassist.FieldHandled;
+
+/**
+ * Strategy for performing build-time instrumentation of persistent classes in order to enable
+ * field-level interception using Javassist.
+ *
+ * @author Steve Ebersole
+ * @author Muga Nishizawa
+ */
+public class JavassistInstrumenter extends AbstractInstrumenter {
+
+ private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
+
+ private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
+
+ public JavassistInstrumenter(Logger logger, Options options) {
+ super( logger, options );
+ }
+
+ protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException {
+ return new CustomClassDescriptor( bytecode );
+ }
+
+ protected ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames) {
+ if ( descriptor.isInstrumented() ) {
+ logger.debug( "class [" + descriptor.getName() + "] already instrumented" );
+ return null;
+ }
+ else {
+ return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor, classNames ) );
+ }
+ }
+
+ private static class CustomClassDescriptor implements ClassDescriptor {
+ private final byte[] bytes;
+ private final ClassFile classFile;
+
+ public CustomClassDescriptor(byte[] bytes) throws IOException {
+ this.bytes = bytes;
+ this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) );
+ }
+
+ public String getName() {
+ return classFile.getName();
+ }
+
+ public boolean isInstrumented() {
+ String[] intfs = classFile.getInterfaces();
+ for ( int i = 0; i < intfs.length; i++ ) {
+ if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public byte[] getBytes() {
+ return bytes;
+ }
+ }
+
+}
Added: core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/buildtime/Logger.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.bytecode.buildtime;
+
+/**
+ * Provides an abstraction for how instrumentation does logging because it is usually run in environments (Ant/Maven)
+ * with their own logging infrastructure. This abstraction allows proper bridging.
+ *
+ * @author Steve Ebersole
+ */
+public interface Logger {
+ public void trace(String message);
+
+ public void debug(String message);
+
+ public void info(String message);
+
+ public void warn(String message);
+
+ public void error(String message);
+}
Modified: core/trunk/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java 2009-03-03 16:54:21 UTC (rev 16063)
+++ core/trunk/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.tool.instrument;
@@ -29,43 +28,31 @@
import org.apache.tools.ant.Project;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.util.ByteCodeHelper;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
+
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.CRC32;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.DataInputStream;
-import java.io.ByteArrayInputStream;
/**
- * Super class for all Hibernate instrumentation tasks. Provides the basic
- * templating of how instrumentation should occur.
+ * Super class for all Hibernate instrumentation tasks. Provides the basic templating of how instrumentation
+ * should occur; subclasses simply plug in to that process appropriately for the given bytecode provider.
*
* @author Steve Ebersole
*/
-public abstract class BasicInstrumentationTask extends Task {
+public abstract class BasicInstrumentationTask extends Task implements Instrumenter.Options {
- private static final int ZIP_MAGIC = 0x504B0304;
- private static final int CLASS_MAGIC = 0xCAFEBABE;
+ private final LoggerBridge logger = new LoggerBridge();
- protected final Logger logger = new Logger();
private List filesets = new ArrayList();
- private Set classNames = new HashSet();
private boolean extended;
+
+ // deprecated option...
private boolean verbose;
public void addFileset(FileSet set) {
@@ -92,32 +79,24 @@
this.verbose = verbose;
}
+ public final boolean performExtendedInstrumentation() {
+ return isExtended();
+ }
+
+ protected abstract Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options);
+
public void execute() throws BuildException {
- if ( isExtended() ) {
- collectClassNames();
+ try {
+ buildInstrumenter( logger, this )
+ .execute( collectSpecifiedFiles() );
}
- logger.info( "starting instrumentation" );
- Project project = getProject();
- Iterator filesets = filesets();
- while ( filesets.hasNext() ) {
- FileSet fs = ( FileSet ) filesets.next();
- DirectoryScanner ds = fs.getDirectoryScanner( project );
- String[] includedFiles = ds.getIncludedFiles();
- File d = fs.getDir( project );
- for ( int i = 0; i < includedFiles.length; ++i ) {
- File file = new File( d, includedFiles[i] );
- try {
- processFile( file );
- }
- catch ( Exception e ) {
- throw new BuildException( e );
- }
- }
+ catch ( Throwable t ) {
+ throw new BuildException( t );
}
}
- private void collectClassNames() {
- logger.info( "collecting class names for extended instrumentation determination" );
+ private Set collectSpecifiedFiles() {
+ HashSet files = new HashSet();
Project project = getProject();
Iterator filesets = filesets();
while ( filesets.hasNext() ) {
@@ -126,239 +105,14 @@
String[] includedFiles = ds.getIncludedFiles();
File d = fs.getDir( project );
for ( int i = 0; i < includedFiles.length; ++i ) {
- File file = new File( d, includedFiles[i] );
- try {
- collectClassNames( file );
- }
- catch ( Exception e ) {
- throw new BuildException( e );
- }
+ files.add( new File( d, includedFiles[i] ) );
}
}
- logger.info( classNames.size() + " class(es) being checked" );
+ return files;
}
- private void collectClassNames(File file) throws Exception {
- if ( isClassFile( file ) ) {
- byte[] bytes = ByteCodeHelper.readByteCode( file );
- ClassDescriptor descriptor = getClassDescriptor( bytes );
- classNames.add( descriptor.getName() );
- }
- else if ( isJarFile( file ) ) {
- ZipEntryHandler collector = new ZipEntryHandler() {
- public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
- if ( !entry.isDirectory() ) {
- // see if the entry represents a class file
- DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
- if ( din.readInt() == CLASS_MAGIC ) {
- classNames.add( getClassDescriptor( byteCode ).getName() );
- }
- }
- }
- };
- ZipFileProcessor processor = new ZipFileProcessor( collector );
- processor.process( file );
- }
- }
-
- protected void processFile(File file) throws Exception {
- logger.verbose( "processing file : " + file.toURL() );
- if ( isClassFile( file ) ) {
- processClassFile(file);
- }
- else if ( isJarFile( file ) ) {
- processJarFile(file);
- }
- else {
- logger.verbose( "ignoring " + file.toURL() );
-
- }
- }
-
- protected final boolean isClassFile(File file) throws IOException {
- return checkMagic( file, CLASS_MAGIC );
- }
-
- protected final boolean isJarFile(File file) throws IOException {
- return checkMagic(file, ZIP_MAGIC);
- }
-
- protected final boolean checkMagic(File file, long magic) throws IOException {
- DataInputStream in = new DataInputStream( new FileInputStream( file ) );
- try {
- int m = in.readInt();
- return magic == m;
- }
- finally {
- in.close();
- }
- }
-
- protected void processClassFile(File file) throws Exception {
- logger.verbose( "Starting class file : " + file.toURL() );
- byte[] bytes = ByteCodeHelper.readByteCode( file );
- ClassDescriptor descriptor = getClassDescriptor( bytes );
- ClassTransformer transformer = getClassTransformer( descriptor );
- if ( transformer == null ) {
- logger.verbose( "skipping file : " + file.toURL() );
- return;
- }
-
- logger.info( "processing class [" + descriptor.getName() + "]; file = " + file.toURL() );
- byte[] transformedBytes = transformer.transform(
- getClass().getClassLoader(),
- descriptor.getName(),
- null,
- null,
- descriptor.getBytes()
- );
-
- OutputStream out = new FileOutputStream( file );
- try {
- out.write( transformedBytes );
- out.flush();
- }
- finally {
- try {
- out.close();
- }
- catch ( IOException ignore) {
- // intentionally empty
- }
- }
- }
-
- protected void processJarFile(final File file) throws Exception {
- logger.verbose( "starting jar file : " + file.toURL() );
-
- File tempFile = File.createTempFile(
- file.getName(),
- null,
- new File( file.getAbsoluteFile().getParent() )
- );
-
- try {
- FileOutputStream fout = new FileOutputStream( tempFile, false );
- try {
- final ZipOutputStream out = new ZipOutputStream( fout );
- ZipEntryHandler transformer = new ZipEntryHandler() {
- public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
- logger.verbose( "starting entry : " + entry.toString() );
- if ( !entry.isDirectory() ) {
- // see if the entry represents a class file
- DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
- if ( din.readInt() == CLASS_MAGIC ) {
- ClassDescriptor descriptor = getClassDescriptor( byteCode );
- ClassTransformer transformer = getClassTransformer( descriptor );
- if ( transformer == null ) {
- logger.verbose( "skipping entry : " + entry.toString() );
- }
- else {
- logger.info( "processing class [" + descriptor.getName() + "]; entry = " + file.toURL() );
- byteCode = transformer.transform(
- getClass().getClassLoader(),
- descriptor.getName(),
- null,
- null,
- descriptor.getBytes()
- );
- }
- }
- else {
- logger.verbose( "ignoring zip entry : " + entry.toString() );
- }
- }
-
- ZipEntry outEntry = new ZipEntry( entry.getName() );
- outEntry.setMethod( entry.getMethod() );
- outEntry.setComment( entry.getComment() );
- outEntry.setSize( byteCode.length );
-
- if ( outEntry.getMethod() == ZipEntry.STORED ){
- CRC32 crc = new CRC32();
- crc.update( byteCode );
- outEntry.setCrc( crc.getValue() );
- outEntry.setCompressedSize( byteCode.length );
- }
- out.putNextEntry( outEntry );
- out.write( byteCode );
- out.closeEntry();
- }
- };
- ZipFileProcessor processor = new ZipFileProcessor( transformer );
- processor.process( file );
- out.close();
- }
- finally{
- fout.close();
- }
-
- if ( file.delete() ) {
- File newFile = new File( tempFile.getAbsolutePath() );
- if( !newFile.renameTo( file ) ) {
- throw new IOException( "can not rename " + tempFile + " to " + file );
- }
- }
- else {
- throw new IOException("can not delete " + file);
- }
- }
- finally {
- tempFile.delete();
- }
- }
-
- protected boolean isBeingIntrumented(String className) {
- logger.verbose( "checking to see if class [" + className + "] is set to be instrumented" );
- return classNames.contains( className );
- }
-
- protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception;
-
- protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor);
-
- protected class CustomFieldFilter implements FieldFilter {
- private final ClassDescriptor descriptor;
-
- public CustomFieldFilter(ClassDescriptor descriptor) {
- this.descriptor = descriptor;
- }
-
- public boolean shouldInstrumentField(String className, String fieldName) {
- if ( descriptor.getName().equals( className ) ) {
- logger.verbose( "accepting transformation of field [" + className + "." + fieldName + "]" );
- return true;
- }
- else {
- logger.verbose( "rejecting transformation of field [" + className + "." + fieldName + "]" );
- return false;
- }
- }
-
- public boolean shouldTransformFieldAccess(
- String transformingClassName,
- String fieldOwnerClassName,
- String fieldName) {
- if ( descriptor.getName().equals( fieldOwnerClassName ) ) {
- logger.verbose( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
- return true;
- }
- else if ( isExtended() && isBeingIntrumented( fieldOwnerClassName ) ) {
- logger.verbose( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
- return true;
- }
- else {
- logger.verbose( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName );
- return false;
- }
- }
- }
-
- protected class Logger {
- public void verbose(String message) {
- if ( verbose ) {
- System.out.println( message );
- }
+ protected class LoggerBridge implements Logger {
+ public void trace(String message) {
log( message, Project.MSG_VERBOSE );
}
@@ -373,34 +127,10 @@
public void warn(String message) {
log( message, Project.MSG_WARN );
}
- }
-
- private static interface ZipEntryHandler {
- public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception;
- }
-
- private static class ZipFileProcessor {
- private final ZipEntryHandler entryHandler;
-
- public ZipFileProcessor(ZipEntryHandler entryHandler) {
- this.entryHandler = entryHandler;
+ public void error(String message) {
+ log( message, Project.MSG_ERR );
}
-
- public void process(File file) throws Exception {
- ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) );
-
- try {
- ZipEntry entry;
- while ( (entry = zip.getNextEntry()) != null ) {
- byte bytes[] = ByteCodeHelper.readByteCode( zip );
- entryHandler.handleEntry( entry, bytes );
- zip.closeEntry();
- }
- }
- finally {
- zip.close();
- }
- }
}
+
}
Modified: core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java 2009-03-03 16:54:21 UTC (rev 16063)
+++ core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -24,18 +24,11 @@
*/
package org.hibernate.tool.instrument.cglib;
-import org.hibernate.bytecode.util.BasicClassFilter;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
-import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.buildtime.CGLIBInstrumenter;
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.hibernate.repackage.cglib.asm.ClassReader;
-import java.io.ByteArrayInputStream;
-
-import org.hibernate.repackage.cglib.core.ClassNameReader;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
-
/**
* An Ant task for instrumenting persistent classes in order to enable
* field-level interception using CGLIB.
@@ -50,7 +43,7 @@
* required Hibernate and CGLIB libraries.
* <p/>
* And then use it like:<pre>
- * <instrument verbose="true">
+ * <instrument>
* <fileset dir="${testclasses.dir}/org/hibernate/test">
* <include name="yadda/yadda/**"/>
* ...
@@ -62,7 +55,7 @@
* <p/>
* Optionally you can chose to enable "Extended Instrumentation" if desired
* by specifying the extended attriubute on the task:<pre>
- * <instrument verbose="true" extended="true">
+ * <instrument extended="true">
* ...
* </instrument>
* </pre>
@@ -72,58 +65,7 @@
* @author Steve Ebersole
*/
public class InstrumentTask extends BasicInstrumentationTask {
-
- private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
-
- private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
-
-
- protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
- return new CustomClassDescriptor( byecode );
+ protected Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options) {
+ return new CGLIBInstrumenter( logger, options );
}
-
- protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
- if ( descriptor.isInstrumented() ) {
- logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
- return null;
- }
- else {
- return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
- }
- }
-
- private static class CustomClassDescriptor implements ClassDescriptor {
- private final byte[] bytecode;
- private final String name;
- private final boolean isInstrumented;
-
- public CustomClassDescriptor(byte[] bytecode) throws Exception {
- this.bytecode = bytecode;
- ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
- String[] names = ClassNameReader.getClassInfo( reader );
- this.name = names[0];
- boolean instrumented = false;
- for ( int i = 1; i < names.length; i++ ) {
- if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
- instrumented = true;
- break;
- }
- }
- this.isInstrumented = instrumented;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean isInstrumented() {
- return isInstrumented;
- }
-
- public byte[] getBytes() {
- return bytecode;
- }
- }
-
-
}
Modified: core/trunk/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java 2009-03-03 16:54:21 UTC (rev 16063)
+++ core/trunk/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -24,18 +24,10 @@
*/
package org.hibernate.tool.instrument.javassist;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.ByteArrayInputStream;
-
-import javassist.bytecode.ClassFile;
-
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.JavassistInstrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.util.BasicClassFilter;
-import org.hibernate.bytecode.ClassTransformer;
-import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
-import org.hibernate.bytecode.javassist.FieldHandled;
/**
* An Ant task for instrumenting persistent classes in order to enable
@@ -73,51 +65,7 @@
* @author Steve Ebersole
*/
public class InstrumentTask extends BasicInstrumentationTask {
-
- private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
-
- private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
-
- protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException {
- return new CustomClassDescriptor( bytecode );
+ protected Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options) {
+ return new JavassistInstrumenter( logger, options );
}
-
- protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
- if ( descriptor.isInstrumented() ) {
- logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
- return null;
- }
- else {
- return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
- }
- }
-
- private static class CustomClassDescriptor implements ClassDescriptor {
- private final byte[] bytes;
- private final ClassFile classFile;
-
- public CustomClassDescriptor(byte[] bytes) throws IOException {
- this.bytes = bytes;
- this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) );
- }
-
- public String getName() {
- return classFile.getName();
- }
-
- public boolean isInstrumented() {
- String[] intfs = classFile.getInterfaces();
- for ( int i = 0; i < intfs.length; i++ ) {
- if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
- return true;
- }
- }
- return false;
- }
-
- public byte[] getBytes() {
- return bytes;
- }
- }
-
}
Modified: core/trunk/core/src/main/java/org/hibernate/util/StringHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/StringHelper.java 2009-03-03 16:54:21 UTC (rev 16063)
+++ core/trunk/core/src/main/java/org/hibernate/util/StringHelper.java 2009-03-03 22:57:50 UTC (rev 16064)
@@ -93,13 +93,16 @@
public static String[] replace(String templates[], String placeholder, String replacement) {
String[] result = new String[templates.length];
for ( int i =0; i<templates.length; i++ ) {
- result[i] = replace( templates[i], placeholder, replacement );;
+ result[i] = replace( templates[i], placeholder, replacement );
}
return result;
}
public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
- int loc = template == null ? -1 : template.indexOf( placeholder );
+ if ( template == null ) {
+ return template;
+ }
+ int loc = template.indexOf( placeholder );
if ( loc < 0 ) {
return template;
}
@@ -119,6 +122,9 @@
public static String replaceOnce(String template, String placeholder, String replacement) {
+ if ( template == null ) {
+ return template; // returnign null!
+ }
int loc = template == null ? -1 : template.indexOf( placeholder );
if ( loc < 0 ) {
return template;
@@ -435,12 +441,12 @@
return name;
}
else {
- return new StringBuilder( name.length() + 2 ).append('`').append( name ).append( '`' ).toString();
+ return new StringBuffer( name.length() + 2 ).append('`').append( name ).append( '`' ).toString();
}
}
/**
- * Return the unquoted version of name (stripping the start and end '`' chanracters if present).
+ * Return the unquoted version of name (stripping the start and end '`' characters if present).
*
* @param name The name to be unquoted.
* @return The unquoted version.
Modified: core/trunk/parent/pom.xml
===================================================================
--- core/trunk/parent/pom.xml 2009-03-03 16:54:21 UTC (rev 16063)
+++ core/trunk/parent/pom.xml 2009-03-03 22:57:50 UTC (rev 16064)
@@ -122,18 +122,18 @@
<goals>
<goal>enforce</goal>
</goals>
- <configuration>
- <rules>
- <requireJavaVersion>
- <version>[1.5,)</version>
- </requireJavaVersion>
- <requireMavenVersion>
- <version>(2.0.7,)</version>
- </requireMavenVersion>
- </rules>
- </configuration>
</execution>
</executions>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <version>[1.5,)</version>
+ </requireJavaVersion>
+ <requireMavenVersion>
+ <version>(2.0.7,)</version>
+ </requireMavenVersion>
+ </rules>
+ </configuration>
</plugin>
<!-- by default, compile to JDK 1.4 compatibility (individual modules and/or user can override) -->
<plugin>
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2009-03-03 16:54:21 UTC (rev 16063)
+++ core/trunk/pom.xml 2009-03-03 22:57:50 UTC (rev 16064)
@@ -62,7 +62,8 @@
<module>testing</module>
<module>testsuite</module>
<module>tutorials</module>
-<!--
+ <module>hibernate-maven-plugin</module>
+ <!--
Need to scope bytecode providers first...
<module>bytecode-cglib</module>
<module>bytecode-javassist</module>
15 years, 10 months
Hibernate SVN: r16063 - in core/branches/envers-hibernate-3.3: src/main/java/org/hibernate/envers/configuration/metadata and 12 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-03-03 11:54:21 -0500 (Tue, 03 Mar 2009)
New Revision: 16063
Added:
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/ComponentSetTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java
Removed:
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java
Modified:
core/branches/envers-hibernate-3.3/pom.xml
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java
core/branches/envers-hibernate-3.3/src/test/resources/testng.xml
Log:
svn merge -r 15899:16062 https://svn.jboss.org/repos/hibernate/core/trunk/envers .
Modified: core/branches/envers-hibernate-3.3/pom.xml
===================================================================
--- core/branches/envers-hibernate-3.3/pom.xml 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/pom.xml 2009-03-03 16:54:21 UTC (rev 16063)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-parent</artifactId>
- <version>3.4.0-SNAPSHOT</version>
+ <version>3.5.0-SNAPSHOT</version>
</parent>
<groupId>org.jboss.envers</groupId>
@@ -84,42 +84,6 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
- <exclusions>
- <!-- todo : only needed until we migrate EM back to core -->
- <exclusion>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate</artifactId>
- </exclusion>
- <exclusion>
- <groupId>javassist</groupId>
- <artifactId>javassist</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>javassist</artifactId>
- </exclusion>
- <exclusion>
- <!-- OMG, YUCK YUCK YUCK -->
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-validator</artifactId>
- </exclusion>
- <exclusion>
- <groupId>net.sf.ehcache</groupId>
- <artifactId>ehcache</artifactId>
- </exclusion>
- <exclusion>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- </exclusion>
- <exclusion>
- <groupId>asm</groupId>
- <artifactId>asm</artifactId>
- </exclusion>
- <exclusion>
- <groupId>asm</groupId>
- <artifactId>asm-attrs</artifactId>
- </exclusion>
- </exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
@@ -159,11 +123,6 @@
<version>3.3.1.GA</version>
</dependency>
<dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>1.0</version>
- </dependency>
- <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.4.0.GA</version>
@@ -184,6 +143,11 @@
<version>3.2.0.ga</version>
</dependency>
<dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -27,7 +27,8 @@
EntityXmlMappingData xmlMappingData, boolean firstPass) {
Component prop_component = (Component) value;
- CompositeMapperBuilder componentMapper = mapper.addComponent(propertyAuditingData.getPropertyData());
+ CompositeMapperBuilder componentMapper = mapper.addComponent(propertyAuditingData.getPropertyData(),
+ prop_component.getComponentClassName());
// The property auditing data must be for a component.
ComponentAuditingData componentAuditingData = (ComponentAuditingData) propertyAuditingData;
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -118,7 +118,7 @@
}
new AuditedPropertiesReader(defaultStore, new PersistentClassPropertiesSource(xclass), auditData,
- globalCfg, "").read();
+ globalCfg, reflectionManager, "").read();
addAuditTable(xclass);
addAuditSecondaryTables(xclass);
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -13,6 +13,7 @@
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.AuditOverrides;
@@ -24,6 +25,7 @@
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
+import org.hibernate.MappingException;
import org.jboss.envers.Versioned;
/**
@@ -40,6 +42,7 @@
private final PersistentPropertiesSource persistentPropertiesSource;
private final AuditedPropertiesHolder auditedPropertiesHolder;
private final GlobalConfiguration globalCfg;
+ private final ReflectionManager reflectionManager;
private final String propertyNamePrefix;
private final Set<String> propertyAccessedPersistentProperties;
@@ -49,11 +52,13 @@
PersistentPropertiesSource persistentPropertiesSource,
AuditedPropertiesHolder auditedPropertiesHolder,
GlobalConfiguration globalCfg,
+ ReflectionManager reflectionManager,
String propertyNamePrefix) {
this.defaultStore = defaultStore;
this.persistentPropertiesSource = persistentPropertiesSource;
this.auditedPropertiesHolder = auditedPropertiesHolder;
this.globalCfg = globalCfg;
+ this.reflectionManager = reflectionManager;
this.propertyNamePrefix = propertyNamePrefix;
propertyAccessedPersistentProperties = newHashSet();
@@ -104,9 +109,10 @@
isAudited = fillPropertyData(property, componentData, accessType);
PersistentPropertiesSource componentPropertiesSource = new ComponentPropertiesSource(
- property.getType(), (Component) propertyValue);
+ (Component) propertyValue);
new AuditedPropertiesReader(ModificationStore.FULL, componentPropertiesSource, componentData,
- globalCfg, propertyNamePrefix+ MappingTools.createComponentPrefix(property.getName()))
+ globalCfg, reflectionManager,
+ propertyNamePrefix + MappingTools.createComponentPrefix(property.getName()))
.read();
propertyData = componentData;
@@ -255,8 +261,13 @@
private final XClass xclass;
private final Component component;
- private ComponentPropertiesSource(XClass xclass, Component component) {
- this.xclass = xclass;
+ private ComponentPropertiesSource(Component component) {
+ try {
+ this.xclass = reflectionManager.classForName(component.getComponentClassName(), this.getClass());
+ } catch (ClassNotFoundException e) {
+ throw new MappingException(e);
+ }
+
this.component = component;
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -34,7 +34,6 @@
import org.hibernate.envers.tools.reflection.ReflectionTools;
import org.hibernate.collection.PersistentCollection;
-import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
import org.hibernate.util.ReflectHelper;
@@ -42,20 +41,22 @@
* @author Adam Warski (adam at warski dot org)
*/
public class ComponentPropertyMapper implements PropertyMapper, CompositeMapperBuilder {
- private PropertyData propertyData;
- private ExtendedPropertyMapper delegate;
+ private final PropertyData propertyData;
+ private final ExtendedPropertyMapper delegate;
+ private final String componentClassName;
- public ComponentPropertyMapper(PropertyData propertyData) {
+ public ComponentPropertyMapper(PropertyData propertyData, String componentClassName) {
this.propertyData = propertyData;
this.delegate = new MultiPropertyMapper();
+ this.componentClassName = componentClassName;
}
public void add(PropertyData propertyData) {
delegate.add(propertyData);
}
- public CompositeMapperBuilder addComponent(PropertyData propertyData) {
- return delegate.addComponent(propertyData);
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) {
+ return delegate.addComponent(propertyData, componentClassName);
}
public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) {
@@ -71,11 +72,11 @@
return;
}
- Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyData);
Setter setter = ReflectionTools.getSetter(obj.getClass(), propertyData);
try {
- Object subObj = ReflectHelper.getDefaultConstructor(getter.getReturnType()).newInstance();
+ Object subObj = ReflectHelper.getDefaultConstructor(
+ Thread.currentThread().getContextClassLoader().loadClass(componentClassName)).newInstance();
setter.set(obj, subObj, null);
delegate.mapToEntityFromMap(verCfg, subObj, data, primaryKey, versionsReader, revision);
} catch (Exception e) {
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -29,6 +29,6 @@
* @author Adam Warski (adam at warski dot org)
*/
public interface CompositeMapperBuilder extends SimpleMapperBuilder {
- public CompositeMapperBuilder addComponent(PropertyData propertyData);
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName);
public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper);
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -56,13 +56,13 @@
propertyDatas.put(propertyData.getName(), propertyData);
}
- public CompositeMapperBuilder addComponent(PropertyData propertyData) {
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) {
if (properties.get(propertyData) != null) {
// This is needed for second pass to work properly in the components mapper
return (CompositeMapperBuilder) properties.get(propertyData);
}
- ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData);
+ ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData, componentClassName);
addComposite(propertyData, componentMapperBuilder);
return componentMapperBuilder;
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -86,8 +86,8 @@
}
}
- public CompositeMapperBuilder addComponent(PropertyData propertyData) {
- return main.addComponent(propertyData);
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) {
+ return main.addComponent(propertyData, componentClassName);
}
public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) {
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -114,13 +114,16 @@
Set<Object> added = new HashSet<Object>();
if (newColl != null) { added.addAll(newCollection); }
- if (oldColl != null) { added.removeAll(oldCollection); }
+ // Re-hashing the old collection as the hash codes of the elements there may have changed, and the
+ // removeAll in AbstractSet has an implementation that is hashcode-change sensitive (as opposed to addAll).
+ if (oldColl != null) { added.removeAll(new HashSet(oldCollection)); }
addCollectionChanges(collectionChanges, added, RevisionType.ADD, id);
Set<Object> deleted = new HashSet<Object>();
if (oldColl != null) { deleted.addAll(oldCollection); }
- if (newColl != null) { deleted.removeAll(newCollection); }
+ // The same as above - re-hashing new collection.
+ if (newColl != null) { deleted.removeAll(new HashSet(newCollection)); }
addCollectionChanges(collectionChanges, deleted, RevisionType.DEL, id);
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/ComponentSetTestEntity.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/components/ComponentSetTestEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/ComponentSetTestEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/ComponentSetTestEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,100 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.entities.components;
+
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class ComponentSetTestEntity {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Embedded
+ @Audited
+ private Set<Component1> comps = new HashSet<Component1>();
+
+ public ComponentSetTestEntity() {
+ }
+
+ public ComponentSetTestEntity(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public Set<Component1> getComps() {
+ return comps;
+ }
+
+ public void setComps(Set<Component1> comps) {
+ this.comps = comps;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ComponentSetTestEntity)) return false;
+
+ ComponentSetTestEntity that = (ComponentSetTestEntity) o;
+
+ if (comps != null ? !comps.equals(that.comps) : that.comps != null) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id != null ? id.hashCode() : 0;
+ result = 31 * result + (comps != null ? comps.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentSetTestEntity{" +
+ "id=" + id +
+ ", comps=" + comps +
+ '}';
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/components/collections)
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,87 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.components.collections;
-
-import java.util.Arrays;
-import java.util.Set;
-import javax.persistence.EntityManager;
-
-import org.hibernate.envers.test.AbstractEntityTest;
-import org.hibernate.envers.test.entities.components.Component1;
-import org.hibernate.envers.test.entities.components.ComponentSetTestEntity;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.hibernate.ejb.Ejb3Configuration;
-
-/**
- * TODO: enable and implement
- * @author Adam Warski (adam at warski dot org)
- */
-public class CollectionOfComponents extends AbstractEntityTest {
- private Integer id1;
-
- public void configure(Ejb3Configuration cfg) {
- cfg.addAnnotatedClass(ComponentSetTestEntity.class);
- }
-
- @BeforeClass(dependsOnMethods = "init")
- public void initData() {
- // Revision 1
- EntityManager em = getEntityManager();
- em.getTransaction().begin();
-
- ComponentSetTestEntity cte1 = new ComponentSetTestEntity();
-
- em.persist(cte1);
-
- em.getTransaction().commit();
-
- // Revision 2
- em = getEntityManager();
- em.getTransaction().begin();
-
- cte1 = em.find(ComponentSetTestEntity.class, cte1.getId());
-
- cte1.getComps().add(new Component1("a", "b"));
-
- em.getTransaction().commit();
-
- id1 = cte1.getId();
- }
-
- @Test(enabled = false)
- public void testRevisionsCounts() {
- assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(ComponentSetTestEntity.class, id1));
- }
-
- @Test(enabled = false)
- public void testHistoryOfId1() {
- assert getAuditReader().find(ComponentSetTestEntity.class, id1, 1).getComps().size() == 0;
-
- Set<Component1> comps1 = getAuditReader().find(ComponentSetTestEntity.class, id1, 2).getComps();
- assert comps1.size() == 1;
- assert comps1.contains(new Component1("a", "b"));
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/collections/CollectionOfComponents.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.components.collections;
+
+import java.util.Arrays;
+import java.util.Set;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.components.Component1;
+import org.hibernate.envers.test.entities.components.ComponentSetTestEntity;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * TODO: enable and implement
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class CollectionOfComponents extends AbstractEntityTest {
+ private Integer id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(ComponentSetTestEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ ComponentSetTestEntity cte1 = new ComponentSetTestEntity();
+
+ em.persist(cte1);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ cte1 = em.find(ComponentSetTestEntity.class, cte1.getId());
+
+ cte1.getComps().add(new Component1("a", "b"));
+
+ em.getTransaction().commit();
+
+ id1 = cte1.getId();
+ }
+
+ @Test(enabled = false)
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(ComponentSetTestEntity.class, id1));
+ }
+
+ @Test(enabled = false)
+ public void testHistoryOfId1() {
+ assert getAuditReader().find(ComponentSetTestEntity.class, id1, 1).getComps().size() == 0;
+
+ Set<Component1> comps1 = getAuditReader().find(ComponentSetTestEntity.class, id1, 2).getComps();
+ assert comps1.size() == 1;
+ assert comps1.contains(new Component1("a", "b"));
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode)
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,103 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.hashcode;
-
-import java.util.Arrays;
-import javax.persistence.EntityManager;
-
-import org.hibernate.envers.test.AbstractEntityTest;
-import org.hibernate.envers.test.tools.TestTools;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.hibernate.ejb.Ejb3Configuration;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public class ChangingHashcode extends AbstractEntityTest {
- private Long pageId;
- private Long imageId;
-
- public void configure(Ejb3Configuration cfg) {
- cfg.addAnnotatedClass(WikiPage.class);
- cfg.addAnnotatedClass(WikiImage.class);
- }
-
- @BeforeClass(dependsOnMethods = "init")
- public void initData() {
- // Revision 1
- EntityManager em = getEntityManager();
- em.getTransaction().begin();
-
- WikiPage page = new WikiPage("title", "content");
- em.persist(page);
-
- em.getTransaction().commit();
-
- // Revision 2
- em = getEntityManager();
- em.getTransaction().begin();
-
- WikiImage image = new WikiImage("name1");
- em.persist(image);
-
- page = em.find(WikiPage.class, page.getId());
- page.getImages().add(image);
-
- em.getTransaction().commit();
-
- // Revision 3
- em = getEntityManager();
- em.getTransaction().begin();
-
- image = em.find(WikiImage.class, image.getId());
- image.setName("name2");
-
- em.getTransaction().commit();
-
- pageId = page.getId();
- imageId = image.getId();
- }
-
- @Test
- public void testRevisionsCounts() {
- assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(WikiPage.class, pageId));
- assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(WikiImage.class, imageId));
- }
-
- @Test
- public void testHistoryOfImage() {
- assert getAuditReader().find(WikiImage.class, imageId, 1) == null;
- assert getAuditReader().find(WikiImage.class, imageId, 2).equals(new WikiImage("name1"));
- assert getAuditReader().find(WikiImage.class, imageId, 3).equals(new WikiImage("name2"));
- }
-
- @Test
- public void testHistoryOfPage() {
- assert getAuditReader().find(WikiPage.class, pageId, 1).getImages().size() == 0;
- assert getAuditReader().find(WikiPage.class, pageId, 2).getImages().equals(TestTools.makeSet(new WikiImage("name1")));
- assert getAuditReader().find(WikiPage.class, pageId, 3).getImages().equals(TestTools.makeSet(new WikiImage("name2")));
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/ChangingHashcode.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,103 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.hashcode;
+
+import java.util.Arrays;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.tools.TestTools;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class ChangingHashcode extends AbstractEntityTest {
+ private Long pageId;
+ private Long imageId;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(WikiPage.class);
+ cfg.addAnnotatedClass(WikiImage.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ WikiPage page = new WikiPage("title", "content");
+ em.persist(page);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ WikiImage image = new WikiImage("name1");
+ em.persist(image);
+
+ page = em.find(WikiPage.class, page.getId());
+ page.getImages().add(image);
+
+ em.getTransaction().commit();
+
+ // Revision 3
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ image = em.find(WikiImage.class, image.getId());
+ image.setName("name2");
+
+ em.getTransaction().commit();
+
+ pageId = page.getId();
+ imageId = image.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(WikiPage.class, pageId));
+ assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(WikiImage.class, imageId));
+ }
+
+ @Test
+ public void testHistoryOfImage() {
+ assert getAuditReader().find(WikiImage.class, imageId, 1) == null;
+ assert getAuditReader().find(WikiImage.class, imageId, 2).equals(new WikiImage("name1"));
+ assert getAuditReader().find(WikiImage.class, imageId, 3).equals(new WikiImage("name2"));
+ }
+
+ @Test
+ public void testHistoryOfPage() {
+ assert getAuditReader().find(WikiPage.class, pageId, 1).getImages().size() == 0;
+ assert getAuditReader().find(WikiPage.class, pageId, 2).getImages().equals(TestTools.makeSet(new WikiImage("name1")));
+ assert getAuditReader().find(WikiPage.class, pageId, 3).getImages().equals(TestTools.makeSet(new WikiImage("name2")));
+ }
+}
\ No newline at end of file
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,65 +0,0 @@
-package org.hibernate.envers.test.integration.hashcode;
-
-import org.hibernate.envers.Audited;
-
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Entity;
-import javax.persistence.Basic;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-@Entity
-@Audited
-public class WikiImage {
- @Id
- @GeneratedValue
- private Long id;
-
- @Basic
- private String name;
-
- public WikiImage() {
- }
-
- public WikiImage(String name) {
- this.name = name;
- }
-
- public Long getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof WikiImage)) return false;
-
- WikiImage wikiImage = (WikiImage) o;
-
- if (name != null ? !name.equals(wikiImage.name) : wikiImage.name != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return name != null ? name.hashCode() : 0;
- }
-
- @Override
- public String toString() {
- return "WikiImage{" +
- "name='" + name + '\'' +
- '}';
- }
-}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiImage.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,65 @@
+package org.hibernate.envers.test.integration.hashcode;
+
+import org.hibernate.envers.Audited;
+
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Entity;
+import javax.persistence.Basic;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class WikiImage {
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ @Basic
+ private String name;
+
+ public WikiImage() {
+ }
+
+ public WikiImage(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof WikiImage)) return false;
+
+ WikiImage wikiImage = (WikiImage) o;
+
+ if (name != null ? !name.equals(wikiImage.name) : wikiImage.name != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return name != null ? name.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return "WikiImage{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+}
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,109 +0,0 @@
-package org.hibernate.envers.test.integration.hashcode;
-
-import org.hibernate.annotations.CollectionOfElements;
-import org.hibernate.envers.Audited;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.Basic;
-import java.util.Set;
-import java.util.HashSet;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-@Entity
-@Audited
-public class WikiPage {
- @Id
- @GeneratedValue
- private Long id;
-
- @Basic
- private String title;
-
- @Basic
- private String content;
-
- @CollectionOfElements
- private Set<String> links = new HashSet<String>();
-
- @OneToMany
- private Set<WikiImage> images = new HashSet<WikiImage>();
-
- public WikiPage() {
- }
-
- public WikiPage(String title, String content) {
- this.title = title;
- this.content = content;
- }
-
- public Long getId() {
- return id;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
-
- public Set<String> getLinks() {
- return links;
- }
-
- public void setLinks(Set<String> links) {
- this.links = links;
- }
-
- public Set<WikiImage> getImages() {
- return images;
- }
-
- public void setImages(Set<WikiImage> images) {
- this.images = images;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof WikiPage)) return false;
-
- WikiPage wikiPage = (WikiPage) o;
-
- if (content != null ? !content.equals(wikiPage.content) : wikiPage.content != null) return false;
- if (title != null ? !title.equals(wikiPage.title) : wikiPage.title != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = title != null ? title.hashCode() : 0;
- result = 31 * result + (content != null ? content.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "WikiPage{" +
- "title='" + title + '\'' +
- ", content='" + content + '\'' +
- ", links=" + links +
- ", images=" + images +
- '}';
- }
-}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/hashcode/WikiPage.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,109 @@
+package org.hibernate.envers.test.integration.hashcode;
+
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.envers.Audited;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Basic;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class WikiPage {
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ @Basic
+ private String title;
+
+ @Basic
+ private String content;
+
+ @CollectionOfElements
+ private Set<String> links = new HashSet<String>();
+
+ @OneToMany
+ private Set<WikiImage> images = new HashSet<WikiImage>();
+
+ public WikiPage() {
+ }
+
+ public WikiPage(String title, String content) {
+ this.title = title;
+ this.content = content;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public Set<String> getLinks() {
+ return links;
+ }
+
+ public void setLinks(Set<String> links) {
+ this.links = links;
+ }
+
+ public Set<WikiImage> getImages() {
+ return images;
+ }
+
+ public void setImages(Set<WikiImage> images) {
+ this.images = images;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof WikiPage)) return false;
+
+ WikiPage wikiPage = (WikiPage) o;
+
+ if (content != null ? !content.equals(wikiPage.content) : wikiPage.content != null) return false;
+ if (title != null ? !title.equals(wikiPage.title) : wikiPage.title != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = title != null ? title.hashCode() : 0;
+ result = 31 * result + (content != null ? content.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "WikiPage{" +
+ "title='" + title + '\'' +
+ ", content='" + content + '\'' +
+ ", links=" + links +
+ ", images=" + images +
+ '}';
+ }
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces)
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components)
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,73 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.interfaces.components;
-
-import javax.persistence.Embeddable;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-@Embeddable
-public class Component1 implements IComponent {
- private String data;
-
- public Component1(String data) {
- this.data = data;
- }
-
- public Component1() {
- }
-
- public String getData() {
- return data;
- }
-
- public void setData(String data) {
- this.data = data;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof Component1)) return false;
-
- Component1 that = (Component1) o;
-
- if (data != null ? !data.equals(that.data) : that.data != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return data != null ? data.hashCode() : 0;
- }
-
- @Override
- public String toString() {
- return "Component1{" +
- "data='" + data + '\'' +
- '}';
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,73 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.components;
+
+import javax.persistence.Embeddable;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Embeddable
+public class Component1 implements IComponent {
+ private String data;
+
+ public Component1(String data) {
+ this.data = data;
+ }
+
+ public Component1() {
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Component1)) return false;
+
+ Component1 that = (Component1) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return data != null ? data.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return "Component1{" +
+ "data='" + data + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,102 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.interfaces.components;
-
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-import org.hibernate.envers.Audited;
-import org.hibernate.annotations.Target;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-@Entity
- @Audited
-public class ComponentTestEntity {
- @Id
- @GeneratedValue
- private Integer id;
-
- @Embedded
- @Target(Component1.class)
- private IComponent comp1;
-
- public ComponentTestEntity() {
- }
-
- public ComponentTestEntity(IComponent comp1) {
- this.comp1 = comp1;
- }
-
- public ComponentTestEntity(Integer id, IComponent comp1) {
- this.id = id;
- this.comp1 = comp1;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public IComponent getComp1() {
- return comp1;
- }
-
- public void setComp1(IComponent comp1) {
- this.comp1 = comp1;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof ComponentTestEntity)) return false;
-
- ComponentTestEntity that = (ComponentTestEntity) o;
-
- if (comp1 != null ? !comp1.equals(that.comp1) : that.comp1 != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = id != null ? id.hashCode() : 0;
- result = 31 * result + (comp1 != null ? comp1.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "ComponentTestEntity{" +
- "id=" + id +
- ", comp1=" + comp1 +
- '}';
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,102 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.components;
+
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+import org.hibernate.annotations.Target;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+ @Audited
+public class ComponentTestEntity {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Embedded
+ @Target(Component1.class)
+ private IComponent comp1;
+
+ public ComponentTestEntity() {
+ }
+
+ public ComponentTestEntity(IComponent comp1) {
+ this.comp1 = comp1;
+ }
+
+ public ComponentTestEntity(Integer id, IComponent comp1) {
+ this.id = id;
+ this.comp1 = comp1;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public IComponent getComp1() {
+ return comp1;
+ }
+
+ public void setComp1(IComponent comp1) {
+ this.comp1 = comp1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ComponentTestEntity)) return false;
+
+ ComponentTestEntity that = (ComponentTestEntity) o;
+
+ if (comp1 != null ? !comp1.equals(that.comp1) : that.comp1 != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id != null ? id.hashCode() : 0;
+ result = 31 * result + (comp1 != null ? comp1.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentTestEntity{" +
+ "id=" + id +
+ ", comp1=" + comp1 +
+ '}';
+ }
+}
\ No newline at end of file
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,9 +0,0 @@
-package org.hibernate.envers.test.integration.interfaces.components;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public interface IComponent {
- String getData();
- void setData(String data);
-}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,9 @@
+package org.hibernate.envers.test.integration.interfaces.components;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public interface IComponent {
+ String getData();
+ void setData(String data);
+}
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,95 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.interfaces.components;
-
-import java.util.Arrays;
-import javax.persistence.EntityManager;
-
-import org.hibernate.envers.test.AbstractEntityTest;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.hibernate.ejb.Ejb3Configuration;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public class InterfacesComponents extends AbstractEntityTest {
- private Integer id1;
-
- public void configure(Ejb3Configuration cfg) {
- cfg.addAnnotatedClass(ComponentTestEntity.class);
- }
-
- @BeforeClass(dependsOnMethods = "init")
- public void initData() {
- // Revision 1
- EntityManager em = getEntityManager();
- em.getTransaction().begin();
-
- ComponentTestEntity cte1 = new ComponentTestEntity(new Component1("a"));
-
- em.persist(cte1);
-
- em.getTransaction().commit();
-
- // Revision 2
- em = getEntityManager();
- em.getTransaction().begin();
-
- cte1 = em.find(ComponentTestEntity.class, cte1.getId());
-
- cte1.setComp1(new Component1("b"));
-
- em.getTransaction().commit();
-
- // Revision 3
- em = getEntityManager();
- em.getTransaction().begin();
-
- cte1 = em.find(ComponentTestEntity.class, cte1.getId());
-
- cte1.getComp1().setData("c");
-
- em.getTransaction().commit();
-
- id1 = cte1.getId();
- }
-
- @Test
- public void testRevisionsCounts() {
- assert Arrays.asList(1, 2, 3).equals(getAuditReader().getRevisions(ComponentTestEntity.class, id1));
- }
-
- @Test
- public void testHistoryOfId1() {
- ComponentTestEntity ver1 = new ComponentTestEntity(id1, new Component1("a"));
- ComponentTestEntity ver2 = new ComponentTestEntity(id1, new Component1("b"));
- ComponentTestEntity ver3 = new ComponentTestEntity(id1, new Component1("c"));
-
- assert getAuditReader().find(ComponentTestEntity.class, id1, 1).equals(ver1);
- assert getAuditReader().find(ComponentTestEntity.class, id1, 2).equals(ver2);
- assert getAuditReader().find(ComponentTestEntity.class, id1, 3).equals(ver3);
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,95 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.components;
+
+import java.util.Arrays;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class InterfacesComponents extends AbstractEntityTest {
+ private Integer id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(ComponentTestEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ ComponentTestEntity cte1 = new ComponentTestEntity(new Component1("a"));
+
+ em.persist(cte1);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ cte1 = em.find(ComponentTestEntity.class, cte1.getId());
+
+ cte1.setComp1(new Component1("b"));
+
+ em.getTransaction().commit();
+
+ // Revision 3
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ cte1 = em.find(ComponentTestEntity.class, cte1.getId());
+
+ cte1.getComp1().setData("c");
+
+ em.getTransaction().commit();
+
+ id1 = cte1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2, 3).equals(getAuditReader().getRevisions(ComponentTestEntity.class, id1));
+ }
+
+ @Test
+ public void testHistoryOfId1() {
+ ComponentTestEntity ver1 = new ComponentTestEntity(id1, new Component1("a"));
+ ComponentTestEntity ver2 = new ComponentTestEntity(id1, new Component1("b"));
+ ComponentTestEntity ver3 = new ComponentTestEntity(id1, new Component1("c"));
+
+ assert getAuditReader().find(ComponentTestEntity.class, id1, 1).equals(ver1);
+ assert getAuditReader().find(ComponentTestEntity.class, id1, 2).equals(ver2);
+ assert getAuditReader().find(ComponentTestEntity.class, id1, 3).equals(ver3);
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation)
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,14 +0,0 @@
-package org.hibernate.envers.test.integration.interfaces.relation;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public interface ISetRefEdEntity {
- Integer getId();
-
- void setId(Integer id);
-
- String getData();
-
- void setData(String data);
-}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,14 @@
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public interface ISetRefEdEntity {
+ Integer getId();
+
+ void setId(Integer id);
+
+ String getData();
+
+ void setData(String data);
+}
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,116 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.interfaces.relation;
-
-import java.util.Arrays;
-import javax.persistence.EntityManager;
-
-import org.hibernate.envers.test.AbstractEntityTest;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.hibernate.ejb.Ejb3Configuration;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public class InterfacesRelation extends AbstractEntityTest {
- private Integer ed1_id;
- private Integer ed2_id;
-
- private Integer ing1_id;
-
- public void configure(Ejb3Configuration cfg) {
- cfg.addAnnotatedClass(SetRefEdEntity.class);
- cfg.addAnnotatedClass(SetRefIngEntity.class);
- }
-
- @BeforeClass(dependsOnMethods = "init")
- public void initData() {
- EntityManager em = getEntityManager();
-
- SetRefEdEntity ed1 = new SetRefEdEntity(1, "data_ed_1");
- SetRefEdEntity ed2 = new SetRefEdEntity(2, "data_ed_2");
-
- SetRefIngEntity ing1 = new SetRefIngEntity(3, "data_ing_1");
-
- // Revision 1
- em.getTransaction().begin();
-
- em.persist(ed1);
- em.persist(ed2);
-
- em.getTransaction().commit();
-
- // Revision 2
-
- em.getTransaction().begin();
-
- ed1 = em.find(SetRefEdEntity.class, ed1.getId());
-
- ing1.setReference(ed1);
- em.persist(ing1);
-
- em.getTransaction().commit();
-
- // Revision 3
- em.getTransaction().begin();
-
- ing1 = em.find(SetRefIngEntity.class, ing1.getId());
- ed2 = em.find(SetRefEdEntity.class, ed2.getId());
-
- ing1.setReference(ed2);
-
- em.getTransaction().commit();
-
- //
-
- ed1_id = ed1.getId();
- ed2_id = ed2.getId();
-
- ing1_id = ing1.getId();
- }
-
- @Test
- public void testRevisionsCounts() {
- assert Arrays.asList(1).equals(getAuditReader().getRevisions(SetRefEdEntity.class, ed1_id));
- assert Arrays.asList(1).equals(getAuditReader().getRevisions(SetRefEdEntity.class, ed2_id));
-
- assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(SetRefIngEntity.class, ing1_id));
- }
-
- @Test
- public void testHistoryOfEdIng1() {
- SetRefEdEntity ed1 = getEntityManager().find(SetRefEdEntity.class, ed1_id);
- SetRefEdEntity ed2 = getEntityManager().find(SetRefEdEntity.class, ed2_id);
-
- SetRefIngEntity rev1 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 1);
- SetRefIngEntity rev2 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 2);
- SetRefIngEntity rev3 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 3);
-
- assert rev1 == null;
- assert rev2.getReference().equals(ed1);
- assert rev3.getReference().equals(ed2);
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,116 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+import java.util.Arrays;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class InterfacesRelation extends AbstractEntityTest {
+ private Integer ed1_id;
+ private Integer ed2_id;
+
+ private Integer ing1_id;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(SetRefEdEntity.class);
+ cfg.addAnnotatedClass(SetRefIngEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ EntityManager em = getEntityManager();
+
+ SetRefEdEntity ed1 = new SetRefEdEntity(1, "data_ed_1");
+ SetRefEdEntity ed2 = new SetRefEdEntity(2, "data_ed_2");
+
+ SetRefIngEntity ing1 = new SetRefIngEntity(3, "data_ing_1");
+
+ // Revision 1
+ em.getTransaction().begin();
+
+ em.persist(ed1);
+ em.persist(ed2);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+
+ em.getTransaction().begin();
+
+ ed1 = em.find(SetRefEdEntity.class, ed1.getId());
+
+ ing1.setReference(ed1);
+ em.persist(ing1);
+
+ em.getTransaction().commit();
+
+ // Revision 3
+ em.getTransaction().begin();
+
+ ing1 = em.find(SetRefIngEntity.class, ing1.getId());
+ ed2 = em.find(SetRefEdEntity.class, ed2.getId());
+
+ ing1.setReference(ed2);
+
+ em.getTransaction().commit();
+
+ //
+
+ ed1_id = ed1.getId();
+ ed2_id = ed2.getId();
+
+ ing1_id = ing1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1).equals(getAuditReader().getRevisions(SetRefEdEntity.class, ed1_id));
+ assert Arrays.asList(1).equals(getAuditReader().getRevisions(SetRefEdEntity.class, ed2_id));
+
+ assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(SetRefIngEntity.class, ing1_id));
+ }
+
+ @Test
+ public void testHistoryOfEdIng1() {
+ SetRefEdEntity ed1 = getEntityManager().find(SetRefEdEntity.class, ed1_id);
+ SetRefEdEntity ed2 = getEntityManager().find(SetRefEdEntity.class, ed2_id);
+
+ SetRefIngEntity rev1 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 1);
+ SetRefIngEntity rev2 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 2);
+ SetRefIngEntity rev3 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 3);
+
+ assert rev1 == null;
+ assert rev2.getReference().equals(ed1);
+ assert rev3.getReference().equals(ed2);
+ }
+}
\ No newline at end of file
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,93 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.interfaces.relation;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.hibernate.envers.Audited;
-
-/**
- * ReferencEd entity
- * @author Adam Warski (adam at warski dot org)
- */
-@Entity
-@Audited
-public class SetRefEdEntity implements ISetRefEdEntity {
- @Id
- private Integer id;
-
- private String data;
-
- public SetRefEdEntity() {
- }
-
- public SetRefEdEntity(Integer id, String data) {
- this.id = id;
- this.data = data;
- }
-
- public SetRefEdEntity(String data) {
- this.data = data;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getData() {
- return data;
- }
-
- public void setData(String data) {
- this.data = data;
- }
-
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof SetRefEdEntity)) return false;
-
- SetRefEdEntity that = (SetRefEdEntity) o;
-
- if (data != null ? !data.equals(that.data) : that.data != null) return false;
- if (id != null ? !id.equals(that.id) : that.id != null) return false;
-
- return true;
- }
-
- public int hashCode() {
- int result;
- result = (id != null ? id.hashCode() : 0);
- result = 31 * result + (data != null ? data.hashCode() : 0);
- return result;
- }
-
- public String toString() {
- return "SetRefEdEntity(id = " + id + ", data = " + data + ")";
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,93 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+
+/**
+ * ReferencEd entity
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class SetRefEdEntity implements ISetRefEdEntity {
+ @Id
+ private Integer id;
+
+ private String data;
+
+ public SetRefEdEntity() {
+ }
+
+ public SetRefEdEntity(Integer id, String data) {
+ this.id = id;
+ this.data = data;
+ }
+
+ public SetRefEdEntity(String data) {
+ this.data = data;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SetRefEdEntity)) return false;
+
+ SetRefEdEntity that = (SetRefEdEntity) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "SetRefEdEntity(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -1,112 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.interfaces.relation;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-
-import org.hibernate.envers.Audited;
-
-/**
- * ReferencIng entity
- * @author Adam Warski (adam at warski dot org)
- */
-@Entity
-public class SetRefIngEntity {
- @Id
- private Integer id;
-
- @Audited
- private String data;
-
- @Audited
- @ManyToOne(targetEntity = SetRefEdEntity.class)
- private ISetRefEdEntity reference;
-
- public SetRefIngEntity() { }
-
- public SetRefIngEntity(Integer id, String data, ISetRefEdEntity reference) {
- this.id = id;
- this.data = data;
- this.reference = reference;
- }
-
- public SetRefIngEntity(String data, ISetRefEdEntity reference) {
- this.data = data;
- this.reference = reference;
- }
-
- public SetRefIngEntity(Integer id, String data) {
- this.id = id;
- this.data = data;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getData() {
- return data;
- }
-
- public void setData(String data) {
- this.data = data;
- }
-
- public ISetRefEdEntity getReference() {
- return reference;
- }
-
- public void setReference(ISetRefEdEntity reference) {
- this.reference = reference;
- }
-
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof SetRefIngEntity)) return false;
-
- SetRefIngEntity that = (SetRefIngEntity) o;
-
- if (data != null ? !data.equals(that.data) : that.data != null) return false;
- if (id != null ? !id.equals(that.id) : that.id != null) return false;
-
- return true;
- }
-
- public int hashCode() {
- int result;
- result = (id != null ? id.hashCode() : 0);
- result = 31 * result + (data != null ? data.hashCode() : 0);
- return result;
- }
-
- public String toString() {
- return "SetRefIngEntity(id = " + id + ", data = " + data + ")";
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java (from rev 16062, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java 2009-03-03 16:54:21 UTC (rev 16063)
@@ -0,0 +1,112 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+import org.hibernate.envers.Audited;
+
+/**
+ * ReferencIng entity
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+public class SetRefIngEntity {
+ @Id
+ private Integer id;
+
+ @Audited
+ private String data;
+
+ @Audited
+ @ManyToOne(targetEntity = SetRefEdEntity.class)
+ private ISetRefEdEntity reference;
+
+ public SetRefIngEntity() { }
+
+ public SetRefIngEntity(Integer id, String data, ISetRefEdEntity reference) {
+ this.id = id;
+ this.data = data;
+ this.reference = reference;
+ }
+
+ public SetRefIngEntity(String data, ISetRefEdEntity reference) {
+ this.data = data;
+ this.reference = reference;
+ }
+
+ public SetRefIngEntity(Integer id, String data) {
+ this.id = id;
+ this.data = data;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public ISetRefEdEntity getReference() {
+ return reference;
+ }
+
+ public void setReference(ISetRefEdEntity reference) {
+ this.reference = reference;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SetRefIngEntity)) return false;
+
+ SetRefIngEntity that = (SetRefIngEntity) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "SetRefIngEntity(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
Modified: core/branches/envers-hibernate-3.3/src/test/resources/testng.xml
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/resources/testng.xml 2009-03-03 16:10:51 UTC (rev 16062)
+++ core/branches/envers-hibernate-3.3/src/test/resources/testng.xml 2009-03-03 16:54:21 UTC (rev 16063)
@@ -28,6 +28,8 @@
<package name="org.hibernate.envers.test.integration.inheritance.tableperclass.childrelation" />
<package name="org.hibernate.envers.test.integration.inheritance.tableperclass.notownedrelation" />
<package name="org.hibernate.envers.test.integration.inheritance.tableperclass.relation" />
+ <package name="org.hibernate.envers.test.integration.interfaces.components" />
+ <package name="org.hibernate.envers.test.integration.interfaces.relation" />
<package name="org.hibernate.envers.test.integration.manytomany" />
<package name="org.hibernate.envers.test.integration.manytomany.ternary" />
<package name="org.hibernate.envers.test.integration.manytomany.unidirectional" />
15 years, 10 months
Hibernate SVN: r16062 - in core/trunk/envers/src: main/java/org/hibernate/envers/configuration/metadata/reader and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-03-03 11:10:51 -0500 (Tue, 03 Mar 2009)
New Revision: 16062
Added:
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
core/trunk/envers/src/test/resources/testng.xml
Log:
HHH-3794:
- fixing interfaces of components support
- tests for interfaces in components and to-one relations
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -27,7 +27,8 @@
EntityXmlMappingData xmlMappingData, boolean firstPass) {
Component prop_component = (Component) value;
- CompositeMapperBuilder componentMapper = mapper.addComponent(propertyAuditingData.getPropertyData());
+ CompositeMapperBuilder componentMapper = mapper.addComponent(propertyAuditingData.getPropertyData(),
+ prop_component.getComponentClassName());
// The property auditing data must be for a component.
ComponentAuditingData componentAuditingData = (ComponentAuditingData) propertyAuditingData;
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -118,7 +118,7 @@
}
new AuditedPropertiesReader(defaultStore, new PersistentClassPropertiesSource(xclass), auditData,
- globalCfg, "").read();
+ globalCfg, reflectionManager, "").read();
addAuditTable(xclass);
addAuditSecondaryTables(xclass);
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -13,6 +13,7 @@
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.AuditOverrides;
@@ -24,6 +25,7 @@
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
+import org.hibernate.MappingException;
import org.jboss.envers.Versioned;
/**
@@ -40,6 +42,7 @@
private final PersistentPropertiesSource persistentPropertiesSource;
private final AuditedPropertiesHolder auditedPropertiesHolder;
private final GlobalConfiguration globalCfg;
+ private final ReflectionManager reflectionManager;
private final String propertyNamePrefix;
private final Set<String> propertyAccessedPersistentProperties;
@@ -49,11 +52,13 @@
PersistentPropertiesSource persistentPropertiesSource,
AuditedPropertiesHolder auditedPropertiesHolder,
GlobalConfiguration globalCfg,
+ ReflectionManager reflectionManager,
String propertyNamePrefix) {
this.defaultStore = defaultStore;
this.persistentPropertiesSource = persistentPropertiesSource;
this.auditedPropertiesHolder = auditedPropertiesHolder;
this.globalCfg = globalCfg;
+ this.reflectionManager = reflectionManager;
this.propertyNamePrefix = propertyNamePrefix;
propertyAccessedPersistentProperties = newHashSet();
@@ -104,9 +109,10 @@
isAudited = fillPropertyData(property, componentData, accessType);
PersistentPropertiesSource componentPropertiesSource = new ComponentPropertiesSource(
- property.getType(), (Component) propertyValue);
+ (Component) propertyValue);
new AuditedPropertiesReader(ModificationStore.FULL, componentPropertiesSource, componentData,
- globalCfg, propertyNamePrefix+ MappingTools.createComponentPrefix(property.getName()))
+ globalCfg, reflectionManager,
+ propertyNamePrefix + MappingTools.createComponentPrefix(property.getName()))
.read();
propertyData = componentData;
@@ -251,12 +257,17 @@
public Class<? extends Annotation> annotationType() { return this.getClass(); }
};
- private static class ComponentPropertiesSource implements PersistentPropertiesSource {
+ private class ComponentPropertiesSource implements PersistentPropertiesSource {
private final XClass xclass;
private final Component component;
- private ComponentPropertiesSource(XClass xclass, Component component) {
- this.xclass = xclass;
+ private ComponentPropertiesSource(Component component) {
+ try {
+ this.xclass = reflectionManager.classForName(component.getComponentClassName(), this.getClass());
+ } catch (ClassNotFoundException e) {
+ throw new MappingException(e);
+ }
+
this.component = component;
}
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -34,7 +34,6 @@
import org.hibernate.envers.tools.reflection.ReflectionTools;
import org.hibernate.collection.PersistentCollection;
-import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
import org.hibernate.util.ReflectHelper;
@@ -42,20 +41,22 @@
* @author Adam Warski (adam at warski dot org)
*/
public class ComponentPropertyMapper implements PropertyMapper, CompositeMapperBuilder {
- private PropertyData propertyData;
- private ExtendedPropertyMapper delegate;
+ private final PropertyData propertyData;
+ private final ExtendedPropertyMapper delegate;
+ private final String componentClassName;
- public ComponentPropertyMapper(PropertyData propertyData) {
+ public ComponentPropertyMapper(PropertyData propertyData, String componentClassName) {
this.propertyData = propertyData;
this.delegate = new MultiPropertyMapper();
+ this.componentClassName = componentClassName;
}
public void add(PropertyData propertyData) {
delegate.add(propertyData);
}
- public CompositeMapperBuilder addComponent(PropertyData propertyData) {
- return delegate.addComponent(propertyData);
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) {
+ return delegate.addComponent(propertyData, componentClassName);
}
public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) {
@@ -71,11 +72,11 @@
return;
}
- Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyData);
Setter setter = ReflectionTools.getSetter(obj.getClass(), propertyData);
try {
- Object subObj = ReflectHelper.getDefaultConstructor(getter.getReturnType()).newInstance();
+ Object subObj = ReflectHelper.getDefaultConstructor(
+ Thread.currentThread().getContextClassLoader().loadClass(componentClassName)).newInstance();
setter.set(obj, subObj, null);
delegate.mapToEntityFromMap(verCfg, subObj, data, primaryKey, versionsReader, revision);
} catch (Exception e) {
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -29,6 +29,6 @@
* @author Adam Warski (adam at warski dot org)
*/
public interface CompositeMapperBuilder extends SimpleMapperBuilder {
- public CompositeMapperBuilder addComponent(PropertyData propertyData);
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName);
public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper);
}
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -56,13 +56,13 @@
propertyDatas.put(propertyData.getName(), propertyData);
}
- public CompositeMapperBuilder addComponent(PropertyData propertyData) {
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) {
if (properties.get(propertyData) != null) {
// This is needed for second pass to work properly in the components mapper
return (CompositeMapperBuilder) properties.get(propertyData);
}
- ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData);
+ ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData, componentClassName);
addComposite(propertyData, componentMapperBuilder);
return componentMapperBuilder;
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -86,8 +86,8 @@
}
}
- public CompositeMapperBuilder addComponent(PropertyData propertyData) {
- return main.addComponent(propertyData);
+ public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) {
+ return main.addComponent(propertyData, componentClassName);
}
public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) {
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java (from rev 16053, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/components/Component1.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/Component1.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,73 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.components;
+
+import javax.persistence.Embeddable;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Embeddable
+public class Component1 implements IComponent {
+ private String data;
+
+ public Component1(String data) {
+ this.data = data;
+ }
+
+ public Component1() {
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Component1)) return false;
+
+ Component1 that = (Component1) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return data != null ? data.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return "Component1{" +
+ "data='" + data + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java (from rev 16053, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/components/ComponentTestEntity.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/ComponentTestEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,102 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.components;
+
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+import org.hibernate.annotations.Target;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+ @Audited
+public class ComponentTestEntity {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Embedded
+ @Target(Component1.class)
+ private IComponent comp1;
+
+ public ComponentTestEntity() {
+ }
+
+ public ComponentTestEntity(IComponent comp1) {
+ this.comp1 = comp1;
+ }
+
+ public ComponentTestEntity(Integer id, IComponent comp1) {
+ this.id = id;
+ this.comp1 = comp1;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public IComponent getComp1() {
+ return comp1;
+ }
+
+ public void setComp1(IComponent comp1) {
+ this.comp1 = comp1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ComponentTestEntity)) return false;
+
+ ComponentTestEntity that = (ComponentTestEntity) o;
+
+ if (comp1 != null ? !comp1.equals(that.comp1) : that.comp1 != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id != null ? id.hashCode() : 0;
+ result = 31 * result + (comp1 != null ? comp1.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentTestEntity{" +
+ "id=" + id +
+ ", comp1=" + comp1 +
+ '}';
+ }
+}
\ No newline at end of file
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/IComponent.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,9 @@
+package org.hibernate.envers.test.integration.interfaces.components;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public interface IComponent {
+ String getData();
+ void setData(String data);
+}
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java (from rev 16053, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/components/Components.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/components/InterfacesComponents.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,95 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.components;
+
+import java.util.Arrays;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class InterfacesComponents extends AbstractEntityTest {
+ private Integer id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(ComponentTestEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ ComponentTestEntity cte1 = new ComponentTestEntity(new Component1("a"));
+
+ em.persist(cte1);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ cte1 = em.find(ComponentTestEntity.class, cte1.getId());
+
+ cte1.setComp1(new Component1("b"));
+
+ em.getTransaction().commit();
+
+ // Revision 3
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ cte1 = em.find(ComponentTestEntity.class, cte1.getId());
+
+ cte1.getComp1().setData("c");
+
+ em.getTransaction().commit();
+
+ id1 = cte1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2, 3).equals(getAuditReader().getRevisions(ComponentTestEntity.class, id1));
+ }
+
+ @Test
+ public void testHistoryOfId1() {
+ ComponentTestEntity ver1 = new ComponentTestEntity(id1, new Component1("a"));
+ ComponentTestEntity ver2 = new ComponentTestEntity(id1, new Component1("b"));
+ ComponentTestEntity ver3 = new ComponentTestEntity(id1, new Component1("c"));
+
+ assert getAuditReader().find(ComponentTestEntity.class, id1, 1).equals(ver1);
+ assert getAuditReader().find(ComponentTestEntity.class, id1, 2).equals(ver2);
+ assert getAuditReader().find(ComponentTestEntity.class, id1, 3).equals(ver3);
+ }
+}
\ No newline at end of file
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/ISetRefEdEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,14 @@
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public interface ISetRefEdEntity {
+ Integer getId();
+
+ void setId(Integer id);
+
+ String getData();
+
+ void setData(String data);
+}
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java (from rev 16053, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/onetomany/BasicSet.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/InterfacesRelation.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,116 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+import java.util.Arrays;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class InterfacesRelation extends AbstractEntityTest {
+ private Integer ed1_id;
+ private Integer ed2_id;
+
+ private Integer ing1_id;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(SetRefEdEntity.class);
+ cfg.addAnnotatedClass(SetRefIngEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ EntityManager em = getEntityManager();
+
+ SetRefEdEntity ed1 = new SetRefEdEntity(1, "data_ed_1");
+ SetRefEdEntity ed2 = new SetRefEdEntity(2, "data_ed_2");
+
+ SetRefIngEntity ing1 = new SetRefIngEntity(3, "data_ing_1");
+
+ // Revision 1
+ em.getTransaction().begin();
+
+ em.persist(ed1);
+ em.persist(ed2);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+
+ em.getTransaction().begin();
+
+ ed1 = em.find(SetRefEdEntity.class, ed1.getId());
+
+ ing1.setReference(ed1);
+ em.persist(ing1);
+
+ em.getTransaction().commit();
+
+ // Revision 3
+ em.getTransaction().begin();
+
+ ing1 = em.find(SetRefIngEntity.class, ing1.getId());
+ ed2 = em.find(SetRefEdEntity.class, ed2.getId());
+
+ ing1.setReference(ed2);
+
+ em.getTransaction().commit();
+
+ //
+
+ ed1_id = ed1.getId();
+ ed2_id = ed2.getId();
+
+ ing1_id = ing1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1).equals(getAuditReader().getRevisions(SetRefEdEntity.class, ed1_id));
+ assert Arrays.asList(1).equals(getAuditReader().getRevisions(SetRefEdEntity.class, ed2_id));
+
+ assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(SetRefIngEntity.class, ing1_id));
+ }
+
+ @Test
+ public void testHistoryOfEdIng1() {
+ SetRefEdEntity ed1 = getEntityManager().find(SetRefEdEntity.class, ed1_id);
+ SetRefEdEntity ed2 = getEntityManager().find(SetRefEdEntity.class, ed2_id);
+
+ SetRefIngEntity rev1 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 1);
+ SetRefIngEntity rev2 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 2);
+ SetRefIngEntity rev3 = getAuditReader().find(SetRefIngEntity.class, ing1_id, 3);
+
+ assert rev1 == null;
+ assert rev2.getReference().equals(ed1);
+ assert rev3.getReference().equals(ed2);
+ }
+}
\ No newline at end of file
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java (from rev 16053, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/SetRefEdEntity.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefEdEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,93 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+
+/**
+ * ReferencEd entity
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class SetRefEdEntity implements ISetRefEdEntity {
+ @Id
+ private Integer id;
+
+ private String data;
+
+ public SetRefEdEntity() {
+ }
+
+ public SetRefEdEntity(Integer id, String data) {
+ this.id = id;
+ this.data = data;
+ }
+
+ public SetRefEdEntity(String data) {
+ this.data = data;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SetRefEdEntity)) return false;
+
+ SetRefEdEntity that = (SetRefEdEntity) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "SetRefEdEntity(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java (from rev 16053, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/SetRefIngEntity.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/interfaces/relation/SetRefIngEntity.java 2009-03-03 16:10:51 UTC (rev 16062)
@@ -0,0 +1,112 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.interfaces.relation;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+import org.hibernate.envers.Audited;
+
+/**
+ * ReferencIng entity
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+public class SetRefIngEntity {
+ @Id
+ private Integer id;
+
+ @Audited
+ private String data;
+
+ @Audited
+ @ManyToOne(targetEntity = SetRefEdEntity.class)
+ private ISetRefEdEntity reference;
+
+ public SetRefIngEntity() { }
+
+ public SetRefIngEntity(Integer id, String data, ISetRefEdEntity reference) {
+ this.id = id;
+ this.data = data;
+ this.reference = reference;
+ }
+
+ public SetRefIngEntity(String data, ISetRefEdEntity reference) {
+ this.data = data;
+ this.reference = reference;
+ }
+
+ public SetRefIngEntity(Integer id, String data) {
+ this.id = id;
+ this.data = data;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public ISetRefEdEntity getReference() {
+ return reference;
+ }
+
+ public void setReference(ISetRefEdEntity reference) {
+ this.reference = reference;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SetRefIngEntity)) return false;
+
+ SetRefIngEntity that = (SetRefIngEntity) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "SetRefIngEntity(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
Modified: core/trunk/envers/src/test/resources/testng.xml
===================================================================
--- core/trunk/envers/src/test/resources/testng.xml 2009-03-03 14:29:04 UTC (rev 16061)
+++ core/trunk/envers/src/test/resources/testng.xml 2009-03-03 16:10:51 UTC (rev 16062)
@@ -28,6 +28,8 @@
<package name="org.hibernate.envers.test.integration.inheritance.tableperclass.childrelation" />
<package name="org.hibernate.envers.test.integration.inheritance.tableperclass.notownedrelation" />
<package name="org.hibernate.envers.test.integration.inheritance.tableperclass.relation" />
+ <package name="org.hibernate.envers.test.integration.interfaces.components" />
+ <package name="org.hibernate.envers.test.integration.interfaces.relation" />
<package name="org.hibernate.envers.test.integration.manytomany" />
<package name="org.hibernate.envers.test.integration.manytomany.ternary" />
<package name="org.hibernate.envers.test.integration.manytomany.unidirectional" />
15 years, 10 months