X-Git-Url: https://juplo.de/gitweb/?p=website;a=blobdiff_plain;f=dist%2Fhibernate4-maven-plugin-1.0.1%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.html;fp=dist%2Fhibernate4-maven-plugin-1.0.1%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.html;h=6ebc04279ae59f57ab59b4fb78545cdf8359c9b2;hp=0000000000000000000000000000000000000000;hb=a53595184bd6e57bdc45292cc92c393c4e2dfe6e;hpb=c48c9ee0e9faa89a4c0a5323b367b9f5a6abe602 diff --git a/dist/hibernate4-maven-plugin-1.0.1/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html b/dist/hibernate4-maven-plugin-1.0.1/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html new file mode 100644 index 00000000..6ebc0427 --- /dev/null +++ b/dist/hibernate4-maven-plugin-1.0.1/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html @@ -0,0 +1,784 @@ + + +
+ ++ +1 package de.juplo.plugins.hibernate4; +2 +3 /* +4 * Copyright 2001-2005 The Apache Software Foundation. +5 * +6 * Licensed under the Apache License, Version 2.0 (the "License"); +7 * you may not use this file except in compliance with the License. +8 * You may obtain a copy of the License at +9 * +10 * http://www.apache.org/licenses/LICENSE-2.0 +11 * +12 * Unless required by applicable law or agreed to in writing, software +13 * distributed under the License is distributed on an "AS IS" BASIS, +14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +15 * See the License for the specific language governing permissions and +16 * limitations under the License. +17 */ +18 +19 import com.pyx4j.log4j.MavenLogAppender; +20 import java.io.File; +21 import java.io.FileInputStream; +22 import java.io.FileOutputStream; +23 import java.io.IOException; +24 import java.io.InputStream; +25 import java.io.ObjectInputStream; +26 import java.io.ObjectOutputStream; +27 import java.math.BigInteger; +28 import java.net.URL; +29 import java.net.URLClassLoader; +30 import java.security.MessageDigest; +31 import java.sql.Connection; +32 import java.sql.Driver; +33 import java.sql.DriverManager; +34 import java.sql.DriverPropertyInfo; +35 import java.sql.SQLException; +36 import java.sql.SQLFeatureNotSupportedException; +37 import java.util.Comparator; +38 import java.util.Enumeration; +39 import java.util.HashMap; +40 import java.util.HashSet; +41 import java.util.List; +42 import java.util.Map; +43 import java.util.Map.Entry; +44 import java.util.Properties; +45 import java.util.Set; +46 import java.util.TreeSet; +47 import java.util.logging.Logger; +48 import javax.persistence.Embeddable; +49 import javax.persistence.Entity; +50 import javax.persistence.MappedSuperclass; +51 import org.apache.maven.plugin.AbstractMojo; +52 import org.apache.maven.plugin.MojoExecutionException; +53 import org.apache.maven.plugin.MojoFailureException; +54 import org.apache.maven.project.MavenProject; +55 import org.hibernate.cfg.Configuration; +56 import org.hibernate.tool.hbm2ddl.SchemaExport; +57 import org.hibernate.tool.hbm2ddl.SchemaExport.Type; +58 import org.hibernate.tool.hbm2ddl.Target; +59 import org.scannotation.AnnotationDB; +60 +61 +62 /** +63 * Goal which extracts the hibernate-mapping-configuration and +64 * exports an according SQL-database-schema. +65 * +66 * @goal export +67 * @phase process-classes +68 * @threadSafe +69 * @requiresDependencyResolution runtime +70 */ +71 public class Hbm2DdlMojo extends AbstractMojo +72 { +73 public final static String EXPORT_SKIPPED_PROPERTY = "hibernate.export.skipped"; +74 +75 public final static String DRIVER_CLASS = "hibernate.connection.driver_class"; +76 public final static String URL = "hibernate.connection.url"; +77 public final static String USERNAME = "hibernate.connection.username"; +78 public final static String PASSWORD = "hibernate.connection.password"; +79 public final static String DIALECT = "hibernate.dialect"; +80 +81 private final static String MD5S = "schema.md5s"; +82 +83 /** +84 * The maven project. +85 * <p> +86 * Only needed internally. +87 * +88 * @parameter expression="${project}" +89 * @required +90 * @readonly +91 */ +92 private MavenProject project; +93 +94 /** +95 * Build-directory. +96 * <p> +97 * Only needed internally. +98 * +99 * @parameter expression="${project.build.directory}" +100 * @required +101 * @readonly +102 */ +103 private String buildDirectory; +104 +105 /** +106 * Classes-Directory to scan. +107 * <p> +108 * This parameter defaults to the maven build-output-directory for classes. +109 * Additonally, all dependencies are scanned for annotated classes. +110 * +111 * @parameter expression="${project.build.outputDirectory}" +112 */ +113 private String outputDirectory; +114 +115 /** +116 * Wether to scan test-classes too, or not. +117 * <p> +118 * If this parameter is set to <code>true</code> the test-classes of the +119 * artifact will be scanned for hibernate-annotated classes additionally. +120 * +121 * @parameter expression="${hibernate.export.scann_testclasses}" default-value="false" +122 */ +123 private boolean scanTestClasses; +124 +125 /** +126 * Test-Classes-Directory to scan. +127 * <p> +128 * This parameter defaults to the maven build-output-directory for +129 * test-classes. +130 * <p> +131 * This parameter is only used, when <code>scanTestClasses</code> is set +132 * to <code>true</code>! +133 * +134 * @parameter expression="${project.build.testOutputDirectory}" +135 */ +136 private String testOutputDirectory; +137 +138 /** +139 * Skip execution +140 * <p> +141 * If set to <code>true</code>, the execution is skipped. +142 * <p> +143 * A skipped excecution is signaled via the maven-property +144 * <code>${hibernate.export.skipped}</code>. +145 * <p> +146 * The excecution is skipped automatically, if no modified or newly added +147 * annotated classes are found and the dialect was not changed. +148 * +149 * @parameter expression="${maven.test.skip}" default-value="false" +150 */ +151 private boolean skip; +152 +153 /** +154 * Force execution +155 * <p> +156 * Force execution, even if no modified or newly added annotated classes +157 * where found and the dialect was not changed. +158 * <p> +159 * <code>skip</code> takes precedence over <code>force</code>. +160 * +161 * @parameter expression="${hibernate.export.force}" default-value="false" +162 */ +163 private boolean force; +164 +165 /** +166 * SQL-Driver name. +167 * +168 * @parameter expression="${hibernate.connection.driver_class} +169 */ +170 private String driverClassName; +171 +172 /** +173 * Database URL. +174 * +175 * @parameter expression="${hibernate.connection.url}" +176 */ +177 private String url; +178 +179 /** +180 * Database username +181 * +182 * @parameter expression="${hibernate.connection.username}" +183 */ +184 private String username; +185 +186 /** +187 * Database password +188 * +189 * @parameter expression="${hibernate.connection.password}" +190 */ +191 private String password; +192 +193 /** +194 * Hibernate dialect. +195 * +196 * @parameter expression="${hibernate.dialect}" +197 */ +198 private String hibernateDialect; +199 +200 /** +201 * Path to Hibernate configuration file. +202 * +203 * @parameter default-value="${project.build.outputDirectory}/hibernate.properties" +204 */ +205 private String hibernateProperties; +206 +207 /** +208 * Target of execution: +209 * <ul> +210 * <li><strong>NONE</strong> do nothing - just validate the configuration (forces excecution, signals skip)</li> +211 * <li><strong>EXPORT</strong> create database (<strong>DEFAULT!</strong>. forces excecution, signals skip)</li> +212 * <li><strong>SCRIPT</strong> export schema to SQL-script</li> +213 * <li><strong>BOTH</strong></li> +214 * </ul> +215 * @parameter expression="${hibernate.export.target}" default-value="EXPORT" +216 */ +217 private String target; +218 +219 /** +220 * Type of execution. +221 * <ul> +222 * <li><strong>NONE</strong> do nothing - just validate the configuration</li> +223 * <li><strong>CREATE</strong> create database-schema</li> +224 * <li><strong>DROP</strong> drop database-schema</li> +225 * <li><strong>BOTH</strong> (<strong>DEFAULT!</strong>)</li> +226 * </ul> +227 * @parameter expression="${hibernate.export.type}" default-value="BOTH" +228 */ +229 private String type; +230 +231 /** +232 * Output file. +233 * +234 * @parameter expression="${hibernate.export.schema.filename}" default-value="${project.build.directory}/schema.sql" +235 */ +236 private String outputFile; +237 +238 /** +239 * Delimiter in output-file. +240 * +241 * @parameter expression="${hibernate.export.schema.delimiter}" default-value=";" +242 */ +243 private String delimiter; +244 +245 /** +246 * Format output-file. +247 * +248 * @parameter expression="${hibernate.export.schema.format}" default-value="true" +249 */ +250 private boolean format; +251 +252 +253 @Override +254 public void execute() +255 throws +256 MojoFailureException, +257 MojoExecutionException +258 { +259 if (skip) +260 { +261 getLog().info("Exectuion of hibernate4-maven-plugin:export was skipped!"); +262 project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); +263 return; +264 } +265 +266 File dir = new File(outputDirectory); +267 if (!dir.exists()) +268 throw new MojoExecutionException("Cannot scan for annotated classes in " + outputDirectory + ": directory does not exist!"); +269 +270 Map<String,String> md5s; +271 boolean modified = false; +272 File saved = new File(buildDirectory + File.separator + MD5S); +273 +274 if (saved.exists()) +275 { +276 try +277 { +278 FileInputStream fis = new FileInputStream(saved); +279 ObjectInputStream ois = new ObjectInputStream(fis); +280 md5s = (HashMap<String,String>)ois.readObject(); +281 ois.close(); +282 } +283 catch (Exception e) +284 { +285 md5s = new HashMap<String,String>(); +286 getLog().warn("Cannot read timestamps from saved: " + e); +287 } +288 } +289 else +290 { +291 md5s = new HashMap<String,String>(); +292 try +293 { +294 saved.createNewFile(); +295 } +296 catch (IOException e) +297 { +298 getLog().warn("Cannot create saved for timestamps: " + e); +299 } +300 } +301 +302 ClassLoader classLoader = null; +303 try +304 { +305 getLog().debug("Creating ClassLoader for project-dependencies..."); +306 List<String> classpathFiles = project.getCompileClasspathElements(); +307 if (scanTestClasses) +308 classpathFiles.addAll(project.getTestClasspathElements()); +309 URL[] urls = new URL[classpathFiles.size()]; +310 for (int i = 0; i < classpathFiles.size(); ++i) +311 { +312 getLog().debug("Dependency: " + classpathFiles.get(i)); +313 urls[i] = new File(classpathFiles.get(i)).toURI().toURL(); +314 } +315 classLoader = new URLClassLoader(urls, getClass().getClassLoader()); +316 } +317 catch (Exception e) +318 { +319 getLog().error("Error while creating ClassLoader!", e); +320 throw new MojoExecutionException(e.getMessage()); +321 } +322 +323 Set<Class<?>> classes = +324 new TreeSet<Class<?>>( +325 new Comparator<Class<?>>() { +326 @Override +327 public int compare(Class<?> a, Class<?> b) +328 { +329 return a.getName().compareTo(b.getName()); +330 } +331 } +332 ); +333 +334 try +335 { +336 AnnotationDB db = new AnnotationDB(); +337 getLog().info("Scanning directory " + outputDirectory + " for annotated classes..."); +338 URL dirUrl = dir.toURI().toURL(); +339 db.scanArchives(dirUrl); +340 if (scanTestClasses) +341 { +342 dir = new File(testOutputDirectory); +343 if (!dir.exists()) +344 throw new MojoExecutionException("Cannot scan for annotated test-classes in " + testOutputDirectory + ": directory does not exist!"); +345 getLog().info("Scanning directory " + testOutputDirectory + " for annotated classes..."); +346 dirUrl = dir.toURI().toURL(); +347 db.scanArchives(dirUrl); +348 } +349 +350 Set<String> classNames = new HashSet<String>(); +351 if (db.getAnnotationIndex().containsKey(Entity.class.getName())) +352 classNames.addAll(db.getAnnotationIndex().get(Entity.class.getName())); +353 if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName())) +354 classNames.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName())); +355 if (db.getAnnotationIndex().containsKey(Embeddable.class.getName())) +356 classNames.addAll(db.getAnnotationIndex().get(Embeddable.class.getName())); +357 +358 MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); +359 for (String name : classNames) +360 { +361 Class<?> annotatedClass = classLoader.loadClass(name); +362 classes.add(annotatedClass); +363 InputStream is = +364 annotatedClass +365 .getResourceAsStream(annotatedClass.getSimpleName() + ".class"); +366 byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks +367 int i; +368 while((i = is.read(buffer)) > -1) +369 digest.update(buffer, 0, i); +370 is.close(); +371 byte[] bytes = digest.digest(); +372 BigInteger bi = new BigInteger(1, bytes); +373 String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi); +374 String oldMd5 = !md5s.containsKey(name) ? "" : md5s.get(name); +375 if (!newMd5.equals(oldMd5)) +376 { +377 getLog().debug("Found new or modified annotated class: " + name); +378 modified = true; +379 md5s.put(name, newMd5); +380 } +381 else +382 { +383 getLog().debug(oldMd5 + " -> class unchanged: " + name); +384 } +385 } +386 } +387 catch (ClassNotFoundException e) +388 { +389 getLog().error("Error while adding annotated classes!", e); +390 throw new MojoExecutionException(e.getMessage()); +391 } +392 catch (Exception e) +393 { +394 getLog().error("Error while scanning!", e); +395 throw new MojoFailureException(e.getMessage()); +396 } +397 +398 if (classes.isEmpty()) +399 throw new MojoFailureException("No annotated classes found in directory " + outputDirectory); +400 +401 getLog().debug("Detected classes with mapping-annotations:"); +402 for (Class<?> annotatedClass : classes) +403 getLog().debug(" " + annotatedClass.getName()); +404 +405 +406 Properties properties = new Properties(); +407 +408 /** Try to read configuration from properties-file */ +409 try +410 { +411 File file = new File(hibernateProperties); +412 if (file.exists()) +413 { +414 getLog().info("Reading properties from file " + hibernateProperties + "..."); +415 properties.load(new FileInputStream(file)); +416 } +417 else +418 getLog().info("No hibernate-properties-file found! (Checked path: " + hibernateProperties + ")"); +419 } +420 catch (IOException e) +421 { +422 getLog().error("Error while reading properties!", e); +423 throw new MojoExecutionException(e.getMessage()); +424 } +425 +426 /** Overwrite values from propertie-file or set, if given */ +427 if (driverClassName != null) +428 { +429 if (properties.containsKey(DRIVER_CLASS)) +430 getLog().debug( +431 "Overwriting property " + +432 DRIVER_CLASS + "=" + properties.getProperty(DRIVER_CLASS) + +433 " with the value " + driverClassName +434 ); +435 else +436 getLog().debug("Using the value " + driverClassName); +437 properties.setProperty(DRIVER_CLASS, driverClassName); +438 } +439 if (url != null) +440 { +441 if (properties.containsKey(URL)) +442 getLog().debug( +443 "Overwriting property " + +444 URL + "=" + properties.getProperty(URL) + +445 " with the value " + url +446 ); +447 else +448 getLog().debug("Using the value " + url); +449 properties.setProperty(URL, url); +450 } +451 if (username != null) +452 { +453 if (properties.containsKey(USERNAME)) +454 getLog().debug( +455 "Overwriting property " + +456 USERNAME + "=" + properties.getProperty(USERNAME) + +457 " with the value " + username +458 ); +459 else +460 getLog().debug("Using the value " + username); +461 properties.setProperty(USERNAME, username); +462 } +463 if (password != null) +464 { +465 if (properties.containsKey(PASSWORD)) +466 getLog().debug( +467 "Overwriting property " + +468 PASSWORD + "=" + properties.getProperty(PASSWORD) + +469 " with the value " + password +470 ); +471 else +472 getLog().debug("Using the value " + password); +473 properties.setProperty(PASSWORD, password); +474 } +475 if (hibernateDialect != null) +476 { +477 if (properties.containsKey(DIALECT)) +478 getLog().debug( +479 "Overwriting property " + +480 DIALECT + "=" + properties.getProperty(DIALECT) + +481 " with the value " + hibernateDialect +482 ); +483 else +484 getLog().debug("Using the value " + hibernateDialect); +485 properties.setProperty(DIALECT, hibernateDialect); +486 } +487 +488 /** The generated SQL varies with the dialect! */ +489 if (md5s.containsKey(DIALECT)) +490 { +491 String dialect = properties.getProperty(DIALECT); +492 if (md5s.get(DIALECT).equals(dialect)) +493 getLog().debug("SQL-dialect unchanged."); +494 else +495 { +496 getLog().debug("SQL-dialect changed: " + dialect); +497 modified = true; +498 md5s.put(DIALECT, dialect); +499 } +500 } +501 else +502 { +503 modified = true; +504 md5s.put(DIALECT, properties.getProperty(DIALECT)); +505 } +506 +507 if (properties.isEmpty()) +508 { +509 getLog().error("No properties set!"); +510 throw new MojoFailureException("Hibernate-Configuration is missing!"); +511 } +512 +513 Configuration config = new Configuration(); +514 config.setProperties(properties); +515 getLog().debug("Adding annotated classes to hibernate-mapping-configuration..."); +516 for (Class<?> annotatedClass : classes) +517 { +518 getLog().debug("Class " + annotatedClass); +519 config.addAnnotatedClass(annotatedClass); +520 } +521 +522 Target target = null; +523 try +524 { +525 target = Target.valueOf(this.target.toUpperCase()); +526 } +527 catch (IllegalArgumentException e) +528 { +529 getLog().error("Invalid value for configuration-option \"target\": " + this.target); +530 getLog().error("Valid values are: NONE, SCRIPT, EXPORT, BOTH"); +531 throw new MojoExecutionException("Invalid value for configuration-option \"target\""); +532 } +533 Type type = null; +534 try +535 { +536 type = Type.valueOf(this.type.toUpperCase()); +537 } +538 catch (IllegalArgumentException e) +539 { +540 getLog().error("Invalid value for configuration-option \"type\": " + this.type); +541 getLog().error("Valid values are: NONE, CREATE, DROP, BOTH"); +542 throw new MojoExecutionException("Invalid value for configuration-option \"type\""); +543 } +544 +545 if (target.equals(Target.SCRIPT) || target.equals(Target.NONE)) +546 { +547 project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); +548 } +549 if ( +550 !modified +551 && !target.equals(Target.SCRIPT) +552 && !target.equals(Target.NONE) +553 && !force +554 ) +555 { +556 getLog().info("No modified annotated classes found and dialect unchanged."); +557 getLog().info("Skipping schema generation!"); +558 project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); +559 return; +560 } +561 +562 getLog().info("Gathered hibernate-configuration (turn on debugging for details):"); +563 for (Entry<Object,Object> entry : properties.entrySet()) +564 getLog().info(" " + entry.getKey() + " = " + entry.getValue()); +565 +566 Connection connection = null; +567 try +568 { +569 /** +570 * The connection must be established outside of hibernate, because +571 * hibernate does not use the context-classloader of the current +572 * thread and, hence, would not be able to resolve the driver-class! +573 */ +574 switch (target) +575 { +576 case EXPORT: +577 case BOTH: +578 switch (type) +579 { +580 case CREATE: +581 case DROP: +582 case BOTH: +583 Class driverClass = classLoader.loadClass(properties.getProperty(DRIVER_CLASS)); +584 getLog().debug("Registering JDBC-driver " + driverClass.getName()); +585 DriverManager.registerDriver(new DriverProxy((Driver)driverClass.newInstance())); +586 getLog().debug( +587 "Opening JDBC-connection to " +588 + properties.getProperty(URL) +589 + " as " +590 + properties.getProperty(USERNAME) +591 + " with password " +592 + properties.getProperty(PASSWORD) +593 ); +594 connection = DriverManager.getConnection( +595 properties.getProperty(URL), +596 properties.getProperty(USERNAME), +597 properties.getProperty(PASSWORD) +598 ); +599 } +600 } +601 } +602 catch (ClassNotFoundException e) +603 { +604 getLog().error("Dependency for driver-class " + properties.getProperty(DRIVER_CLASS) + " is missing!"); +605 throw new MojoExecutionException(e.getMessage()); +606 } +607 catch (Exception e) +608 { +609 getLog().error("Cannot establish connection to database!"); +610 Enumeration<Driver> drivers = DriverManager.getDrivers(); +611 if (!drivers.hasMoreElements()) +612 getLog().error("No drivers registered!"); +613 while (drivers.hasMoreElements()) +614 getLog().debug("Driver: " + drivers.nextElement()); +615 throw new MojoExecutionException(e.getMessage()); +616 } +617 +618 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); +619 MavenLogAppender.startPluginLog(this); +620 try +621 { +622 /** +623 * Change class-loader of current thread, so that hibernate can +624 * see all dependencies! +625 */ +626 Thread.currentThread().setContextClassLoader(classLoader); +627 +628 SchemaExport export = new SchemaExport(config, connection); +629 export.setOutputFile(outputFile); +630 export.setDelimiter(delimiter); +631 export.setFormat(format); +632 export.execute(target, type); +633 +634 for (Object exception : export.getExceptions()) +635 getLog().debug(exception.toString()); +636 } +637 finally +638 { +639 /** Stop Log-Capturing */ +640 MavenLogAppender.endPluginLog(this); +641 +642 /** Restore the old class-loader (TODO: is this really necessary?) */ +643 Thread.currentThread().setContextClassLoader(contextClassLoader); +644 +645 /** Close the connection */ +646 try +647 { +648 if (connection != null) +649 connection.close(); +650 } +651 catch (SQLException e) +652 { +653 getLog().error("Error while closing connection: " + e.getMessage()); +654 } +655 } +656 +657 /** Write md5-sums for annotated classes to file */ +658 try +659 { +660 FileOutputStream fos = new FileOutputStream(saved); +661 ObjectOutputStream oos = new ObjectOutputStream(fos); +662 oos.writeObject(md5s); +663 oos.close(); +664 fos.close(); +665 } +666 catch (Exception e) +667 { +668 getLog().error("Cannot write md5-sums to file: " + e); +669 } +670 } +671 +672 /** +673 * Needed, because DriverManager won't pick up drivers, that were not +674 * loaded by the system-classloader! +675 * See: +676 * http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-fromodifiedm-an-arbitrary-location +677 */ +678 static final class DriverProxy implements Driver +679 { +680 private final Driver target; +681 +682 DriverProxy(Driver target) +683 { +684 if (target == null) +685 throw new NullPointerException(); +686 this.target = target; +687 } +688 +689 public java.sql.Driver getTarget() +690 { +691 return target; +692 } +693 +694 @Override +695 public boolean acceptsURL(String url) throws SQLException +696 { +697 return target.acceptsURL(url); +698 } +699 +700 @Override +701 public java.sql.Connection connect( +702 String url, +703 java.util.Properties info +704 ) +705 throws +706 SQLException +707 { +708 return target.connect(url, info); +709 } +710 +711 @Override +712 public int getMajorVersion() +713 { +714 return target.getMajorVersion(); +715 } +716 +717 @Override +718 public int getMinorVersion() +719 { +720 return target.getMinorVersion(); +721 } +722 +723 @Override +724 public DriverPropertyInfo[] getPropertyInfo( +725 String url, +726 Properties info +727 ) +728 throws +729 SQLException +730 { +731 return target.getPropertyInfo(url, info); +732 } +733 +734 @Override +735 public boolean jdbcCompliant() +736 { +737 return target.jdbcCompliant(); +738 } +739 +740 /** +741 * This Method cannot be annotated with @Override, becaus the plugin +742 * will not compile then under Java 1.6! +743 */ +744 public Logger getParentLogger() throws SQLFeatureNotSupportedException +745 { +746 throw new SQLFeatureNotSupportedException("Not supported, for backward-compatibility with Java 1.6"); +747 } +748 +749 @Override +750 public String toString() +751 { +752 return "Proxy: " + target; +753 } +754 +755 @Override +756 public int hashCode() +757 { +758 return target.hashCode(); +759 } +760 +761 @Override +762 public boolean equals(Object obj) +763 { +764 if (!(obj instanceof DriverProxy)) +765 return false; +766 DriverProxy other = (DriverProxy) obj; +767 return this.target.equals(other.target); +768 } +769 } +770 } ++