1 package de.juplo.plugins.hibernate;
2
3
4 import com.pyx4j.log4j.MavenLogAppender;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.net.MalformedURLException;
10 import java.net.URL;
11 import java.security.NoSuchAlgorithmException;
12 import java.util.Collections;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.LinkedHashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.Properties;
20 import java.util.Set;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23 import javax.persistence.Embeddable;
24 import javax.persistence.Entity;
25 import javax.persistence.MappedSuperclass;
26 import javax.persistence.spi.PersistenceUnitTransactionType;
27 import org.apache.maven.artifact.Artifact;
28 import org.apache.maven.model.Resource;
29 import org.apache.maven.plugin.AbstractMojo;
30 import org.apache.maven.plugin.MojoExecutionException;
31 import org.apache.maven.plugin.MojoFailureException;
32 import org.apache.maven.project.MavenProject;
33 import org.hibernate.boot.MetadataBuilder;
34 import org.hibernate.boot.MetadataSources;
35 import org.hibernate.boot.cfgxml.internal.ConfigLoader;
36 import org.hibernate.boot.cfgxml.spi.LoadedConfig;
37 import org.hibernate.boot.cfgxml.spi.MappingReference;
38 import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
39 import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
40 import org.hibernate.boot.registry.BootstrapServiceRegistry;
41 import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
42 import org.hibernate.boot.registry.StandardServiceRegistry;
43 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
44 import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
45 import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
46 import org.hibernate.boot.registry.selector.spi.StrategySelector;
47 import org.hibernate.boot.spi.MetadataImplementor;
48 import static org.hibernate.cfg.AvailableSettings.DIALECT;
49 import static org.hibernate.cfg.AvailableSettings.DRIVER;
50 import static org.hibernate.cfg.AvailableSettings.FORMAT_SQL;
51 import static org.hibernate.cfg.AvailableSettings.HBM2DLL_CREATE_NAMESPACES;
52 import static org.hibernate.cfg.AvailableSettings.IMPLICIT_NAMING_STRATEGY;
53 import static org.hibernate.cfg.AvailableSettings.PASS;
54 import static org.hibernate.cfg.AvailableSettings.PHYSICAL_NAMING_STRATEGY;
55 import static org.hibernate.cfg.AvailableSettings.SHOW_SQL;
56 import static org.hibernate.cfg.AvailableSettings.USER;
57 import static org.hibernate.cfg.AvailableSettings.URL;
58 import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
59 import org.hibernate.internal.util.config.ConfigurationException;
60 import static org.hibernate.jpa.AvailableSettings.JDBC_DRIVER;
61 import static org.hibernate.jpa.AvailableSettings.JDBC_PASSWORD;
62 import static org.hibernate.jpa.AvailableSettings.JDBC_URL;
63 import static org.hibernate.jpa.AvailableSettings.JDBC_USER;
64 import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
65 import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
66 import org.hibernate.jpa.boot.spi.ProviderChecker;
67 import org.scannotation.AnnotationDB;
68
69
70
71
72
73
74
75
76
77 public abstract class AbstractSchemaMojo extends AbstractMojo
78 {
79 public final static String EXPORT = "hibernate.schema.export";
80 public final static String DELIMITER = "hibernate.schema.delimiter";
81 public final static String OUTPUTDIRECTORY = "project.build.outputDirectory";
82 public final static String SCAN_CLASSES = "hibernate.schema.scan.classes";
83 public final static String SCAN_DEPENDENCIES = "hibernate.schema.scan.dependencies";
84 public final static String SCAN_TESTCLASSES = "hibernate.schema.scan.test_classes";
85 public final static String TEST_OUTPUTDIRECTORY = "project.build.testOutputDirectory";
86 public final static String SKIPPED = "hibernate.schema.skipped";
87
88 private final static Pattern SPLIT = Pattern.compile("[^,\\s]+");
89
90 private final Set<String> packages = new HashSet<String>();
91
92
93
94
95
96
97
98
99
100
101 private MavenProject project;
102
103
104
105
106
107
108
109
110
111
112 String buildDirectory;
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 Boolean export;
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 private boolean skip;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 private boolean force;
173
174
175
176
177
178
179
180 private String dialect;
181
182
183
184
185
186
187
188
189
190
191
192
193
194 String delimiter;
195
196
197
198
199
200
201
202 Boolean show;
203
204
205
206
207
208
209
210 Boolean format;
211
212
213
214
215
216
217
218 Boolean createNamespaces;
219
220
221
222
223
224
225
226 private String implicitNamingStrategy;
227
228
229
230
231
232
233
234 private String physicalNamingStrategy;
235
236
237
238
239
240
241
242
243
244
245
246 private Boolean scanClasses;
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 private String outputDirectory;
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 private String scanDependencies;
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 private Boolean scanTestClasses;
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 private String testOutputDirectory;
321
322
323
324
325
326
327
328
329
330
331 private String driver;
332
333
334
335
336
337
338
339 private String url;
340
341
342
343
344
345
346
347 private String username;
348
349
350
351
352
353
354
355 private String password;
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 private String hibernateProperties;
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 private String hibernateConfig;
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413 private String persistenceUnit;
414
415
416
417
418
419
420
421
422 private String mappings;
423
424
425
426 public final void execute(String filename)
427 throws
428 MojoFailureException,
429 MojoExecutionException
430 {
431 if (skip)
432 {
433 getLog().info("Execution of hibernate-maven-plugin was skipped!");
434 project.getProperties().setProperty(SKIPPED, "true");
435 return;
436 }
437
438 ModificationTracker tracker;
439 try
440 {
441 tracker = new ModificationTracker(buildDirectory, filename, getLog());
442 }
443 catch (NoSuchAlgorithmException e)
444 {
445 throw new MojoFailureException("Digest-Algorithm MD5 is missing!", e);
446 }
447
448 SimpleConnectionProvider connectionProvider =
449 new SimpleConnectionProvider(getLog());
450
451 try
452 {
453
454 MavenLogAppender.startPluginLog(this);
455
456
457 tracker.load();
458
459
460 MutableClassLoader classLoader = createClassLoader();
461
462
463 BootstrapServiceRegistry bootstrapServiceRegitry =
464 new BootstrapServiceRegistryBuilder()
465 .applyClassLoader(classLoader)
466 .build();
467 ClassLoaderService classLoaderService =
468 bootstrapServiceRegitry.getService(ClassLoaderService.class);
469
470 Properties properties = new Properties();
471 ConfigLoader configLoader = new ConfigLoader(bootstrapServiceRegitry);
472
473
474 properties.putAll(loadProperties(configLoader));
475 LoadedConfig config = loadConfig(configLoader);
476 if (config != null)
477 properties.putAll(config.getConfigurationValues());
478 ParsedPersistenceXmlDescriptor unit =
479 loadPersistenceUnit(classLoaderService, properties);
480 if (unit != null)
481 properties.putAll(unit.getProperties());
482
483
484 configure(properties, tracker);
485
486
487 if(tracker.track(properties))
488 getLog().debug("Configuration has changed.");
489 else
490 getLog().debug("Configuration unchanged.");
491
492
493 StandardServiceRegistry serviceRegistry =
494 new StandardServiceRegistryBuilder(bootstrapServiceRegitry)
495 .applySettings(properties)
496 .addService(ConnectionProvider.class, connectionProvider)
497 .build();
498 MetadataSources sources = new MetadataSources(serviceRegistry);
499
500
501 completeClassPath(classLoader);
502
503
504 if (config != null)
505 {
506 for (MappingReference mapping : config.getMappingReferences())
507 mapping.apply(sources);
508 }
509
510 Set<String> classes;
511 if (unit == null)
512 {
513
514 if (scanClasses == null)
515 scanClasses = true;
516 Set<URL> urls = new HashSet<URL>();
517 if (scanClasses)
518 addRoot(urls, outputDirectory);
519 if (scanTestClasses)
520 addRoot(urls, testOutputDirectory);
521 addDependencies(urls);
522 classes = scanUrls(urls);
523 }
524 else
525 {
526
527 if (scanClasses == null)
528 scanClasses = !unit.isExcludeUnlistedClasses();
529 Set<URL> urls = new HashSet<URL>();
530 if (scanClasses)
531 {
532
533
534
535
536 urls.add(unit.getPersistenceUnitRootUrl());
537 for (URL url : unit.getJarFileUrls())
538 urls.add(url);
539 }
540 if (scanTestClasses)
541 addRoot(urls, testOutputDirectory);
542 classes = scanUrls(urls);
543 for (String className : unit.getManagedClassNames())
544 classes.add(className);
545
546
547
548
549 try
550 {
551 InputStream is = classLoader.getResourceAsStream("META-INF/orm.xml");
552 if (is != null)
553 {
554 getLog().info("Adding default JPA-XML-mapping from META-INF/orm.xml");
555 tracker.track("META-INF/orm.xml", is);
556 sources.addResource("META-INF/orm.xml");
557 }
558
559
560
561
562 for (String mapping : unit.getMappingFileNames())
563 {
564 getLog().info("Adding explicitly configured mapping from " + mapping);
565 tracker.track(mapping, classLoader.getResourceAsStream(mapping));
566 sources.addResource(mapping);
567 }
568 }
569 catch (IOException e)
570 {
571 throw new MojoFailureException("Error reading XML-mappings", e);
572 }
573 }
574
575
576 for (String className : classes)
577 addAnnotated(className, sources, classLoaderService, tracker);
578
579
580 addMappings(sources, tracker);
581
582
583 if (!tracker.modified())
584 {
585 getLog().info(
586 "Mapping and configuration unchanged."
587 );
588 if (force)
589 getLog().info("Schema generation is forced!");
590 else
591 {
592 getLog().info("Skipping schema generation!");
593 project.getProperties().setProperty(SKIPPED, "true");
594 return;
595 }
596 }
597
598
599
600 connectionProvider.open(classLoaderService, properties);
601
602 MetadataBuilder metadataBuilder = sources.getMetadataBuilder();
603
604 StrategySelector strategySelector =
605 serviceRegistry.getService(StrategySelector.class);
606
607 if (properties.containsKey(IMPLICIT_NAMING_STRATEGY))
608 {
609 metadataBuilder.applyImplicitNamingStrategy(
610 strategySelector.resolveStrategy(
611 ImplicitNamingStrategy.class,
612 properties.getProperty(IMPLICIT_NAMING_STRATEGY)
613 )
614 );
615 }
616
617 if (properties.containsKey(PHYSICAL_NAMING_STRATEGY))
618 {
619 metadataBuilder.applyPhysicalNamingStrategy(
620 strategySelector.resolveStrategy(
621 PhysicalNamingStrategy.class,
622 properties.getProperty(PHYSICAL_NAMING_STRATEGY)
623 )
624 );
625 }
626
627
628
629
630
631
632 Thread thread = Thread.currentThread();
633 ClassLoader contextClassLoader = thread.getContextClassLoader();
634 try
635 {
636 thread.setContextClassLoader(classLoader);
637 build((MetadataImplementor)metadataBuilder.build());
638 }
639 finally
640 {
641 thread.setContextClassLoader(contextClassLoader);
642 }
643 }
644 catch (MojoExecutionException e)
645 {
646 tracker.failed();
647 throw e;
648 }
649 catch (MojoFailureException e)
650 {
651 tracker.failed();
652 throw e;
653 }
654 catch (RuntimeException e)
655 {
656 tracker.failed();
657 throw e;
658 }
659 finally
660 {
661
662 tracker.save();
663
664
665 connectionProvider.close();
666
667
668 MavenLogAppender.endPluginLog(this);
669 }
670 }
671
672
673 abstract void build(MetadataImplementor metadata)
674 throws
675 MojoFailureException,
676 MojoExecutionException;
677
678
679 private MutableClassLoader createClassLoader() throws MojoExecutionException
680 {
681 try
682 {
683 getLog().debug("Creating ClassLoader for project-dependencies...");
684 LinkedHashSet<URL> urls = new LinkedHashSet<URL>();
685 File file;
686
687 file = new File(testOutputDirectory);
688 if (!file.exists())
689 {
690 getLog().info("Creating test-output-directory: " + testOutputDirectory);
691 file.mkdirs();
692 }
693 urls.add(file.toURI().toURL());
694
695 file = new File(outputDirectory);
696 if (!file.exists())
697 {
698 getLog().info("Creating output-directory: " + outputDirectory);
699 file.mkdirs();
700 }
701 urls.add(file.toURI().toURL());
702
703 return new MutableClassLoader(urls, getLog());
704 }
705 catch (Exception e)
706 {
707 getLog().error("Error while creating ClassLoader!", e);
708 throw new MojoExecutionException(e.getMessage());
709 }
710 }
711
712 private void completeClassPath(MutableClassLoader classLoader)
713 throws
714 MojoExecutionException
715 {
716 try
717 {
718 getLog().debug("Completing class-paths of the ClassLoader for project-dependencies...");
719 List<String> classpathFiles = project.getCompileClasspathElements();
720 if (scanTestClasses)
721 classpathFiles.addAll(project.getTestClasspathElements());
722 LinkedHashSet<URL> urls = new LinkedHashSet<URL>();
723 for (String pathElement : classpathFiles)
724 {
725 getLog().debug("Dependency: " + pathElement);
726 urls.add(new File(pathElement).toURI().toURL());
727 }
728 classLoader.add(urls);
729 }
730 catch (Exception e)
731 {
732 getLog().error("Error while creating ClassLoader!", e);
733 throw new MojoExecutionException(e.getMessage());
734 }
735 }
736
737 private Map loadProperties(ConfigLoader configLoader)
738 throws
739 MojoExecutionException
740 {
741
742 if (hibernateProperties == null)
743 {
744 try
745 {
746 return configLoader.loadProperties("hibernate.properties");
747 }
748 catch (ConfigurationException e)
749 {
750 getLog().debug(e.getMessage());
751 return Collections.EMPTY_MAP;
752 }
753 }
754 else
755 {
756 try
757 {
758 File file = new File(hibernateProperties);
759 if (file.exists())
760 {
761 getLog().info("Reading settings from file " + hibernateProperties + "...");
762 return configLoader.loadProperties(file);
763 }
764 else
765 return configLoader.loadProperties(hibernateProperties);
766 }
767 catch (ConfigurationException e)
768 {
769 getLog().error("Error while reading properties!", e);
770 throw new MojoExecutionException(e.getMessage());
771 }
772 }
773 }
774
775 private LoadedConfig loadConfig(ConfigLoader configLoader)
776 throws MojoExecutionException
777 {
778
779 if (hibernateConfig == null)
780 {
781 try
782 {
783 return configLoader.loadConfigXmlResource("hibernate.cfg.xml");
784 }
785 catch (ConfigurationException e)
786 {
787 getLog().debug(e.getMessage());
788 return null;
789 }
790 }
791 else
792 {
793 try
794 {
795 File file = new File(hibernateConfig);
796 if (file.exists())
797 {
798 getLog().info("Reading configuration from file " + hibernateConfig + "...");
799 return configLoader.loadConfigXmlFile(file);
800 }
801 else
802 {
803 return configLoader.loadConfigXmlResource(hibernateConfig);
804 }
805 }
806 catch (ConfigurationException e)
807 {
808 getLog().error("Error while reading configuration!", e);
809 throw new MojoExecutionException(e.getMessage());
810 }
811 }
812 }
813
814 private void configure(Properties properties, ModificationTracker tracker)
815 throws MojoFailureException
816 {
817
818
819
820
821 if (tracker.check(EXPORT, export.toString()) && export)
822 tracker.touch();
823
824
825
826
827
828
829 dialect = configure(properties, dialect, DIALECT);
830 tracker.track(DELIMITER, delimiter);
831 format = configure(properties, format, FORMAT_SQL);
832 createNamespaces = configure(properties, createNamespaces, HBM2DLL_CREATE_NAMESPACES);
833 implicitNamingStrategy = configure(properties, implicitNamingStrategy, IMPLICIT_NAMING_STRATEGY);
834 physicalNamingStrategy = configure(properties, physicalNamingStrategy, PHYSICAL_NAMING_STRATEGY);
835 tracker.track(OUTPUTDIRECTORY, outputDirectory);
836 tracker.track(SCAN_DEPENDENCIES, scanDependencies);
837 tracker.track(SCAN_TESTCLASSES, scanTestClasses.toString());
838 tracker.track(TEST_OUTPUTDIRECTORY, testOutputDirectory);
839
840
841
842
843
844
845 if (show == null)
846 show = Boolean.valueOf(properties.getProperty(SHOW_SQL));
847 else
848 properties.setProperty(SHOW_SQL, show.toString());
849
850
851
852
853
854 driver = configure(properties, driver, DRIVER, JDBC_DRIVER);
855 url = configure(properties, url, URL, JDBC_URL);
856 username = configure(properties, username, USER, JDBC_USER);
857 password = configure(properties, password, PASS, JDBC_PASSWORD);
858
859 if (properties.isEmpty())
860 {
861 getLog().error("No properties set!");
862 throw new MojoFailureException("Hibernate configuration is missing!");
863 }
864
865 getLog().info("Gathered hibernate-configuration (turn on debugging for details):");
866 for (Entry<Object,Object> entry : properties.entrySet())
867 getLog().info(" " + entry.getKey() + " = " + entry.getValue());
868 }
869
870 private String configure(
871 Properties properties,
872 String value,
873 String key,
874 String alternativeKey
875 )
876 {
877 value = configure(properties, value, key);
878 if (value == null)
879 return properties.getProperty(alternativeKey);
880
881 if (properties.containsKey(alternativeKey))
882 {
883 getLog().warn(
884 "Ignoring property " + alternativeKey + "=" +
885 properties.getProperty(alternativeKey) + " in favour for property " +
886 key + "=" + properties.getProperty(key)
887 );
888 properties.remove(alternativeKey);
889 }
890 return properties.getProperty(alternativeKey);
891 }
892
893 private String configure(Properties properties, String value, String key)
894 {
895 if (value != null)
896 {
897 if (properties.containsKey(key))
898 getLog().debug(
899 "Overwriting property " + key + "=" + properties.getProperty(key) +
900 " with the value " + value
901 );
902 else
903 getLog().debug("Using the value " + value + " for property " + key);
904 properties.setProperty(key, value);
905 }
906 return properties.getProperty(key);
907 }
908
909 private boolean configure(Properties properties, Boolean value, String key)
910 {
911 if (value != null)
912 {
913 if (properties.containsKey(key))
914 getLog().debug(
915 "Overwriting property " + key + "=" + properties.getProperty(key) +
916 " with the value " + value
917 );
918 else
919 getLog().debug("Using the value " + value + " for property " + key);
920 properties.setProperty(key, value.toString());
921 }
922 return Boolean.valueOf(properties.getProperty(key));
923 }
924
925 private void addMappings(MetadataSources sources, ModificationTracker tracker)
926 throws MojoFailureException
927 {
928 getLog().debug("Adding explicitly configured mappings...");
929 if (mappings != null)
930 {
931 try
932 {
933 for (String filename : mappings.split("[\\s,]+"))
934 {
935
936 File file = new File(filename);
937 if (!file.exists())
938 {
939
940 for (Resource resource : project.getResources())
941 {
942 file = new File(resource.getDirectory() + File.separator + filename);
943 if (file.exists())
944 break;
945 }
946 }
947 if (file.exists())
948 {
949 if (file.isDirectory())
950
951 throw new MojoFailureException(file.getAbsolutePath() + " is a directory");
952 if (tracker.track(filename, new FileInputStream(file)))
953 getLog().debug("Found new or modified mapping-file: " + filename);
954 else
955 getLog().debug("Mapping-file unchanged: " + filename);
956
957 sources.addFile(file);
958 }
959 else
960 throw new MojoFailureException("File " + filename + " could not be found in any of the configured resource-directories!");
961 }
962 }
963 catch (IOException e)
964 {
965 throw new MojoFailureException("Cannot calculate MD5 sums!", e);
966 }
967 }
968 }
969
970 private void addRoot(Set<URL> urls, String path) throws MojoFailureException
971 {
972 try
973 {
974 File dir = new File(outputDirectory);
975 if (dir.exists())
976 {
977 getLog().info("Adding " + dir.getAbsolutePath() + " to the list of roots to scan...");
978 urls.add(dir.toURI().toURL());
979 }
980 }
981 catch (MalformedURLException e)
982 {
983 getLog().error("error while adding the project-root to the list of roots to scan!", e);
984 throw new MojoFailureException(e.getMessage());
985 }
986 }
987
988 private void addDependencies(Set<URL> urls) throws MojoFailureException
989 {
990 try
991 {
992 if (scanDependencies != null)
993 {
994 Matcher matcher = SPLIT.matcher(scanDependencies);
995 while (matcher.find())
996 {
997 getLog().info("Adding dependencies from scope " + matcher.group() + " to the list of roots to scan");
998 for (Artifact artifact : project.getDependencyArtifacts())
999 {
1000 if (!artifact.getScope().equalsIgnoreCase(matcher.group()))
1001 continue;
1002 if (artifact.getFile() == null)
1003 {
1004 getLog().warn("Cannot add dependency " + artifact.getId() + ": no JAR-file available!");
1005 continue;
1006 }
1007 getLog().info("Adding dependencies from scope " + artifact.getId() + " to the list of roots to scan");
1008 urls.add(artifact.getFile().toURI().toURL());
1009 }
1010 }
1011 }
1012 }
1013 catch (MalformedURLException e)
1014 {
1015 getLog().error("Error while adding dependencies to the list of roots to scan!", e);
1016 throw new MojoFailureException(e.getMessage());
1017 }
1018 }
1019
1020 private Set<String> scanUrls(Set<URL> scanRoots)
1021 throws
1022 MojoFailureException
1023 {
1024 try
1025 {
1026 AnnotationDB db = new AnnotationDB();
1027 for (URL root : scanRoots)
1028 db.scanArchives(root);
1029
1030 Set<String> classes = new HashSet<String>();
1031 if (db.getAnnotationIndex().containsKey(Entity.class.getName()))
1032 classes.addAll(db.getAnnotationIndex().get(Entity.class.getName()));
1033 if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName()))
1034 classes.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName()));
1035 if (db.getAnnotationIndex().containsKey(Embeddable.class.getName()))
1036 classes.addAll(db.getAnnotationIndex().get(Embeddable.class.getName()));
1037
1038 return classes;
1039 }
1040 catch (Exception e)
1041 {
1042 getLog().error("Error while scanning!", e);
1043 throw new MojoFailureException(e.getMessage());
1044 }
1045 }
1046
1047 private void addAnnotated(
1048 String name,
1049 MetadataSources sources,
1050 ClassLoaderService classLoaderService,
1051 ModificationTracker tracker
1052 )
1053 throws
1054 MojoFailureException,
1055 MojoExecutionException
1056 {
1057 try
1058 {
1059 getLog().info("Adding annotated resource: " + name);
1060 String packageName;
1061
1062 try
1063 {
1064 Class<?> annotatedClass = classLoaderService.classForName(name);
1065 String resourceName = annotatedClass.getName();
1066 resourceName =
1067 resourceName.substring(
1068 resourceName.lastIndexOf(".") + 1,
1069 resourceName.length()
1070 ) + ".class";
1071 InputStream is = annotatedClass.getResourceAsStream(resourceName);
1072 if (tracker.track(name, is))
1073 getLog().debug("New or modified class: " + name);
1074 else
1075 getLog().debug("Unchanged class: " + name);
1076 sources.addAnnotatedClass(annotatedClass);
1077 packageName = annotatedClass.getPackage().getName();
1078 }
1079 catch(ClassLoadingException e)
1080 {
1081 packageName = name;
1082 }
1083
1084 while (packageName != null)
1085 {
1086 if (packages.contains(packageName))
1087 return;
1088 String resource = packageName.replace('.', '/') + "/package-info.class";
1089 InputStream is = classLoaderService.locateResourceStream(resource);
1090 if (is == null)
1091 {
1092
1093 getLog().debug("Package " + packageName + " is not annotated.");
1094 }
1095 else
1096 {
1097 if (tracker.track(packageName, is))
1098 getLog().debug("New or modified package: " + packageName);
1099 else
1100 getLog().debug("Unchanged package: " + packageName);
1101 getLog().info("Adding annotations from package " + packageName);
1102 sources.addPackage(packageName);
1103 }
1104 packages.add(packageName);
1105 int i = packageName.lastIndexOf('.');
1106 if (i < 0)
1107 packageName = null;
1108 else
1109 packageName = packageName.substring(0,i);
1110 }
1111 }
1112 catch (Exception e)
1113 {
1114 getLog().error("Error while adding the annotated class " + name, e);
1115 throw new MojoFailureException(e.getMessage());
1116 }
1117 }
1118
1119 private ParsedPersistenceXmlDescriptor loadPersistenceUnit(
1120 ClassLoaderService classLoaderService,
1121 Properties properties
1122 )
1123 throws
1124 MojoFailureException
1125 {
1126 PersistenceXmlParser parser =
1127 new PersistenceXmlParser(
1128 classLoaderService,
1129 PersistenceUnitTransactionType.RESOURCE_LOCAL
1130 );
1131
1132 List<ParsedPersistenceXmlDescriptor> units = parser.doResolve(properties);
1133
1134 if (persistenceUnit == null)
1135 {
1136 switch (units.size())
1137 {
1138 case 0:
1139 getLog().info("Found no META-INF/persistence.xml.");
1140 return null;
1141 case 1:
1142 getLog().info("Using persistence-unit " + units.get(0).getName());
1143 return units.get(0);
1144 default:
1145 StringBuilder builder = new StringBuilder();
1146 builder.append("No name provided and multiple persistence units found: ");
1147 Iterator<ParsedPersistenceXmlDescriptor> it = units.iterator();
1148 builder.append(it.next().getName());
1149 while (it.hasNext())
1150 {
1151 builder.append(", ");
1152 builder.append(it.next().getName());
1153 }
1154 builder.append('.');
1155 throw new MojoFailureException(builder.toString());
1156 }
1157 }
1158
1159 for (ParsedPersistenceXmlDescriptor unit : units)
1160 {
1161 getLog().debug("Found persistence-unit " + unit.getName());
1162 if (!unit.getName().equals(persistenceUnit))
1163 continue;
1164
1165
1166 if (!ProviderChecker.isProvider(unit, properties))
1167 {
1168 getLog().debug("Wrong provider: " + unit.getProviderClassName());
1169 continue;
1170 }
1171
1172 getLog().info("Using persistence-unit " + unit.getName());
1173 return unit;
1174 }
1175
1176 throw new MojoFailureException("Could not find persistence-unit " + persistenceUnit);
1177 }
1178 }