From 349fdef18bcf688709f19097c140c69724905768 Mon Sep 17 00:00:00 2001 From: michaelisvy Date: Wed, 9 Jan 2013 01:05:18 -0800 Subject: [PATCH 001/887] Initial commit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..560aaaa5e --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +spring-petclinic +================ + +sample application for the Spring framework \ No newline at end of file From f09d67cc1c216b445d01f1893f37ff391bb3b4b7 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 5 May 2009 17:22:49 +0000 Subject: [PATCH 002/887] petclinic 3 initial commit - wip --- .../.classpath | 14 +++ .../.project | 42 +++++++ .../com.springsource.server.ide.jdt.core.xml | 2 + .../.settings/org.eclipse.jdt.core.prefs | 12 ++ ...clipse.jst.common.project.facet.core.prefs | 3 + .../org.eclipse.wst.common.component | 10 ++ ....eclipse.wst.common.project.facet.core.xml | 7 ++ .../org.eclipse.wst.validation.prefs | 6 + .../.settings/org.maven.ide.eclipse.prefs | 9 ++ ...ringframework.ide.eclipse.beans.core.prefs | 3 + ...org.springframework.ide.eclipse.core.prefs | 67 +++++++++++ .../.springBeans | 13 +++ org.springframework.samples.petclinic/pom.xml | 106 ++++++++++++++++++ .../samples/petclinic/HomeController.java | 14 +++ .../samples/petclinic/owner/Owner.java | 26 +++++ .../petclinic/owner/OwnerController.java | 36 ++++++ .../petclinic/owner/OwnerRepository.java | 13 +++ .../petclinic/owner/OwnersController.java | 39 +++++++ .../samples/petclinic/pet/Gender.java | 5 + .../samples/petclinic/pet/Pet.java | 25 +++++ .../samples/petclinic/pet/PetController.java | 41 +++++++ .../samples/petclinic/pet/PetRepository.java | 9 ++ .../samples/petclinic/util/Measurement.java | 10 ++ .../petclinic/util/ResponseContext.java | 9 ++ .../samples/petclinic/util/Unit.java | 5 + .../src/main/resources/log4j.xml | 42 +++++++ .../src/main/webapp/WEB-INF/home.jsp | 12 ++ .../main/webapp/WEB-INF/spring/app-config.xml | 14 +++ .../main/webapp/WEB-INF/spring/mvc-config.xml | 36 ++++++ .../src/main/webapp/WEB-INF/urlrewrite.xml | 12 ++ .../src/main/webapp/WEB-INF/web.xml | 36 ++++++ .../src/test/resources/log4j.xml | 42 +++++++ 32 files changed, 720 insertions(+) create mode 100644 org.springframework.samples.petclinic/.classpath create mode 100644 org.springframework.samples.petclinic/.project create mode 100644 org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml create mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs create mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs create mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component create mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs create mode 100644 org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs create mode 100644 org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs create mode 100644 org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs create mode 100644 org.springframework.samples.petclinic/.springBeans create mode 100644 org.springframework.samples.petclinic/pom.xml create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java create mode 100644 org.springframework.samples.petclinic/src/main/resources/log4j.xml create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml create mode 100644 org.springframework.samples.petclinic/src/test/resources/log4j.xml diff --git a/org.springframework.samples.petclinic/.classpath b/org.springframework.samples.petclinic/.classpath new file mode 100644 index 000000000..5c40e0b3f --- /dev/null +++ b/org.springframework.samples.petclinic/.classpath @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/org.springframework.samples.petclinic/.project b/org.springframework.samples.petclinic/.project new file mode 100644 index 000000000..ed4ca5e5a --- /dev/null +++ b/org.springframework.samples.petclinic/.project @@ -0,0 +1,42 @@ + + + org.springframework.samples.petclinic + + + Servers + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.maven.ide.eclipse.maven2Nature + org.springframework.ide.eclipse.core.springnature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.common.modulecore.ModuleCoreNature + + diff --git a/org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml b/org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml new file mode 100644 index 000000000..0a4413c52 --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml @@ -0,0 +1,2 @@ + + diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs b/org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..9ec44e3e6 --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Tue Mar 17 10:00:21 EDT 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs b/org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs new file mode 100644 index 000000000..763a1503d --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs @@ -0,0 +1,3 @@ +#Tue Mar 17 09:59:19 EDT 2009 +classpath.helper/org.eclipse.jdt.launching.JRE_CONTAINER\:\:org.eclipse.jdt.internal.launching.macosx.MacOSXType\:\:JVM\ 1.5.0\ (MacOS\ X\ Default)/owners=jst.java\:5.0 +eclipse.preferences.version=1 diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component new file mode 100644 index 000000000..89d4f2ab5 --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..d24a733bd --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 000000000..75abca5ce --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,6 @@ +#Fri Jun 06 17:00:12 BST 2008 +DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator; +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.common.componentcore.internal.ModuleCoreValidator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.common.componentcore.internal.ModuleCoreValidator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator; +USER_PREFERENCE=overrideGlobalPreferencesfalse +eclipse.preferences.version=1 diff --git a/org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs b/org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..0b751087c --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Mar 17 14:28:16 EDT 2009 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs b/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs new file mode 100644 index 000000000..a7eb2b337 --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs @@ -0,0 +1,3 @@ +#Wed Dec 17 01:09:03 EST 2008 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.beans.core.ignoreMissingNamespaceHandler=false diff --git a/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs b/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 000000000..e096d67b6 --- /dev/null +++ b/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,67 @@ +#Tue Mar 17 10:00:21 EDT 2009 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=false +org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=true +org.springframework.ide.eclipse.core.enable.project.preferences=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/org.springframework.samples.petclinic/.springBeans b/org.springframework.samples.petclinic/.springBeans new file mode 100644 index 000000000..24e2d6593 --- /dev/null +++ b/org.springframework.samples.petclinic/.springBeans @@ -0,0 +1,13 @@ + + + 1 + + + + + + + + + + diff --git a/org.springframework.samples.petclinic/pom.xml b/org.springframework.samples.petclinic/pom.xml new file mode 100644 index 000000000..e38359706 --- /dev/null +++ b/org.springframework.samples.petclinic/pom.xml @@ -0,0 +1,106 @@ + + + 4.0.0 + org.springframework + samples + org.springframework.samples.petclinic + war + 1.0.0-SNAPSHOT + + 2.5.6 + + + + + javax.servlet + jstl + 1.2 + + + log4j + log4j + 1.2.14 + + + org.tuckey + urlrewritefilter + 3.1.0 + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + + javax.servlet + servlet-api + 2.4 + provided + + + javax.servlet.jsp + jsp-api + 2.1 + provided + + + + junit + junit + 4.5 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-dependency-plugin + + + install + install + + sources + + + + + + + diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java new file mode 100644 index 000000000..b11f02cec --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java @@ -0,0 +1,14 @@ +package org.springframework.samples.petclinic; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +public class HomeController { + + @RequestMapping(value="/", method = RequestMethod.GET) + public void getHome() { + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java new file mode 100644 index 000000000..4321ce3bd --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -0,0 +1,26 @@ +package org.springframework.samples.petclinic.owner; + + +public class Owner { + + private Long id; + + private String firstName; + + private String lastName; + + private String address; + + private String city; + + private String telephone; + + public Long getId() { + return id; + } + + public String getName() { + return lastName; + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java new file mode 100644 index 000000000..548889c7e --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -0,0 +1,36 @@ +package org.springframework.samples.petclinic.owner; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.util.ResponseContext; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +@RequestMapping(value="/owners/{owner}") +public class OwnerController { + + private final OwnerRepository repository; + + @Autowired + public OwnerController(OwnerRepository repository) { + this.repository = repository; + } + + @RequestMapping(method=RequestMethod.GET) + public Owner get(Long owner) { + return repository.getOwner(owner); + } + + @RequestMapping(value="/edit", method=RequestMethod.GET) + public Owner getEditForm(Long owner) { + return repository.getOwner(owner); + } + + @RequestMapping(method = RequestMethod.PUT) + public void put(Owner owner, ResponseContext response) { + repository.saveOwner(owner); + response.redirect(owner.getName()); + } + +} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java new file mode 100644 index 000000000..e151f45e2 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java @@ -0,0 +1,13 @@ +package org.springframework.samples.petclinic.owner; + +import java.util.Collection; + +public interface OwnerRepository { + + Collection findOwnersByLastName(String lastName); + + Owner getOwner(Long id); + + void saveOwner(Owner owner); + +} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java new file mode 100644 index 000000000..9c547d9d0 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java @@ -0,0 +1,39 @@ +package org.springframework.samples.petclinic.owner; + +import java.util.Collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.util.ResponseContext; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@RequestMapping("/owners") +public class OwnersController { + + private final OwnerRepository repository; + + @Autowired + public OwnersController(OwnerRepository repository) { + this.repository = repository; + } + + @RequestMapping(method = RequestMethod.GET) + public Collection get(@RequestParam String lastName) { + return repository.findOwnersByLastName(lastName); + } + + @RequestMapping(value="/new", method = RequestMethod.GET) + public Owner getNewForm() { + return new Owner(); + } + + @RequestMapping(method = RequestMethod.POST) + public void post(Owner owner, ResponseContext response) { + repository.saveOwner(owner); + response.redirect(owner.getName()); + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java new file mode 100644 index 000000000..e67a95aa6 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java @@ -0,0 +1,5 @@ +package org.springframework.samples.petclinic.pet; + +public enum Gender { + MALE, FEMALE +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java new file mode 100644 index 000000000..e0765ee4c --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java @@ -0,0 +1,25 @@ +package org.springframework.samples.petclinic.pet; + +import java.util.Date; + +import org.springframework.samples.petclinic.util.Measurement; + +public class Pet { + + private String name; + + private String species; + + private String breed; + + private Gender gender; + + private Date birthDate; + + private Measurement weight; + + public String getName() { + return name; + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java new file mode 100644 index 000000000..106754071 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java @@ -0,0 +1,41 @@ +package org.springframework.samples.petclinic.pet; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.util.ResponseContext; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +@RequestMapping(value="/owners/{owner}/pets/{pet}") +public class PetController { + + private final PetRepository repository; + + @Autowired + public PetController(PetRepository repository) { + this.repository = repository; + } + + @RequestMapping(method=RequestMethod.GET) + public Pet get(Long owner, String pet) { + return repository.getPet(owner, pet); + } + + @RequestMapping(value="/edit", method=RequestMethod.GET) + public Pet getEditForm(Long owner, String pet) { + return repository.getPet(owner, pet); + } + + @RequestMapping(method = RequestMethod.PUT) + public void put(Pet pet, ResponseContext response) { + repository.savePet(pet); + response.redirect(pet.getName()); + } + + @RequestMapping(method = RequestMethod.DELETE) + public void delete(Long owner, String pet, ResponseContext context) { + context.forResource("owners").redirect(owner); + } + +} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java new file mode 100644 index 000000000..c3b52f4f1 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java @@ -0,0 +1,9 @@ +package org.springframework.samples.petclinic.pet; + +public interface PetRepository { + + Pet getPet(Long owner, String name); + + void savePet(Pet pet); + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java new file mode 100644 index 000000000..9120e5838 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.util; + +import java.math.BigDecimal; + +public class Measurement { + + private BigDecimal amount; + + private Unit unit; +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java new file mode 100644 index 000000000..fd9d5f674 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java @@ -0,0 +1,9 @@ +package org.springframework.samples.petclinic.util; + +public interface ResponseContext { + + void redirect(Object resource); + + ResponseContext forResource(Object resource); + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java new file mode 100644 index 000000000..6bcf4e2e7 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java @@ -0,0 +1,5 @@ +package org.springframework.samples.petclinic.util; + +public enum Unit { + POUNDS +} diff --git a/org.springframework.samples.petclinic/src/main/resources/log4j.xml b/org.springframework.samples.petclinic/src/main/resources/log4j.xml new file mode 100644 index 000000000..d65fd3775 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/resources/log4j.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp new file mode 100644 index 000000000..b37beeda4 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp @@ -0,0 +1,12 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" %> + + + Welcome + + +

+ Congratulations! You're running Spring! +

+ + diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml new file mode 100644 index 000000000..63165f80e --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml new file mode 100644 index 000000000..c9833d687 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml new file mode 100644 index 000000000..26672b6cd --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml @@ -0,0 +1,12 @@ + + + + + /** + /app/$1 + + + /app/** + /$1 + + diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..95239d4a2 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,36 @@ + + + + + + UrlRewriteFilter + org.tuckey.web.filters.urlrewrite.UrlRewriteFilter + + + + UrlRewriteFilter + /* + + + + + Spring MVC Dispatcher Servlet + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + + /WEB-INF/spring/*.xml + + + 1 + + + + + Spring MVC Dispatcher Servlet + /app/* + + + diff --git a/org.springframework.samples.petclinic/src/test/resources/log4j.xml b/org.springframework.samples.petclinic/src/test/resources/log4j.xml new file mode 100644 index 000000000..6cd59573d --- /dev/null +++ b/org.springframework.samples.petclinic/src/test/resources/log4j.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7ff5e857fdb41a9f3e012c56390c2baa1f8b0f3e Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 5 May 2009 17:30:38 +0000 Subject: [PATCH 003/887] app deploys and runs - initial commit --- .../samples/petclinic/HomeController.java | 3 ++- .../petclinic/owner/StubOwnerRepository.java | 21 +++++++++++++++++++ .../petclinic/pet/StubPetRepository.java | 15 +++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java index b11f02cec..72d36e8a0 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java @@ -8,7 +8,8 @@ import org.springframework.web.bind.annotation.RequestMethod; public class HomeController { @RequestMapping(value="/", method = RequestMethod.GET) - public void getHome() { + public String getHome() { + return "home"; } } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java new file mode 100644 index 000000000..b9da84907 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java @@ -0,0 +1,21 @@ +package org.springframework.samples.petclinic.owner; + +import java.util.Collection; + +import org.springframework.stereotype.Repository; + +@Repository +public class StubOwnerRepository implements OwnerRepository { + + public Collection findOwnersByLastName(String lastName) { + return null; + } + + public Owner getOwner(Long id) { + return null; + } + + public void saveOwner(Owner owner) { + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java new file mode 100644 index 000000000..1c0e731a5 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java @@ -0,0 +1,15 @@ +package org.springframework.samples.petclinic.pet; + +import org.springframework.stereotype.Repository; + +@Repository +public class StubPetRepository implements PetRepository { + + public Pet getPet(Long owner, String name) { + return null; + } + + public void savePet(Pet pet) { + } + +} From 556824d7c7f31405deb6ba7bc066cf957eed0be5 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 5 May 2009 22:00:59 +0000 Subject: [PATCH 004/887] styles --- org.springframework.samples.petclinic/pom.xml | 38 +++++- .../src/main/webapp/WEB-INF/home.jsp | 16 +-- .../main/webapp/WEB-INF/spring/mvc-config.xml | 12 ++ .../src/main/webapp/WEB-INF/urlrewrite.xml | 4 + .../src/main/webapp/WEB-INF/web.xml | 13 ++ .../src/main/webapp/images/banner-graphic.png | Bin 0 -> 13773 bytes .../src/main/webapp/images/pets.png | Bin 0 -> 55318 bytes .../main/webapp/images/springsource-logo.png | Bin 0 -> 4974 bytes .../src/main/webapp/styles/main.css | 118 ++++++++++++++++++ 9 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 org.springframework.samples.petclinic/src/main/webapp/images/banner-graphic.png create mode 100644 org.springframework.samples.petclinic/src/main/webapp/images/pets.png create mode 100644 org.springframework.samples.petclinic/src/main/webapp/images/springsource-logo.png create mode 100644 org.springframework.samples.petclinic/src/main/webapp/styles/main.css diff --git a/org.springframework.samples.petclinic/pom.xml b/org.springframework.samples.petclinic/pom.xml index e38359706..808c5f6f6 100644 --- a/org.springframework.samples.petclinic/pom.xml +++ b/org.springframework.samples.petclinic/pom.xml @@ -22,11 +22,41 @@ log4j 1.2.14 + + commons-fileupload + commons-fileupload + 1.2.1 + + + + commons-io + commons-io + 1.3.2 + + + + hsqldb + hsqldb + 1.8.0.7 + + + + org.apache.tiles + tiles-core + 2.0.7 + + + org.apache.tiles + tiles-jsp + 2.0.7 + + org.tuckey urlrewritefilter 3.1.0 - + + org.springframework spring-core @@ -57,6 +87,12 @@ spring-jdbc ${spring.version} + + + org.springframework.webflow + spring-js + 2.0.7.RELEASE + javax.servlet diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp index b37beeda4..08ab75826 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp @@ -1,12 +1,6 @@ <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ page session="false" %> - - - Welcome - - -

- Congratulations! You're running Spring! -

- - +

Welcome to the Spring 3 Petclinic

+ +

+ This sample application demonstrates many of the features Spring provides for web application development. +

\ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml index c9833d687..15466b8fc 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml @@ -28,9 +28,21 @@ + + + + + + + + + + + + diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml index 26672b6cd..9e3a4589b 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml @@ -1,6 +1,10 @@ + + /resources/** + /resources/$1 + /** /app/$1 diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml index 95239d4a2..8238f5100 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml @@ -32,5 +32,18 @@ Spring MVC Dispatcher Servlet /app/* + + + + Resources Servlet + org.springframework.js.resource.ResourceServlet + 0 + + + + + Resources Servlet + /resources/* + diff --git a/org.springframework.samples.petclinic/src/main/webapp/images/banner-graphic.png b/org.springframework.samples.petclinic/src/main/webapp/images/banner-graphic.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d01d5885266efbf4dc99431576a13dee5725e4 GIT binary patch literal 13773 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 literal 0 HcmV?d00001 diff --git a/org.springframework.samples.petclinic/src/main/webapp/images/springsource-logo.png b/org.springframework.samples.petclinic/src/main/webapp/images/springsource-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e170f8abf778b24ed1de11dad6f1444e849269ba GIT binary patch literal 4974 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 Date: Tue, 5 May 2009 22:12:23 +0000 Subject: [PATCH 005/887] will add css later --- .../samples/petclinic/HomeController.java | 2 +- .../samples/petclinic/owner/Owner.java | 1 - .../petclinic/owner/OwnersController.java | 7 +- .../src/main/webapp/styles/main.css | 118 ------------------ 4 files changed, 7 insertions(+), 121 deletions(-) diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java index 72d36e8a0..797ca81e0 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java @@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.RequestMethod; public class HomeController { @RequestMapping(value="/", method = RequestMethod.GET) - public String getHome() { + public String get() { return "home"; } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java index 4321ce3bd..eab0654c0 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -1,6 +1,5 @@ package org.springframework.samples.petclinic.owner; - public class Owner { private Long id; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java index 9c547d9d0..fe42ab02c 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java @@ -21,7 +21,12 @@ public class OwnersController { } @RequestMapping(method = RequestMethod.GET) - public Collection get(@RequestParam String lastName) { + public void get() { + + } + + @RequestMapping(value="/search", method = RequestMethod.GET) + public Collection getSearchResults(@RequestParam String lastName) { return repository.findOwnersByLastName(lastName); } diff --git a/org.springframework.samples.petclinic/src/main/webapp/styles/main.css b/org.springframework.samples.petclinic/src/main/webapp/styles/main.css index 2eb8f819f..e69de29bb 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/styles/main.css +++ b/org.springframework.samples.petclinic/src/main/webapp/styles/main.css @@ -1,118 +0,0 @@ -* { - margin: 0px; - padding: 0px; -} - -body { - background-image: url(../images/banner-graphic.png); - background-position: top; - background-repeat: no-repeat; - width: 820px; - margin: auto; - margin-top: 60px; - font-family:verdana; - font-size: 62.5%; -} - -h2 { - text-align: center; -} - -/* Header */ -#header { - height: 50px; -} - -#signin { - float: right; - list-style: none; - width: 100px; - overflow: hidden; -} -#signin li{ - display: inline; - padding: 0 2px; - border-left: 1px solid #000; - margin-left: -1px; -} -#signin li a{ - -} -#nav { - margin-left: auto; - margin-right: auto; - width: 600px; - clear: right; - padding: 1em; -} -#nav ul { - list-style: none; -} -#nav ul li { - display: inline; -} -#nav ul li a { - display: block; - float: left; - width: 150px; - font-size: 1.2em; -} - -/* Sidebar */ -#sidebar { - float: left; - width: 200px; -} -#sub-nav { - list-style: none; -} -#sub-nav li { - display: inline; -} -#sub-nav li a { - display: block; - font-size: 1.2em; -} - -/* content */ -#content{ - font-size: 1.2em; -} - -#petlogo { - display: block; - margin-left: auto; - margin-right: auto; -} - -#main{ - padding-left: 200px; -} -#main label{ - display: block; - padding: 1em 0; -} -/* content - application */ - -#footer { - clear: both; - padding-top: 1em; -} -#copyright{ - float: left; -} -ul#legal{ - list-style: none; - width: 300px; - overflow: hidden; - float: right; -} -ul#legal li{ - display: inline; - padding: 0px 4px 0px 5px; - border-left: 1px solid #000; - margin-left: -1px; -} -ul#legal li a{ - -} \ No newline at end of file From e7a6c22ef05ba86c57477b3971818459c471f6e6 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 5 May 2009 22:14:54 +0000 Subject: [PATCH 006/887] logging --- .../src/main/resources/log4j.xml | 2 +- .../src/test/resources/log4j.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.springframework.samples.petclinic/src/main/resources/log4j.xml b/org.springframework.samples.petclinic/src/main/resources/log4j.xml index d65fd3775..e09edc3bf 100644 --- a/org.springframework.samples.petclinic/src/main/resources/log4j.xml +++ b/org.springframework.samples.petclinic/src/main/resources/log4j.xml @@ -12,7 +12,7 @@ > - + diff --git a/org.springframework.samples.petclinic/src/test/resources/log4j.xml b/org.springframework.samples.petclinic/src/test/resources/log4j.xml index 6cd59573d..f2c798d46 100644 --- a/org.springframework.samples.petclinic/src/test/resources/log4j.xml +++ b/org.springframework.samples.petclinic/src/test/resources/log4j.xml @@ -12,7 +12,7 @@ > - + From d8014ae193f5190625a338c4d7faf095ddcd65bd Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 16:37:16 +0000 Subject: [PATCH 007/887] petclinic tiles --- .../src/main/webapp/WEB-INF/layouts/page.jsp | 45 +++++++++++++++++++ .../src/main/webapp/WEB-INF/tiles.xml | 21 +++++++++ 2 files changed, 66 insertions(+) create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp new file mode 100644 index 000000000..f0a2acda9 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp @@ -0,0 +1,45 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> +<%@ page session="false" %> + + + <tiles:insertAttribute name="title"/> + + + +
+ +
+ +
+ +
+ + \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml new file mode 100644 index 000000000..92a429fa9 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 098cfb60b6de7d75d9c2d39f6b2ee23b8b6ead43 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 17:50:03 +0000 Subject: [PATCH 008/887] upgrade to spring 3.0.0.m3 --- org.springframework.samples.petclinic/pom.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/org.springframework.samples.petclinic/pom.xml b/org.springframework.samples.petclinic/pom.xml index 808c5f6f6..0f1d00bae 100644 --- a/org.springframework.samples.petclinic/pom.xml +++ b/org.springframework.samples.petclinic/pom.xml @@ -8,7 +8,7 @@ war 1.0.0-SNAPSHOT - 2.5.6 + 3.0.0.M3 @@ -114,6 +114,13 @@ test
+ + + org.springsource.maven.snapshot + SpringSource Maven Central-compatible Milestone Repository + http://maven.springframework.org/milestone + + From 24ea3e9916d08cd2034f4f97d4af844ebf7c2bae Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 17:55:57 +0000 Subject: [PATCH 009/887] artifact id update --- org.springframework.samples.petclinic/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.springframework.samples.petclinic/pom.xml b/org.springframework.samples.petclinic/pom.xml index 0f1d00bae..3f392d89b 100644 --- a/org.springframework.samples.petclinic/pom.xml +++ b/org.springframework.samples.petclinic/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.springframework - samples + org.springframework.samples + org.springframework.samples.petclinic org.springframework.samples.petclinic war 1.0.0-SNAPSHOT From 775e85dd1716c8c3da53722a645f2cd51bdf4abc Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 18:02:27 +0000 Subject: [PATCH 010/887] polish --- org.springframework.samples.petclinic/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.springframework.samples.petclinic/pom.xml b/org.springframework.samples.petclinic/pom.xml index 3f392d89b..df94a059a 100644 --- a/org.springframework.samples.petclinic/pom.xml +++ b/org.springframework.samples.petclinic/pom.xml @@ -97,7 +97,7 @@ javax.servlet servlet-api - 2.4 + 2.5 provided From cc199a7a1581f76403d7c88b420caa452cd4f595 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 18:06:20 +0000 Subject: [PATCH 011/887] polish --- .../src/main/webapp/WEB-INF/spring/mvc-config.xml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml index 15466b8fc..01be04080 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml @@ -31,13 +31,8 @@ - - - - - - - + + From 2742ccbd4a0a3ee72b1fde500c093a9da41322ce Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 18:18:31 +0000 Subject: [PATCH 012/887] moved pets under owners --- .../samples/petclinic/{owner => owners}/Owner.java | 2 +- .../samples/petclinic/{owner => owners}/OwnerController.java | 2 +- .../samples/petclinic/{owner => owners}/OwnerRepository.java | 2 +- .../petclinic/{owner => owners}/OwnersController.java | 2 +- .../petclinic/{owner => owners}/StubOwnerRepository.java | 2 +- .../samples/petclinic/owners/pets/Gender.java | 5 +++++ .../samples/petclinic/{pet => owners/pets}/Pet.java | 2 +- .../petclinic/{pet => owners/pets}/PetController.java | 2 +- .../petclinic/{pet => owners/pets}/PetRepository.java | 2 +- .../petclinic/{pet => owners/pets}/StubPetRepository.java | 2 +- .../org/springframework/samples/petclinic/pet/Gender.java | 5 ----- 11 files changed, 14 insertions(+), 14 deletions(-) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{owner => owners}/Owner.java (83%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{owner => owners}/OwnerController.java (94%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{owner => owners}/OwnerRepository.java (77%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{owner => owners}/OwnersController.java (95%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{owner => owners}/StubOwnerRepository.java (86%) create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{pet => owners/pets}/Pet.java (84%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{pet => owners/pets}/PetController.java (95%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{pet => owners/pets}/PetRepository.java (63%) rename org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/{pet => owners/pets}/StubPetRepository.java (79%) delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java similarity index 83% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java index eab0654c0..ec19625a3 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.owners; public class Owner { diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java similarity index 94% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java index 548889c7e..11be755b2 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.owners; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.util.ResponseContext; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java similarity index 77% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java index e151f45e2..762ba5dc8 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.owners; import java.util.Collection; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java similarity index 95% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java index fe42ab02c..93fd5b9e7 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnersController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.owners; import java.util.Collection; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java similarity index 86% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java index b9da84907..5c3406bf0 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owner/StubOwnerRepository.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.owners; import java.util.Collection; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java new file mode 100644 index 000000000..6691f557e --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java @@ -0,0 +1,5 @@ +package org.springframework.samples.petclinic.owners.pets; + +public enum Gender { + MALE, FEMALE +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java similarity index 84% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java index e0765ee4c..63f189d3a 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Pet.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.pet; +package org.springframework.samples.petclinic.owners.pets; import java.util.Date; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java similarity index 95% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java index 106754071..d789f9151 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.pet; +package org.springframework.samples.petclinic.owners.pets; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.util.ResponseContext; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java similarity index 63% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java index c3b52f4f1..76afff837 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/PetRepository.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.pet; +package org.springframework.samples.petclinic.owners.pets; public interface PetRepository { diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java similarity index 79% rename from org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java rename to org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java index 1c0e731a5..0dae2f563 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/StubPetRepository.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java @@ -1,4 +1,4 @@ -package org.springframework.samples.petclinic.pet; +package org.springframework.samples.petclinic.owners.pets; import org.springframework.stereotype.Repository; diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java deleted file mode 100644 index e67a95aa6..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/pet/Gender.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.samples.petclinic.pet; - -public enum Gender { - MALE, FEMALE -} From 9106b8383489c4db969feb0198c6dd81f6f96ea1 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 18:22:37 +0000 Subject: [PATCH 013/887] polish --- .../src/main/webapp/WEB-INF/layouts/page.jsp | 4 +--- .../src/main/webapp/WEB-INF/spring/mvc-config.xml | 12 +++--------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp index f0a2acda9..df5ed7bae 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp @@ -16,8 +16,7 @@
  • ">Sign Out
  • -
  • ">Sign In
  • -
  • ">Register
  • +
  • ">Sign In
  • @@ -26,7 +25,6 @@
  • ">Home
  • Appointments
  • Owners
  • -
  • Pets
  • diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml index 01be04080..8f2b7f1d2 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml @@ -9,17 +9,11 @@ + If no annotation-based path mapping is found, Spring MVC sends a 404 response and logs a pageNotFound warning. --> - - - - - @@ -27,12 +21,12 @@ - + - + From 75504b859f8abbbe7cc05324b7842e4a71d90d4f Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 19:28:19 +0000 Subject: [PATCH 014/887] polish --- .../main/webapp/WEB-INF/appointments/calendar.jsp | 2 ++ .../src/main/webapp/WEB-INF/owners/search.jsp | 2 ++ .../src/main/webapp/WEB-INF/tiles.xml | 14 ++++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp new file mode 100644 index 000000000..692d0bb0d --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp @@ -0,0 +1,2 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +

    Appointment Calendar

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp new file mode 100644 index 000000000..f098b9d19 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp @@ -0,0 +1,2 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +

    Search Owners

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml index 92a429fa9..64d5e66b5 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml @@ -13,9 +13,19 @@ - + - + + + + + + + + + + + \ No newline at end of file From d4fc5b036bbd851dab9fabe4460c9578c7ff2da0 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 19:28:33 +0000 Subject: [PATCH 015/887] polish --- .../appointments/AppointmentsController.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java new file mode 100644 index 000000000..c8abc0ab8 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java @@ -0,0 +1,16 @@ +package org.springframework.samples.petclinic.appointments; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +@RequestMapping("/appointments") +public class AppointmentsController { + + @RequestMapping(method = RequestMethod.GET) + public void get() { + + } + +} From 090136418a5e2d939ee4fe09e9be74757f497bb8 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 6 May 2009 21:43:08 +0000 Subject: [PATCH 016/887] owner pages --- .../samples/petclinic/owners/Owner.java | 49 ++++++++++++++++++- .../petclinic/owners/OwnerController.java | 15 +++--- .../petclinic/owners/OwnerRepository.java | 2 +- .../petclinic/owners/OwnerSearchForm.java | 15 ++++++ .../petclinic/owners/OwnersController.java | 12 ++--- .../petclinic/owners/StubOwnerRepository.java | 5 +- .../petclinic/owners/pets/PetController.java | 6 +-- .../petclinic/util/ExternalContext.java | 22 +++++++++ .../petclinic/util/ResponseContext.java | 9 ---- .../src/main/webapp/WEB-INF/layouts/page.jsp | 6 +-- .../main/webapp/WEB-INF/owners/addNewForm.jsp | 15 ++++++ .../main/webapp/WEB-INF/owners/content.jsp | 11 +++++ .../WEB-INF/owners/{search.jsp => owner.jsp} | 2 +- .../main/webapp/WEB-INF/owners/searchForm.jsp | 12 +++++ .../webapp/WEB-INF/owners/searchResults.jsp | 2 + .../src/main/webapp/WEB-INF/tiles.xml | 44 +++++++++++++++-- 16 files changed, 190 insertions(+), 37 deletions(-) create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp rename org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/{search.jsp => owner.jsp} (74%) create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java index ec19625a3..934accd06 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java @@ -14,12 +14,57 @@ public class Owner { private String telephone; + public Owner() { + + } + + public Owner(Long id) { + this.id = id; + } + public Long getId() { return id; } - - public String getName() { + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { return lastName; } + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getTelephone() { + return telephone; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java index 11be755b2..d357c0471 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java @@ -1,8 +1,10 @@ package org.springframework.samples.petclinic.owners; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.util.ResponseContext; +import org.springframework.samples.petclinic.util.ExternalContext; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -18,19 +20,20 @@ public class OwnerController { } @RequestMapping(method=RequestMethod.GET) - public Owner get(Long owner) { - return repository.getOwner(owner); + public String get(@PathVariable Long owner, Model model) { + model.addAttribute(repository.getOwner(owner)); + return "owner"; } @RequestMapping(value="/edit", method=RequestMethod.GET) - public Owner getEditForm(Long owner) { + public Owner getEditForm(@PathVariable Long owner) { return repository.getOwner(owner); } @RequestMapping(method = RequestMethod.PUT) - public void put(Owner owner, ResponseContext response) { + public void put(Owner owner, ExternalContext response) { repository.saveOwner(owner); - response.redirect(owner.getName()); + response.redirect(owner.getId()); } } \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java index 762ba5dc8..10702243d 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java @@ -8,6 +8,6 @@ public interface OwnerRepository { Owner getOwner(Long id); - void saveOwner(Owner owner); + Long saveOwner(Owner owner); } \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java new file mode 100644 index 000000000..c9c589607 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java @@ -0,0 +1,15 @@ +package org.springframework.samples.petclinic.owners; + +public class OwnerSearchForm { + + private String lastName; + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java index 93fd5b9e7..f41e89571 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java @@ -3,7 +3,6 @@ package org.springframework.samples.petclinic.owners; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.util.ResponseContext; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -21,8 +20,8 @@ public class OwnersController { } @RequestMapping(method = RequestMethod.GET) - public void get() { - + public OwnerSearchForm get() { + return new OwnerSearchForm(); } @RequestMapping(value="/search", method = RequestMethod.GET) @@ -36,9 +35,10 @@ public class OwnersController { } @RequestMapping(method = RequestMethod.POST) - public void post(Owner owner, ResponseContext response) { - repository.saveOwner(owner); - response.redirect(owner.getName()); + public String post(Owner owner) { + Long ownerId = repository.saveOwner(owner); + // TODO simplify this since /owners is the current resource already? + return "redirect:/owners/" + ownerId; } } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java index 5c3406bf0..d442ee994 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java @@ -12,10 +12,11 @@ public class StubOwnerRepository implements OwnerRepository { } public Owner getOwner(Long id) { - return null; + return new Owner(id); } - public void saveOwner(Owner owner) { + public Long saveOwner(Owner owner) { + return 1L; } } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java index d789f9151..a0a7e74e8 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java @@ -1,7 +1,7 @@ package org.springframework.samples.petclinic.owners.pets; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.util.ResponseContext; +import org.springframework.samples.petclinic.util.ExternalContext; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -28,13 +28,13 @@ public class PetController { } @RequestMapping(method = RequestMethod.PUT) - public void put(Pet pet, ResponseContext response) { + public void put(Pet pet, ExternalContext response) { repository.savePet(pet); response.redirect(pet.getName()); } @RequestMapping(method = RequestMethod.DELETE) - public void delete(Long owner, String pet, ResponseContext context) { + public void delete(Long owner, String pet, ExternalContext context) { context.forResource("owners").redirect(owner); } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java new file mode 100644 index 000000000..5f4fc1e3e --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java @@ -0,0 +1,22 @@ +package org.springframework.samples.petclinic.util; + +import org.springframework.ui.Model; + +// This is an idea as a context object to make avail to @Controller methods to interact with Dispatcher +public interface ExternalContext { + + Model getModel(); + + void selectView(String viewName); + + void renderFragment(String fragment); + + void redirect(Object resource); + + ExternalContext forResource(Object resource); + + Object getNativeRequest(); + + Object getNativeResponse(); + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java deleted file mode 100644 index fd9d5f674..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ResponseContext.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.springframework.samples.petclinic.util; - -public interface ResponseContext { - - void redirect(Object resource); - - ResponseContext forResource(Object resource); - -} diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp index df5ed7bae..b92d0ffa1 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp @@ -22,9 +22,9 @@ diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp new file mode 100644 index 000000000..68ad9dd6f --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp @@ -0,0 +1,15 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +

    Add New Owner

    + + + + First Name + + + + Last Name + + + + \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp new file mode 100644 index 000000000..c0dae0e50 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp @@ -0,0 +1,11 @@ +<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> + + +
    + +
    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp similarity index 74% rename from org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp rename to org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp index f098b9d19..85dcec17b 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/search.jsp +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp @@ -1,2 +1,2 @@ <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -

    Search Owners

    \ No newline at end of file +

    Owner Details

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp new file mode 100644 index 000000000..1a5830d29 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp @@ -0,0 +1,12 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + +

    Search Owners

    + + + + Last Name + + + + \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp new file mode 100644 index 000000000..c01fd8abb --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp @@ -0,0 +1,2 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +

    Search Results

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml index 64d5e66b5..87229ac06 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml @@ -18,14 +18,50 @@ - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 2781809c095c8cf53c60a524499a9a74649ab506 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 7 May 2009 20:39:59 +0000 Subject: [PATCH 017/887] appointments --- .../petclinic/appointments/Appointment.java | 37 ++++++++++ .../appointments/AppointmentBook.java | 13 ++++ .../appointments/AppointmentForm.java | 67 +++++++++++++++++++ .../petclinic/appointments/Appointments.java | 15 +++++ .../appointments/AppointmentsController.java | 30 ++++++++- .../appointments/StubAppointmentBook.java | 23 +++++++ .../samples/petclinic/owners/Owner.java | 13 ++-- .../petclinic/owners/OwnersController.java | 1 - .../WEB-INF/appointments/addNewForm.jsp | 31 +++++++++ .../webapp/WEB-INF/appointments/content.jsp | 11 +++ .../src/main/webapp/WEB-INF/tiles.xml | 24 ++++++- 11 files changed, 252 insertions(+), 13 deletions(-) create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java create mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp create mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java new file mode 100644 index 000000000..d193117e0 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java @@ -0,0 +1,37 @@ +package org.springframework.samples.petclinic.appointments; + +import java.util.Date; + +public class Appointment { + + private String owner; + + private String ownerPhone; + + private String pet; + + private String notes; + + private Date dateTime; + + public String getOwner() { + return owner; + } + + public String getOwnerPhone() { + return ownerPhone; + } + + public String getPet() { + return pet; + } + + public Date getDateTime() { + return dateTime; + } + + public String getNotes() { + return notes; + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java new file mode 100644 index 000000000..55ebd488b --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java @@ -0,0 +1,13 @@ +package org.springframework.samples.petclinic.appointments; + +import java.util.Date; + +public interface AppointmentBook { + + Appointments getAppointmentsForToday(); + + Appointments getAppointmentsForDay(Date day); + + Long createAppointment(AppointmentForm form); + +} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java new file mode 100644 index 000000000..d3d7abaaf --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java @@ -0,0 +1,67 @@ +package org.springframework.samples.petclinic.appointments; + +import java.util.Date; + +public class AppointmentForm { + + private Long doctor; + + private Long owner; + + private String pet; + + private Date date; + + private Date time; + + private String notes; + + public Long getDoctor() { + return doctor; + } + + public void setDoctor(Long doctor) { + this.doctor = doctor; + } + + public Long getOwner() { + return owner; + } + + public void setOwner(Long owner) { + this.owner = owner; + } + + public String getPet() { + return pet; + } + + public void setPet(String pet) { + this.pet = pet; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + +} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java new file mode 100644 index 000000000..f2aa85e68 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java @@ -0,0 +1,15 @@ +package org.springframework.samples.petclinic.appointments; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class Appointments { + + private Map> vetAppointments = new LinkedHashMap>(); + + public Map> getAllByVet() { + return vetAppointments; + } + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java index c8abc0ab8..e3c786017 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java @@ -1,6 +1,10 @@ package org.springframework.samples.petclinic.appointments; +import java.util.Date; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -8,9 +12,31 @@ import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/appointments") public class AppointmentsController { + private AppointmentBook appointmentBook; + + @Autowired + public AppointmentsController(AppointmentBook appointmentBook) { + this.appointmentBook = appointmentBook; + } + @RequestMapping(method = RequestMethod.GET) - public void get() { - + public Appointments get() { + return appointmentBook.getAppointmentsForToday(); + } + + @RequestMapping(value="/{day}", method = RequestMethod.GET) + public Appointments getForDay(@PathVariable Date day) { + return appointmentBook.getAppointmentsForDay(day); + } + + @RequestMapping(value="/new", method = RequestMethod.GET) + public AppointmentForm getNewForm() { + return new AppointmentForm(); } + @RequestMapping(method = RequestMethod.POST) + public String post(AppointmentForm form) { + appointmentBook.createAppointment(form); + return "redirect:/appointments"; + } } diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java new file mode 100644 index 000000000..92525a365 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java @@ -0,0 +1,23 @@ +package org.springframework.samples.petclinic.appointments; + +import java.util.Date; + +import org.springframework.stereotype.Repository; + +@Repository +public class StubAppointmentBook implements AppointmentBook { + + public Appointments getAppointmentsForDay(Date day) { + return new Appointments(); + } + + public Appointments getAppointmentsForToday() { + return new Appointments(); + } + + public Long createAppointment(AppointmentForm form) { + return 1L; + } + + +} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java index 934accd06..9841482b5 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java @@ -12,7 +12,7 @@ public class Owner { private String city; - private String telephone; + private String phone; public Owner() { @@ -58,13 +58,12 @@ public class Owner { this.city = city; } - public String getTelephone() { - return telephone; + public String getPhone() { + return phone; } - public void setTelephone(String telephone) { - this.telephone = telephone; + public void setPhone(String phone) { + this.phone = phone; } - -} +} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java index f41e89571..f24cd0745 100644 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java +++ b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java @@ -37,7 +37,6 @@ public class OwnersController { @RequestMapping(method = RequestMethod.POST) public String post(Owner owner) { Long ownerId = repository.saveOwner(owner); - // TODO simplify this since /owners is the current resource already? return "redirect:/owners/" + ownerId; } diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp new file mode 100644 index 000000000..997640df0 --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp @@ -0,0 +1,31 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +

    Add New Appointment

    + + + + Doctor + + + + Owner + + + + Pet + + + + Date + + + + Time + + + + Notes + + + + \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp new file mode 100644 index 000000000..b171fb5ad --- /dev/null +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp @@ -0,0 +1,11 @@ +<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> + + +
    + +
    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml index 87229ac06..e87543e73 100644 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml +++ b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml @@ -17,13 +17,30 @@ + + - + + + + + + + + + + + + + + + + @@ -36,7 +53,7 @@ - + @@ -54,7 +71,7 @@ - + @@ -64,4 +81,5 @@ + \ No newline at end of file From 9dd07f05f39662a7c37dbaac26976b2481a63afd Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 25 Nov 2009 16:53:14 +0000 Subject: [PATCH 018/887] SPR-6447 + added basic files --- .classpath | 43 ++++++++++ .project | 36 +++++++++ petclinic.iml | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ readme.txt | 105 +++++++++++++++++++++++++ 4 files changed, 395 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 petclinic.iml create mode 100644 readme.txt diff --git a/.classpath b/.classpath new file mode 100644 index 000000000..b60cdffa6 --- /dev/null +++ b/.classpath @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 000000000..ee1dfb9be --- /dev/null +++ b/.project @@ -0,0 +1,36 @@ + + + petclinic-classic + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/petclinic.iml b/petclinic.iml new file mode 100644 index 000000000..134ccb632 --- /dev/null +++ b/petclinic.iml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jar://$IVY_CACHE$/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-1.1.2.jar!/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme.txt b/readme.txt new file mode 100644 index 000000000..aee19b7ff --- /dev/null +++ b/readme.txt @@ -0,0 +1,105 @@ +========================================================================== +=== Spring PetClinic Sample Application +========================================================================== + +@author Ken Krebs +@author Juergen Hoeller +@author Rob Harrop +@author Costin Leau +@author Sam Brannen +@author Scott Andrews + +========================================================================== +=== Data Access Strategies +========================================================================== + +PetClinic features alternative DAO implementations and application +configurations for JDBC, Hibernate, and JPA, with HSQLDB and MySQL as +target databases. The default PetClinic configuration is JDBC on HSQLDB. +See "src/main/resources/jdbc.properties" as well as web.xml and +applicationContext-*.xml in the "src/main/webapp/WEB-INF" folder for +details. A simple comment change in web.xml switches between the data +access strategies. + +The JDBC and Hibernate versions of PetClinic also demonstrate JMX support +via the use of for exporting MBeans. +SimpleJdbcClinic exposes the SimpleJdbcClinicMBean management interface +via JMX through the use of the @ManagedResource and @ManagedOperation +annotations; whereas, the HibernateStatistics service is exposed via JMX +through auto-detection of the service MBean. You can start up the JDK's +JConsole to manage the exported bean. + +All data access strategies can work with JTA for transaction management by +activating the JtaTransactionManager and a JndiObjectFactoryBean that +refers to a transactional container DataSource. The default for JDBC is +DataSourceTransactionManager; for Hibernate, HibernateTransactionManager; +for JPA, JpaTransactionManager. Those local strategies allow for working +with any locally defined DataSource. + +Note that the sample configurations for JDBC, Hibernate, and JPA configure +a BasicDataSource from the Apache Commons DBCP project for connection +pooling. + +========================================================================== +=== Build and Deployment +========================================================================== + +The Spring PetClinic sample application is built using Spring Build, which +is a custom build solution based on Ant and Ivy for dependency management. +For deployment, the web application needs to be built with Apache Ant 1.6 +or higher. When the project is first built, Spring Build will use Ivy to +automatically download all required dependencies. Thus the initial build +may take a few minutes depending on the speed of your Internet connection, +but subsequent builds will be much faster. + +Available build commands: + +- ant clean --> cleans the project +- ant clean test --> cleans the project and runs all tests +- ant clean jar --> cleans the project and builds the WAR + +After building the project with "ant clean jar", you will find the +resulting WAR file in the "target/artifacts" directory. By default, an +embedded HSQLDB instance in configured. No other steps are necessary to +get the data source up and running: you can simply deploy the built WAR +file directly to your Servlet container. + +For MySQL, you'll need to use the corresponding schema and SQL scripts in +the "db/mysql" subdirectory. Follow the steps outlined in +"db/mysql/petclinic_db_setup_mysql.txt" for explicit details. + +In you intend to use a local DataSource, the JDBC settings can be adapted +in "src/main/resources/jdbc.properties". To use a JTA DataSource, you need +to set up corresponding DataSources in your Java EE container. + +Notes on enabling Log4J: + - Log4J is disabled by default due to issues with JBoss. + - Uncomment the Log4J listener in "WEB-INF/web.xml" to enable logging. + +========================================================================== +=== JPA on Tomcat +========================================================================== + +This section provides tips on using the Java Persistence API (JPA) on +Apache Tomcat 4.x or higher with a persistence provider that requires +class instrumentation (such as TopLink Essentials). + +To use JPA class instrumentation, Tomcat has to be instructed to use a +custom class loader which supports instrumentation. See the JPA section of +the Spring reference manual for complete details. + +The basic steps are: + - Copy "org.springframework.instrument.tomcat-3.0.0.RELEASE.jar" from the + Spring distribution to "TOMCAT_HOME/server/lib". + - If you're running on Tomcat 5.x, modify "TOMCAT_HOME/conf/server.xml" + and add a new "" element for 'petclinic' (see below). You can + alternatively deploy the WAR including "META-INF/context.xml" from this + sample application's "src/main/webapp" directory, in which case you + will need to uncomment the Loader element in that file to enable the + use of the TomcatInstrumentableClassLoader. + + + + + ... + From 521d01db950e357cf81ef78c50daf290e92b309c Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 25 Nov 2009 18:45:52 +0000 Subject: [PATCH 019/887] SPR-6447 SPR-6448 + commit the gross of the files + added maven pom --- db/build.xml | 85 ++ db/dropTables.txt | 7 + db/emptyDB.txt | 7 + db/mysql/createDB.txt | 3 + db/mysql/dropDB.txt | 1 + db/mysql/initDB.txt | 58 + db/mysql/petclinic_db_setup_mysql.txt | 22 + db/mysql/petclinic_tomcat_mysql.xml | 64 + db/petclinic_tomcat_all.xml | 112 ++ db/populateDB.txt | 53 + pom.xml | 233 ++++ readme.txt | 18 +- .../samples/petclinic/BaseEntity.java | 27 + .../samples/petclinic/Clinic.java | 82 ++ .../samples/petclinic/NamedEntity.java | 28 + .../samples/petclinic/Owner.java | 127 ++ .../samples/petclinic/Person.java | 32 + .../samples/petclinic/Pet.java | 77 ++ .../samples/petclinic/PetType.java | 8 + .../samples/petclinic/Specialty.java | 10 + .../samples/petclinic/Vet.java | 52 + .../samples/petclinic/Vets.java | 43 + .../samples/petclinic/Visit.java | 70 + .../aspects/AbstractTraceAspect.java | 31 + .../aspects/CallMonitoringAspect.java | 81 ++ .../petclinic/aspects/UsageLogAspect.java | 48 + .../config/DbcpDataSourceFactory.java | 261 ++++ .../petclinic/hibernate/HibernateClinic.java | 98 ++ .../petclinic/hibernate/package-info.java | 9 + .../samples/petclinic/jdbc/JdbcPet.java | 35 + .../petclinic/jdbc/SimpleJdbcClinic.java | 342 +++++ .../petclinic/jdbc/SimpleJdbcClinicMBean.java | 20 + .../samples/petclinic/jdbc/package-info.java | 9 + .../petclinic/jpa/EntityManagerClinic.java | 96 ++ .../samples/petclinic/jpa/package-info.java | 9 + .../samples/petclinic/package-info.java | 8 + ...entialsHSQLPlatformWithNativeSequence.java | 56 + .../petclinic/toplink/package-info.java | 10 + .../samples/petclinic/util/EntityUtils.java | 41 + .../petclinic/validation/OwnerValidator.java | 43 + .../petclinic/validation/PetValidator.java | 25 + .../petclinic/validation/VisitValidator.java | 21 + .../petclinic/validation/package-info.java | 9 + .../samples/petclinic/web/AddOwnerForm.java | 65 + .../samples/petclinic/web/AddPetForm.java | 77 ++ .../samples/petclinic/web/AddVisitForm.java | 69 + .../web/ClinicBindingInitializer.java | 37 + .../petclinic/web/ClinicController.java | 89 ++ .../samples/petclinic/web/EditOwnerForm.java | 65 + .../samples/petclinic/web/EditPetForm.java | 80 ++ .../samples/petclinic/web/FindOwnersForm.java | 74 ++ .../samples/petclinic/web/PetTypeEditor.java | 30 + .../samples/petclinic/web/VisitsAtomView.java | 82 ++ .../samples/petclinic/web/package-info.java | 8 + src/main/java/overview.html | 7 + src/main/resources/jdbc.properties | 63 + src/main/resources/log4j.properties | 18 + src/main/resources/messages.properties | 8 + src/main/resources/messages_de.properties | 8 + src/main/resources/messages_en.properties | 1 + src/main/resources/petclinic.hbm.xml | 74 ++ src/main/webapp/META-INF/aop.xml | 18 + src/main/webapp/META-INF/context.xml | 7 + .../webapp/META-INF/hsqldb/dropTables.txt | 7 + src/main/webapp/META-INF/hsqldb/initDB.txt | 55 + .../webapp/META-INF/hsqldb/populateDB.txt | 53 + src/main/webapp/META-INF/orm.xml | 122 ++ src/main/webapp/META-INF/persistence.xml | 16 + .../WEB-INF/applicationContext-hibernate.xml | 89 ++ .../WEB-INF/applicationContext-jdbc.xml | 85 ++ .../webapp/WEB-INF/applicationContext-jpa.xml | 101 ++ .../webapp/WEB-INF/classes/log4j.properties | 18 + .../WEB-INF/classes/messages.properties | 8 + .../WEB-INF/classes/messages_de.properties | 8 + .../WEB-INF/classes/messages_en.properties | 1 + src/main/webapp/WEB-INF/geronimo-web.xml | 6 + .../webapp/WEB-INF/jsp/dataAccessFailure.jsp | 19 + src/main/webapp/WEB-INF/jsp/footer.jsp | 12 + src/main/webapp/WEB-INF/jsp/header.jsp | 14 + src/main/webapp/WEB-INF/jsp/includes.jsp | 5 + src/main/webapp/WEB-INF/jsp/owners/form.jsp | 61 + src/main/webapp/WEB-INF/jsp/owners/list.jsp | 34 + src/main/webapp/WEB-INF/jsp/owners/search.jsp | 26 + src/main/webapp/WEB-INF/jsp/owners/show.jsp | 108 ++ src/main/webapp/WEB-INF/jsp/pets/form.jsp | 56 + .../webapp/WEB-INF/jsp/pets/visitForm.jsp | 68 + .../webapp/WEB-INF/jsp/uncaughtException.jsp | 49 + src/main/webapp/WEB-INF/jsp/vets.jsp | 31 + src/main/webapp/WEB-INF/jsp/welcome.jsp | 15 + src/main/webapp/WEB-INF/petclinic-servlet.xml | 110 ++ src/main/webapp/WEB-INF/web.xml | 161 +++ src/main/webapp/html/tutorial.html | 1153 +++++++++++++++++ src/main/webapp/images/banner-graphic.png | Bin 0 -> 13773 bytes src/main/webapp/images/bullet-arrow.png | Bin 0 -> 2954 bytes src/main/webapp/images/pets.png | Bin 0 -> 55318 bytes src/main/webapp/images/springsource-logo.png | Bin 0 -> 4974 bytes src/main/webapp/images/submit-bg.png | Bin 0 -> 2820 bytes src/main/webapp/styles/petclinic.css | 234 ++++ .../petclinic/AbstractClinicTests.java | 224 ++++ .../samples/petclinic/OwnerTests.java | 27 + .../samples/petclinic/PetClinicTestSuite.java | 29 + .../hibernate/HibernateClinicTests.java | 20 + .../petclinic/jdbc/SimpleJdbcClinicTests.java | 19 + .../petclinic/jpa/AbstractJpaClinicTests.java | 199 +++ .../jpa/EntityManagerClinicTests.java | 51 + .../HibernateEntityManagerClinicTests.java | 26 + .../jpa/OpenJpaEntityManagerClinicTests.java | 27 + .../petclinic/web/VisitsAtomViewTest.java | 90 ++ src/test/resources/log4j.xml | 28 + .../petclinic/AbstractClinicTests-context.xml | 22 + .../HibernateClinicTests-context.xml | 32 + .../jdbc/SimpleJdbcClinicTests-context.xml | 11 + .../jpa/applicationContext-entityManager.xml | 16 + .../applicationContext-hibernateAdapter.xml | 9 + .../jpa/applicationContext-jpaCommon.xml | 31 + .../jpa/applicationContext-openJpaAdapter.xml | 9 + .../jpa/applicationContext-toplinkAdapter.xml | 9 + 117 files changed, 6945 insertions(+), 10 deletions(-) create mode 100644 db/build.xml create mode 100644 db/dropTables.txt create mode 100644 db/emptyDB.txt create mode 100644 db/mysql/createDB.txt create mode 100644 db/mysql/dropDB.txt create mode 100644 db/mysql/initDB.txt create mode 100644 db/mysql/petclinic_db_setup_mysql.txt create mode 100644 db/mysql/petclinic_tomcat_mysql.xml create mode 100644 db/petclinic_tomcat_all.xml create mode 100644 db/populateDB.txt create mode 100644 pom.xml create mode 100644 src/main/java/org/springframework/samples/petclinic/BaseEntity.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Clinic.java create mode 100644 src/main/java/org/springframework/samples/petclinic/NamedEntity.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Owner.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Person.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Pet.java create mode 100644 src/main/java/org/springframework/samples/petclinic/PetType.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Specialty.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Vet.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Vets.java create mode 100644 src/main/java/org/springframework/samples/petclinic/Visit.java create mode 100644 src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java create mode 100644 src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java create mode 100644 src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java create mode 100644 src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java create mode 100644 src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java create mode 100644 src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java create mode 100644 src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java create mode 100644 src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java create mode 100644 src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java create mode 100644 src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java create mode 100644 src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java create mode 100644 src/main/java/org/springframework/samples/petclinic/jpa/package-info.java create mode 100644 src/main/java/org/springframework/samples/petclinic/package-info.java create mode 100644 src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java create mode 100644 src/main/java/org/springframework/samples/petclinic/toplink/package-info.java create mode 100644 src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java create mode 100644 src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java create mode 100644 src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java create mode 100644 src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java create mode 100644 src/main/java/org/springframework/samples/petclinic/validation/package-info.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/ClinicController.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java create mode 100644 src/main/java/org/springframework/samples/petclinic/web/package-info.java create mode 100644 src/main/java/overview.html create mode 100644 src/main/resources/jdbc.properties create mode 100644 src/main/resources/log4j.properties create mode 100644 src/main/resources/messages.properties create mode 100644 src/main/resources/messages_de.properties create mode 100644 src/main/resources/messages_en.properties create mode 100644 src/main/resources/petclinic.hbm.xml create mode 100644 src/main/webapp/META-INF/aop.xml create mode 100644 src/main/webapp/META-INF/context.xml create mode 100644 src/main/webapp/META-INF/hsqldb/dropTables.txt create mode 100644 src/main/webapp/META-INF/hsqldb/initDB.txt create mode 100644 src/main/webapp/META-INF/hsqldb/populateDB.txt create mode 100644 src/main/webapp/META-INF/orm.xml create mode 100644 src/main/webapp/META-INF/persistence.xml create mode 100644 src/main/webapp/WEB-INF/applicationContext-hibernate.xml create mode 100644 src/main/webapp/WEB-INF/applicationContext-jdbc.xml create mode 100644 src/main/webapp/WEB-INF/applicationContext-jpa.xml create mode 100644 src/main/webapp/WEB-INF/classes/log4j.properties create mode 100644 src/main/webapp/WEB-INF/classes/messages.properties create mode 100644 src/main/webapp/WEB-INF/classes/messages_de.properties create mode 100644 src/main/webapp/WEB-INF/classes/messages_en.properties create mode 100644 src/main/webapp/WEB-INF/geronimo-web.xml create mode 100644 src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/footer.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/header.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/includes.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/owners/form.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/owners/list.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/owners/search.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/owners/show.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/pets/form.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/uncaughtException.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/vets.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/welcome.jsp create mode 100644 src/main/webapp/WEB-INF/petclinic-servlet.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/html/tutorial.html create mode 100644 src/main/webapp/images/banner-graphic.png create mode 100644 src/main/webapp/images/bullet-arrow.png create mode 100644 src/main/webapp/images/pets.png create mode 100644 src/main/webapp/images/springsource-logo.png create mode 100644 src/main/webapp/images/submit-bg.png create mode 100644 src/main/webapp/styles/petclinic.css create mode 100644 src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/OwnerTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java create mode 100644 src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java create mode 100644 src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java create mode 100644 src/test/resources/log4j.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml create mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml diff --git a/db/build.xml b/db/build.xml new file mode 100644 index 000000000..b6d09936b --- /dev/null +++ b/db/build.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/db/dropTables.txt b/db/dropTables.txt new file mode 100644 index 000000000..90ae6329f --- /dev/null +++ b/db/dropTables.txt @@ -0,0 +1,7 @@ +DROP TABLE visits; +DROP TABLE pets; +DROP TABLE owners; +DROP TABLE types; +DROP TABLE vet_specialties; +DROP TABLE specialties; +DROP TABLE vets; diff --git a/db/emptyDB.txt b/db/emptyDB.txt new file mode 100644 index 000000000..d5dd8728c --- /dev/null +++ b/db/emptyDB.txt @@ -0,0 +1,7 @@ +DELETE FROM vets; +DELETE FROM specialties; +DELETE FROM vet_specialties; +DELETE FROM types; +DELETE FROM owners; +DELETE FROM pets; +DELETE FROM visits; diff --git a/db/mysql/createDB.txt b/db/mysql/createDB.txt new file mode 100644 index 000000000..5b4b3859e --- /dev/null +++ b/db/mysql/createDB.txt @@ -0,0 +1,3 @@ +CREATE DATABASE petclinic; + +GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; \ No newline at end of file diff --git a/db/mysql/dropDB.txt b/db/mysql/dropDB.txt new file mode 100644 index 000000000..e1209da0e --- /dev/null +++ b/db/mysql/dropDB.txt @@ -0,0 +1 @@ +DROP DATABASE petclinic; diff --git a/db/mysql/initDB.txt b/db/mysql/initDB.txt new file mode 100644 index 000000000..0007ee3a3 --- /dev/null +++ b/db/mysql/initDB.txt @@ -0,0 +1,58 @@ +USE petclinic; + +CREATE TABLE vets ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30), + INDEX(last_name) +) engine=InnoDB; + +CREATE TABLE specialties ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(80), + INDEX(name) +) engine=InnoDB; + +CREATE TABLE vet_specialties ( + vet_id INT(4) UNSIGNED NOT NULL, + specialty_id INT(4) UNSIGNED NOT NULL +) engine=InnoDB; +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets(id); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties(id); + +CREATE TABLE types ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(80), + INDEX(name) +) engine=InnoDB; + +CREATE TABLE owners ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30), + address VARCHAR(255), + city VARCHAR(80), + telephone VARCHAR(20), + INDEX(last_name) +) engine=InnoDB; + +CREATE TABLE pets ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(30), + birth_date DATE, + type_id INT(4) UNSIGNED NOT NULL, + owner_id INT(4) UNSIGNED NOT NULL, + INDEX(name) +) engine=InnoDB; +ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners(id); +ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types(id); +CREATE INDEX pets_name ON pets(name); + +CREATE TABLE visits ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + pet_id INT(4) UNSIGNED NOT NULL, + visit_date DATE, + description VARCHAR(255), + INDEX(pet_id) +) engine=InnoDB; +ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets(id); diff --git a/db/mysql/petclinic_db_setup_mysql.txt b/db/mysql/petclinic_db_setup_mysql.txt new file mode 100644 index 000000000..66727e190 --- /dev/null +++ b/db/mysql/petclinic_db_setup_mysql.txt @@ -0,0 +1,22 @@ +================================================================================ +=== Spring PetClinic sample application - MySQL Configuration === +================================================================================ + +@author Sam Brannen + +-------------------------------------------------------------------------------- + +1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), + which can be found here: http://dev.mysql.com/downloads/ + +2) Download Connector/J, the MySQL JDBC driver (e.g., Connector/J 5.1.x), which + can be found here: http://dev.mysql.com/downloads/connector/j/ + Copy the Connector/J JAR file (e.g., mysql-connector-java-5.1.5-bin.jar) into + the db/mysql directory. + +3) Create the PetClinic database and user by executing the "db/mysql/createDB.txt" + script. + +4) Open "src/main/resources/jdbc.properties"; comment out all properties in the + "HSQL Settings" section; uncomment all properties in the "MySQL Settings" + section. \ No newline at end of file diff --git a/db/mysql/petclinic_tomcat_mysql.xml b/db/mysql/petclinic_tomcat_mysql.xml new file mode 100644 index 000000000..d1c5a3b04 --- /dev/null +++ b/db/mysql/petclinic_tomcat_mysql.xml @@ -0,0 +1,64 @@ + + + + + + + + + + factory + org.apache.commons.dbcp.BasicDataSourceFactory + + + + driverClassName + org.gjt.mm.mysql.Driver + + + + url + jdbc:mysql://localhost:3306/petclinic?autoReconnect=true + + + username + pc + + + password + pc + + + + maxActive + 50 + + + maxIdle + 10 + + + maxWait + 10000 + + + removeAbandoned + true + + + removeAbandonedTimeout + 60 + + + logAbandoned + true + + + + + diff --git a/db/petclinic_tomcat_all.xml b/db/petclinic_tomcat_all.xml new file mode 100644 index 000000000..ed45c5cd3 --- /dev/null +++ b/db/petclinic_tomcat_all.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + factory + org.apache.commons.dbcp.BasicDataSourceFactory + + + + driverClassName + org.hsqldb.jdbcDriver + + + url + jdbc:hsqldb:hsql://localhost:9001 + + + username + sa + + + + maxActive + 50 + + + maxIdle + 10 + + + maxWait + 10000 + + + removeAbandoned + true + + + removeAbandonedTimeout + 60 + + + logAbandoned + true + + + + + + + + factory + org.apache.commons.dbcp.BasicDataSourceFactory + + + + driverClassName + org.gjt.mm.mysql.Driver + + + + url + jdbc:mysql://localhost:3306/petclinic?autoReconnect=true + + + username + pc + + + password + pc + + + + maxActive + 50 + + + maxIdle + 10 + + + maxWait + 10000 + + + removeAbandoned + true + + + removeAbandonedTimeout + 60 + + + logAbandoned + true + + + + + diff --git a/db/populateDB.txt b/db/populateDB.txt new file mode 100644 index 000000000..1bf0c4a6e --- /dev/null +++ b/db/populateDB.txt @@ -0,0 +1,53 @@ +INSERT INTO vets VALUES (1, 'James', 'Carter'); +INSERT INTO vets VALUES (2, 'Helen', 'Leary'); +INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); +INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); +INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); +INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); + +INSERT INTO specialties VALUES (1, 'radiology'); +INSERT INTO specialties VALUES (2, 'surgery'); +INSERT INTO specialties VALUES (3, 'dentistry'); + +INSERT INTO vet_specialties VALUES (2, 1); +INSERT INTO vet_specialties VALUES (3, 2); +INSERT INTO vet_specialties VALUES (3, 3); +INSERT INTO vet_specialties VALUES (4, 2); +INSERT INTO vet_specialties VALUES (5, 1); + +INSERT INTO types VALUES (1, 'cat'); +INSERT INTO types VALUES (2, 'dog'); +INSERT INTO types VALUES (3, 'lizard'); +INSERT INTO types VALUES (4, 'snake'); +INSERT INTO types VALUES (5, 'bird'); +INSERT INTO types VALUES (6, 'hamster'); + +INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); + +INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1); +INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2); +INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3); +INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3); +INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4); +INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5); +INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6); +INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6); +INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7); +INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8); +INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9); +INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10); +INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10); + +INSERT INTO visits VALUES (1, 7, '1996-03-04', 'rabies shot'); +INSERT INTO visits VALUES (2, 8, '1996-03-04', 'rabies shot'); +INSERT INTO visits VALUES (3, 8, '1996-06-04', 'neutered'); +INSERT INTO visits VALUES (4, 7, '1996-09-04', 'spayed'); diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..d9b79897e --- /dev/null +++ b/pom.xml @@ -0,0 +1,233 @@ + + + 4.0.0 + org.springframework.samples + org.springframework.samples.petclinic + petclinic-classic + war + 1.0.0-SNAPSHOT + + 3.0.0.RC2 + 1.5.6 + + + + com.oracle.toplink.essentials + com.springsource.oracle.toplink.essentials + 2.0.0.b41-beta2 + + + com.sun.syndication + com.springsource.com.sun.syndication + 1.0.0 + + + javax.persistence + com.springsource.javax.persistence + 1.0.0 + + + javax.servlet + com.springsource.javax.servlet + 2.5.0 + provided + + + javax.servlet + com.springsource.javax.servlet.jsp + 2.1.0 + provided + + + javax.servlet + com.springsource.javax.servlet.jsp.jstl + 1.2.0 + + + javax.xml.bind + com.springsource.javax.xml.bind + 2.1.7 + + + org.apache.commons + com.springsource.org.apache.commons.dbcp + 1.2.2.osgi + + + org.apache.log4j + com.springsource.org.apache.log4j + 1.2.15 + + + org.apache.openjpa + com.springsource.org.apache.openjpa + 1.1.0 + + + org.apache.taglibs + com.springsource.org.apache.taglibs.standard + 1.1.2 + + + org.aspectj + com.springsource.org.aspectj.weaver + 1.6.3.RELEASE + + + org.hibernate + com.springsource.org.hibernate + 3.3.1.GA + + + org.hibernate + com.springsource.org.hibernate.ejb + 3.4.0.GA + + + org.hsqldb + com.springsource.org.hsqldb + 1.8.0.9 + + + org.jdom + com.springsource.org.jdom + 1.0.0 + + + org.springframework + org.springframework.asm + ${spring.version} + + + org.springframework + org.springframework.orm + ${spring.version} + + + org.springframework + org.springframework.oxm + ${spring.version} + + + org.springframework + org.springframework.web.servlet + ${spring.version} + + + + org.junit + com.springsource.org.junit + 4.5.0 + test + + + org.springframework + org.springframework.test + ${spring.version} + test + + + javax.transaction + com.springsource.javax.transaction + 1.1.0 + test + + + org.hibernate + com.springsource.org.hibernate.annotations + 3.4.0.GA + test + + + org.slf4j + com.springsource.slf4j.org.apache.commons.logging + ${slf4j.version} + provided + + + org.slf4j + com.springsource.slf4j.api + ${slf4j.version} + provided + + + org.slf4j + com.springsource.slf4j.log4j + ${slf4j.version} + provided + + + log4j + log4j + + + org.apache.log4j + com.springsource.org.apache.log4j + + + + + + + com.springsource.repository.bundles.release + SpringSource Enterprise Bundle Repository - SpringSource Releases + http://repository.springsource.com/maven/bundles/release + + + com.springsource.repository.bundles.milestone + SpringSource Enterprise Bundle Repository - SpringSource Milestones + http://repository.springsource.com/maven/bundles/milestone + + + com.springsource.repository.bundles.external + SpringSource Enterprise Bundle Repository - External Releases + http://repository.springsource.com/maven/bundles/external + + + com.springsource.repository.bundles.snapshot + SpringSource Enterprise Bundle Repository - Snapshot Releases + http://repository.springsource.com/maven/bundles/snapshot + + + spring-release + Spring Portfolio Release Repository + http://maven.springframework.org/release + + + spring-external + Spring Portfolio External Repository + http://maven.springframework.org/external + + + spring-milestone + Spring Portfolio Milestone Repository + http://maven.springframework.org/milestone + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-dependency-plugin + + + install + install + + sources + + + + + + + \ No newline at end of file diff --git a/readme.txt b/readme.txt index aee19b7ff..ae1fb2511 100644 --- a/readme.txt +++ b/readme.txt @@ -44,22 +44,20 @@ pooling. === Build and Deployment ========================================================================== -The Spring PetClinic sample application is built using Spring Build, which -is a custom build solution based on Ant and Ivy for dependency management. -For deployment, the web application needs to be built with Apache Ant 1.6 -or higher. When the project is first built, Spring Build will use Ivy to -automatically download all required dependencies. Thus the initial build +The Spring PetClinic sample application is built using Maven. +When the project is first built, Maven will automatically download all required +dependencies (if these haven't been downloaded before). Thus the initial build may take a few minutes depending on the speed of your Internet connection, but subsequent builds will be much faster. Available build commands: -- ant clean --> cleans the project -- ant clean test --> cleans the project and runs all tests -- ant clean jar --> cleans the project and builds the WAR +- mvn clean --> cleans the project +- mvn clean test --> cleans the project and runs all tests +- mvn clean package --> cleans the project and builds the WAR -After building the project with "ant clean jar", you will find the -resulting WAR file in the "target/artifacts" directory. By default, an +After building the project with "mvn clean package", you will find the +resulting WAR file in the "target/" directory. By default, an embedded HSQLDB instance in configured. No other steps are necessary to get the data source up and running: you can simply deploy the built WAR file directly to your Servlet container. diff --git a/src/main/java/org/springframework/samples/petclinic/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/BaseEntity.java new file mode 100644 index 000000000..bb68af4fc --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/BaseEntity.java @@ -0,0 +1,27 @@ +package org.springframework.samples.petclinic; + +/** + * Simple JavaBean domain object with an id property. + * Used as a base class for objects needing this property. + * + * @author Ken Krebs + * @author Juergen Hoeller + */ +public class BaseEntity { + + private Integer id; + + + public void setId(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public boolean isNew() { + return (this.id == null); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Clinic.java b/src/main/java/org/springframework/samples/petclinic/Clinic.java new file mode 100644 index 000000000..e48e8507b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Clinic.java @@ -0,0 +1,82 @@ +package org.springframework.samples.petclinic; + +import java.util.Collection; + +import org.springframework.dao.DataAccessException; + +/** + * The high-level PetClinic business interface. + * + *

    This is basically a data access object. + * PetClinic doesn't have a dedicated business facade. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Sam Brannen + */ +public interface Clinic { + + /** + * Retrieve all Vets from the data store. + * @return a Collection of Vets + */ + Collection getVets() throws DataAccessException; + + /** + * Retrieve all PetTypes from the data store. + * @return a Collection of PetTypes + */ + Collection getPetTypes() throws DataAccessException; + + /** + * Retrieve Owners from the data store by last name, + * returning all owners whose last name starts with the given name. + * @param lastName Value to search for + * @return a Collection of matching Owners + * (or an empty Collection if none found) + */ + Collection findOwners(String lastName) throws DataAccessException; + + /** + * Retrieve an Owner from the data store by id. + * @param id the id to search for + * @return the Owner if found + * @throws org.springframework.dao.DataRetrievalFailureException if not found + */ + Owner loadOwner(int id) throws DataAccessException; + + /** + * Retrieve a Pet from the data store by id. + * @param id the id to search for + * @return the Pet if found + * @throws org.springframework.dao.DataRetrievalFailureException if not found + */ + Pet loadPet(int id) throws DataAccessException; + + /** + * Save an Owner to the data store, either inserting or updating it. + * @param owner the Owner to save + * @see BaseEntity#isNew + */ + void storeOwner(Owner owner) throws DataAccessException; + + /** + * Save a Pet to the data store, either inserting or updating it. + * @param pet the Pet to save + * @see BaseEntity#isNew + */ + void storePet(Pet pet) throws DataAccessException; + + /** + * Save a Visit to the data store, either inserting or updating it. + * @param visit the Visit to save + * @see BaseEntity#isNew + */ + void storeVisit(Visit visit) throws DataAccessException; + + /** + * Deletes a Pet from the data store. + */ + void deletePet(int id) throws DataAccessException; + +} diff --git a/src/main/java/org/springframework/samples/petclinic/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/NamedEntity.java new file mode 100644 index 000000000..40c5931d8 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/NamedEntity.java @@ -0,0 +1,28 @@ +package org.springframework.samples.petclinic; + +/** + * Simple JavaBean domain object adds a name property to BaseEntity. + * Used as a base class for objects needing these properties. + * + * @author Ken Krebs + * @author Juergen Hoeller + */ +public class NamedEntity extends BaseEntity { + + private String name; + + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return this.getName(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Owner.java b/src/main/java/org/springframework/samples/petclinic/Owner.java new file mode 100644 index 000000000..75ea3bc06 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Owner.java @@ -0,0 +1,127 @@ +package org.springframework.samples.petclinic; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; +import org.springframework.core.style.ToStringCreator; + +/** + * Simple JavaBean domain object representing an owner. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Sam Brannen + */ +public class Owner extends Person { + + private String address; + + private String city; + + private String telephone; + + private Set pets; + + + public String getAddress() { + return this.address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return this.city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getTelephone() { + return this.telephone; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + protected void setPetsInternal(Set pets) { + this.pets = pets; + } + + protected Set getPetsInternal() { + if (this.pets == null) { + this.pets = new HashSet(); + } + return this.pets; + } + + public List getPets() { + List sortedPets = new ArrayList(getPetsInternal()); + PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedPets); + } + + public void addPet(Pet pet) { + getPetsInternal().add(pet); + pet.setOwner(this); + } + + /** + * Return the Pet with the given name, or null if none found for this Owner. + * + * @param name to test + * @return true if pet name is already in use + */ + public Pet getPet(String name) { + return getPet(name, false); + } + + /** + * Return the Pet with the given name, or null if none found for this Owner. + * + * @param name to test + * @return true if pet name is already in use + */ + public Pet getPet(String name, boolean ignoreNew) { + name = name.toLowerCase(); + for (Pet pet : getPetsInternal()) { + if (!ignoreNew || !pet.isNew()) { + String compName = pet.getName(); + compName = compName.toLowerCase(); + if (compName.equals(name)) { + return pet; + } + } + } + return null; + } + + @Override + public String toString() { + return new ToStringCreator(this) + + .append("id", this.getId()) + + .append("new", this.isNew()) + + .append("lastName", this.getLastName()) + + .append("firstName", this.getFirstName()) + + .append("address", this.address) + + .append("city", this.city) + + .append("telephone", this.telephone) + + .toString(); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/Person.java b/src/main/java/org/springframework/samples/petclinic/Person.java new file mode 100644 index 000000000..da7974a7d --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Person.java @@ -0,0 +1,32 @@ +package org.springframework.samples.petclinic; + +/** + * Simple JavaBean domain object representing an person. + * + * @author Ken Krebs + */ +public class Person extends BaseEntity { + + private String firstName; + + private String lastName; + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return this.lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Pet.java b/src/main/java/org/springframework/samples/petclinic/Pet.java new file mode 100644 index 000000000..f5294b5ca --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Pet.java @@ -0,0 +1,77 @@ +package org.springframework.samples.petclinic; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; + +/** + * Simple JavaBean business object representing a pet. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Sam Brannen + */ +public class Pet extends NamedEntity { + + private Date birthDate; + + private PetType type; + + private Owner owner; + + private Set visits; + + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + public Date getBirthDate() { + return this.birthDate; + } + + public void setType(PetType type) { + this.type = type; + } + + public PetType getType() { + return this.type; + } + + protected void setOwner(Owner owner) { + this.owner = owner; + } + + public Owner getOwner() { + return this.owner; + } + + protected void setVisitsInternal(Set visits) { + this.visits = visits; + } + + protected Set getVisitsInternal() { + if (this.visits == null) { + this.visits = new HashSet(); + } + return this.visits; + } + + public List getVisits() { + List sortedVisits = new ArrayList(getVisitsInternal()); + PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false)); + return Collections.unmodifiableList(sortedVisits); + } + + public void addVisit(Visit visit) { + getVisitsInternal().add(visit); + visit.setPet(this); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/PetType.java b/src/main/java/org/springframework/samples/petclinic/PetType.java new file mode 100644 index 000000000..aaadc5c44 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/PetType.java @@ -0,0 +1,8 @@ +package org.springframework.samples.petclinic; + +/** + * @author Juergen Hoeller + */ +public class PetType extends NamedEntity { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Specialty.java b/src/main/java/org/springframework/samples/petclinic/Specialty.java new file mode 100644 index 000000000..d19ccaba9 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Specialty.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic; + +/** + * Models a {@link Vet Vet's} specialty (for example, dentistry). + * + * @author Juergen Hoeller + */ +public class Specialty extends NamedEntity { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Vet.java b/src/main/java/org/springframework/samples/petclinic/Vet.java new file mode 100644 index 000000000..9c7c8da0b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Vet.java @@ -0,0 +1,52 @@ +package org.springframework.samples.petclinic; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.xml.bind.annotation.XmlElement; + +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; + +/** + * Simple JavaBean domain object representing a veterinarian. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Sam Brannen + * @author Arjen Poutsma + */ +public class Vet extends Person { + + private Set specialties; + + + protected void setSpecialtiesInternal(Set specialties) { + this.specialties = specialties; + } + + protected Set getSpecialtiesInternal() { + if (this.specialties == null) { + this.specialties = new HashSet(); + } + return this.specialties; + } + + @XmlElement + public List getSpecialties() { + List sortedSpecs = new ArrayList(getSpecialtiesInternal()); + PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedSpecs); + } + + public int getNrOfSpecialties() { + return getSpecialtiesInternal().size(); + } + + public void addSpecialty(Specialty specialty) { + getSpecialtiesInternal().add(specialty); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Vets.java b/src/main/java/org/springframework/samples/petclinic/Vets.java new file mode 100644 index 000000000..2e3b25e27 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Vets.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Simple JavaBean domain object representing a list of veterinarians. Mostly here to be used for the 'vets' + * {@link org.springframework.web.servlet.view.xml.MarshallingView}. + * + * @author Arjen Poutsma + */ +@XmlRootElement +public class Vets { + + private List vets; + + @XmlElement + public List getVetList() { + if (vets == null) { + vets = new ArrayList(); + } + return vets; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/Visit.java b/src/main/java/org/springframework/samples/petclinic/Visit.java new file mode 100644 index 000000000..c42bdcee5 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/Visit.java @@ -0,0 +1,70 @@ +package org.springframework.samples.petclinic; + +import java.util.Date; + +/** + * Simple JavaBean domain object representing a visit. + * + * @author Ken Krebs + */ +public class Visit extends BaseEntity { + + /** Holds value of property date. */ + private Date date; + + /** Holds value of property description. */ + private String description; + + /** Holds value of property pet. */ + private Pet pet; + + + /** Creates a new instance of Visit for the current date */ + public Visit() { + this.date = new Date(); + } + + + /** Getter for property date. + * @return Value of property date. + */ + public Date getDate() { + return this.date; + } + + /** Setter for property date. + * @param date New value of property date. + */ + public void setDate(Date date) { + this.date = date; + } + + /** Getter for property description. + * @return Value of property description. + */ + public String getDescription() { + return this.description; + } + + /** Setter for property description. + * @param description New value of property description. + */ + public void setDescription(String description) { + this.description = description; + } + + /** Getter for property pet. + * @return Value of property pet. + */ + public Pet getPet() { + return this.pet; + } + + /** Setter for property pet. + * @param pet New value of property pet. + */ + public void setPet(Pet pet) { + this.pet = pet; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java new file mode 100644 index 000000000..26d32359f --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java @@ -0,0 +1,31 @@ +package org.springframework.samples.petclinic.aspects; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; + +/** + * Aspect to illustrate Spring-driven load-time weaving. + * + * @author Ramnivas Laddad + * @since 2.5 + */ +@Aspect +public abstract class AbstractTraceAspect { + + private static final Log logger = LogFactory.getLog(AbstractTraceAspect.class); + + @Pointcut + public abstract void traced(); + + @Before("traced()") + public void trace(JoinPoint.StaticPart jpsp) { + if (logger.isTraceEnabled()) { + logger.trace("Entering " + jpsp.getSignature().toLongString()); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java new file mode 100644 index 000000000..2de4cb41d --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java @@ -0,0 +1,81 @@ +package org.springframework.samples.petclinic.aspects; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; + +import org.springframework.jmx.export.annotation.ManagedAttribute; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.util.StopWatch; + +/** + * Simple AspectJ aspect that monitors call count and call invocation time. + * Implements the CallMonitor management interface. + * + * @author Rob Harrop + * @author Juergen Hoeller + * @since 2.5 + */ +@ManagedResource("petclinic:type=CallMonitor") +@Aspect +public class CallMonitoringAspect { + + private boolean isEnabled = true; + + private int callCount = 0; + + private long accumulatedCallTime = 0; + + + @ManagedAttribute + public void setEnabled(boolean enabled) { + isEnabled = enabled; + } + + @ManagedAttribute + public boolean isEnabled() { + return isEnabled; + } + + @ManagedOperation + public void reset() { + this.callCount = 0; + this.accumulatedCallTime = 0; + } + + @ManagedAttribute + public int getCallCount() { + return callCount; + } + + @ManagedAttribute + public long getCallTime() { + return (this.callCount > 0 ? this.accumulatedCallTime / this.callCount : 0); + } + + + @Around("within(@org.springframework.stereotype.Service *)") + public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable { + if (this.isEnabled) { + StopWatch sw = new StopWatch(joinPoint.toShortString()); + + sw.start("invoke"); + try { + return joinPoint.proceed(); + } + finally { + sw.stop(); + synchronized (this) { + this.callCount++; + this.accumulatedCallTime += sw.getTotalTimeMillis(); + } + } + } + + else { + return joinPoint.proceed(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java new file mode 100644 index 000000000..e326abfb7 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java @@ -0,0 +1,48 @@ +package org.springframework.samples.petclinic.aspects; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; + +/** + * Sample AspectJ annotation-style aspect that saves + * every owner name requested to the clinic. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 2.0 + */ +@Aspect +public class UsageLogAspect { + + private int historySize = 100; + + // Of course saving all names is not suitable for + // production use, but this is a simple example. + private List namesRequested = new ArrayList(this.historySize); + + + public synchronized void setHistorySize(int historySize) { + this.historySize = historySize; + this.namesRequested = new ArrayList(historySize); + } + + @Before("execution(* *.findOwners(String)) && args(name)") + public synchronized void logNameRequest(String name) { + // Not the most efficient implementation, + // but we're aiming to illustrate the power of + // @AspectJ AOP, not write perfect code here :-) + if (this.namesRequested.size() > this.historySize) { + this.namesRequested.remove(0); + } + this.namesRequested.add(name); + } + + public synchronized List getNamesRequested() { + return Collections.unmodifiableList(this.namesRequested); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java b/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java new file mode 100644 index 000000000..0454161e6 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java @@ -0,0 +1,261 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.config; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.DataSource; + +import org.apache.commons.dbcp.BasicDataSource; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.core.io.Resource; + +/** + * A factory that creates a data source fit for use in a system environment. Creates a DBCP simple data source + * from the provided connection properties. + * + * This factory returns a fully-initialized DataSource implementation. When the DataSource is returned, callers are + * guaranteed that the database schema and data will have been loaded by that time. + * + * Is a FactoryBean, for exposing the fully-initialized DataSource as a Spring bean. See {@link #getObject()}. + * + * @author Chris Beams + * @author Scott Andrews + */ +public class DbcpDataSourceFactory implements FactoryBean, DisposableBean { + + // configurable properties + + private String driverClassName; + + private String url; + + private String username; + + private String password; + + private boolean populate; + + private Resource schemaLocation; + + private Resource dataLocation; + + private Resource dropLocation; + + /** + * The object created by this factory. + */ + private BasicDataSource dataSource; + + public void setDriverClassName(String driverClassName) { + this.driverClassName = driverClassName; + } + + /** + * The data source connection URL + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * The data source username + */ + public void setUsername(String username) { + this.username = username; + } + + /** + *The data source password + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * Indicates that the data base should be populated from the schema and data locations + */ + public void setPopulate(boolean populate) { + this.populate = populate; + } + + /** + * Sets the location of the file containing the schema DDL to export to the database. + * @param schemaLocation the location of the database schema DDL + */ + public void setSchemaLocation(Resource schemaLocation) { + this.schemaLocation = schemaLocation; + } + + /** + * Sets the location of the file containing the data to load into the database. + * @param testDataLocation the location of the data file + */ + public void setDataLocation(Resource testDataLocation) { + this.dataLocation = testDataLocation; + } + + /** + * Sets the location of the file containing the drop scripts for the database. + * @param testDataLocation the location of the data file + */ + public void setDropLocation(Resource testDropLocation) { + this.dropLocation = testDropLocation; + } + + // implementing FactoryBean + + // this method is called by Spring to expose the DataSource as a bean + public DataSource getObject() throws Exception { + if (dataSource == null) { + initDataSource(); + } + return dataSource; + } + + public Class getObjectType() { + return DataSource.class; + } + + public boolean isSingleton() { + return true; + } + + // implementing DisposableBean + + public void destroy() throws Exception { + dataSource.close(); + } + + // internal helper methods + + // encapsulates the steps involved in initializing the data source: creating it, and populating it + private void initDataSource() { + // create the database source first + this.dataSource = createDataSource(); + + if (this.populate) { + // now populate the database by loading the schema and data + populateDataSource(); + } + } + + private BasicDataSource createDataSource() { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(this.driverClassName); + dataSource.setUrl(this.url); + dataSource.setUsername(this.username); + dataSource.setPassword(this.password); + return dataSource; + } + + private void populateDataSource() { + DatabasePopulator populator = new DatabasePopulator(dataSource); + if (dropLocation != null) { + try { + populator.populate(this.dropLocation); + } + catch (Exception e) { + // ignore + } + } + populator.populate(this.schemaLocation); + populator.populate(this.dataLocation); + } + + /** + * Populates a in memory data source with data. + */ + private class DatabasePopulator { + + private DataSource dataSource; + + /** + * Creates a new database populator. + * @param dataSource the data source that will be populated. + */ + public DatabasePopulator(DataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * Populate the database executing the statements in the provided resource against the database + * @param sqlFile spring resource containing SQL to run against the db + */ + public void populate(Resource sqlFile) { + Connection connection = null; + try { + connection = dataSource.getConnection(); + try { + String sql = parseSqlIn(sqlFile); + executeSql(sql, connection); + } catch (IOException e) { + throw new RuntimeException("I/O exception occurred accessing the database schema file", e); + } catch (SQLException e) { + throw new RuntimeException("SQL exception occurred exporting database schema", e); + } + } catch (SQLException e) { + throw new RuntimeException("SQL exception occurred acquiring connection", e); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + } + } + + // utility method to read a .sql txt input stream + private String parseSqlIn(Resource resource) throws IOException { + InputStream is = null; + try { + is = resource.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + + StringWriter sw = new StringWriter(); + BufferedWriter writer = new BufferedWriter(sw); + + for (int c=reader.read(); c != -1; c=reader.read()) { + writer.write(c); + } + writer.flush(); + return sw.toString(); + + } finally { + if (is != null) { + is.close(); + } + } + } + + // utility method to run the parsed sql + private void executeSql(String sql, Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + statement.execute(sql); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java b/src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java new file mode 100644 index 000000000..411638562 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java @@ -0,0 +1,98 @@ +package org.springframework.samples.petclinic.hibernate; + +import java.util.Collection; + +import org.hibernate.SessionFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.Vet; +import org.springframework.samples.petclinic.Visit; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +/** + * Hibernate implementation of the Clinic interface. + * + *

    The mappings are defined in "petclinic.hbm.xml", located in the root of the + * class path. + * + *

    Note that transactions are declared with annotations and that some methods + * contain "readOnly = true" which is an optimization that is particularly + * valuable when using Hibernate (to suppress unnecessary flush attempts for + * read-only operations). + * + * @author Juergen Hoeller + * @author Sam Brannen + * @author Mark Fisher + * @since 19.10.2003 + */ +@Repository +@Transactional +public class HibernateClinic implements Clinic { + + private SessionFactory sessionFactory; + + @Autowired + public HibernateClinic(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public Collection getVets() { + return sessionFactory.getCurrentSession().createQuery("from Vet vet order by vet.lastName, vet.firstName").list(); + } + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public Collection getPetTypes() { + return sessionFactory.getCurrentSession().createQuery("from PetType type order by type.name").list(); + } + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public Collection findOwners(String lastName) { + return sessionFactory.getCurrentSession().createQuery("from Owner owner where owner.lastName like :lastName") + .setString("lastName", lastName + "%").list(); + } + + @Transactional(readOnly = true) + public Owner loadOwner(int id) { + return (Owner) sessionFactory.getCurrentSession().load(Owner.class, id); + } + + @Transactional(readOnly = true) + public Pet loadPet(int id) { + return (Pet) sessionFactory.getCurrentSession().load(Pet.class, id); + } + + public void storeOwner(Owner owner) { + // Note: Hibernate3's merge operation does not reassociate the object + // with the current Hibernate Session. Instead, it will always copy the + // state over to a registered representation of the entity. In case of a + // new entity, it will register a copy as well, but will not update the + // id of the passed-in object. To still update the ids of the original + // objects too, we need to register Spring's + // IdTransferringMergeEventListener on our SessionFactory. + sessionFactory.getCurrentSession().merge(owner); + } + + public void storePet(Pet pet) { + sessionFactory.getCurrentSession().merge(pet); + } + + public void storeVisit(Visit visit) { + sessionFactory.getCurrentSession().merge(visit); + } + + public void deletePet(int id) throws DataAccessException { + Pet pet = loadPet(id); + sessionFactory.getCurrentSession().delete(pet); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java b/src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java new file mode 100644 index 000000000..e39ebac47 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java @@ -0,0 +1,9 @@ + +/** + * + * The classes in this package represent the Hibernate implementation + * of PetClinic's persistence layer. + * + */ +package org.springframework.samples.petclinic.hibernate; + diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java b/src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java new file mode 100644 index 000000000..963ffdfe0 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java @@ -0,0 +1,35 @@ +package org.springframework.samples.petclinic.jdbc; + +import org.springframework.samples.petclinic.Pet; + +/** + * Subclass of Pet that carries temporary id properties which + * are only relevant for a JDBC implmentation of the Clinic. + * + * @author Juergen Hoeller + * @see SimpleJdbcClinic + */ +class JdbcPet extends Pet { + + private int typeId; + + private int ownerId; + + + public void setTypeId(int typeId) { + this.typeId = typeId; + } + + public int getTypeId() { + return this.typeId; + } + + public void setOwnerId(int ownerId) { + this.ownerId = ownerId; + } + + public int getOwnerId() { + return this.ownerId; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java new file mode 100644 index 000000000..587acecb9 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java @@ -0,0 +1,342 @@ +package org.springframework.samples.petclinic.jdbc; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.sql.DataSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper; +import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.Specialty; +import org.springframework.samples.petclinic.Vet; +import org.springframework.samples.petclinic.Visit; +import org.springframework.samples.petclinic.util.EntityUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * A simple JDBC-based implementation of the {@link Clinic} interface. + * + *

    This class uses Java 5 language features and the {@link SimpleJdbcTemplate} + * plus {@link SimpleJdbcInsert}. It also takes advantage of classes like + * {@link BeanPropertySqlParameterSource} and + * {@link ParameterizedBeanPropertyRowMapper} which provide automatic mapping + * between JavaBean properties and JDBC parameters or query results. + * + *

    SimpleJdbcClinic is a rewrite of the AbstractJdbcClinic which was the base + * class for JDBC implementations of the Clinic interface for Spring 2.0. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Rob Harrop + * @author Sam Brannen + * @author Thomas Risberg + * @author Mark Fisher + */ +@Service +@ManagedResource("petclinic:type=Clinic") +public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean { + + private final Log logger = LogFactory.getLog(getClass()); + + private SimpleJdbcTemplate simpleJdbcTemplate; + + private SimpleJdbcInsert insertOwner; + private SimpleJdbcInsert insertPet; + private SimpleJdbcInsert insertVisit; + + private final List vets = new ArrayList(); + + + @Autowired + public void init(DataSource dataSource) { + this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); + + this.insertOwner = new SimpleJdbcInsert(dataSource) + .withTableName("owners") + .usingGeneratedKeyColumns("id"); + this.insertPet = new SimpleJdbcInsert(dataSource) + .withTableName("pets") + .usingGeneratedKeyColumns("id"); + this.insertVisit = new SimpleJdbcInsert(dataSource) + .withTableName("visits") + .usingGeneratedKeyColumns("id"); + } + + + /** + * Refresh the cache of Vets that the Clinic is holding. + * @see org.springframework.samples.petclinic.Clinic#getVets() + */ + @ManagedOperation + @Transactional(readOnly = true) + public void refreshVetsCache() throws DataAccessException { + synchronized (this.vets) { + this.logger.info("Refreshing vets cache"); + + // Retrieve the list of all vets. + this.vets.clear(); + this.vets.addAll(this.simpleJdbcTemplate.query( + "SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name", + ParameterizedBeanPropertyRowMapper.newInstance(Vet.class))); + + // Retrieve the list of all possible specialties. + final List specialties = this.simpleJdbcTemplate.query( + "SELECT id, name FROM specialties", + ParameterizedBeanPropertyRowMapper.newInstance(Specialty.class)); + + // Build each vet's list of specialties. + for (Vet vet : this.vets) { + final List vetSpecialtiesIds = this.simpleJdbcTemplate.query( + "SELECT specialty_id FROM vet_specialties WHERE vet_id=?", + new ParameterizedRowMapper() { + public Integer mapRow(ResultSet rs, int row) throws SQLException { + return Integer.valueOf(rs.getInt(1)); + }}, + vet.getId().intValue()); + for (int specialtyId : vetSpecialtiesIds) { + Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId); + vet.addSpecialty(specialty); + } + } + } + } + + + // START of Clinic implementation section ******************************* + + @Transactional(readOnly = true) + public Collection getVets() throws DataAccessException { + synchronized (this.vets) { + if (this.vets.isEmpty()) { + refreshVetsCache(); + } + return this.vets; + } + } + + @Transactional(readOnly = true) + public Collection getPetTypes() throws DataAccessException { + return this.simpleJdbcTemplate.query( + "SELECT id, name FROM types ORDER BY name", + ParameterizedBeanPropertyRowMapper.newInstance(PetType.class)); + } + + /** + * Loads {@link Owner Owners} from the data store by last name, returning + * all owners whose last name starts with the given name; also loads + * the {@link Pet Pets} and {@link Visit Visits} for the corresponding + * owners, if not already loaded. + */ + @Transactional(readOnly = true) + public Collection findOwners(String lastName) throws DataAccessException { + List owners = this.simpleJdbcTemplate.query( + "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like ?", + ParameterizedBeanPropertyRowMapper.newInstance(Owner.class), + lastName + "%"); + loadOwnersPetsAndVisits(owners); + return owners; + } + + /** + * Loads the {@link Owner} with the supplied id; also loads + * the {@link Pet Pets} and {@link Visit Visits} for the corresponding + * owner, if not already loaded. + */ + @Transactional(readOnly = true) + public Owner loadOwner(int id) throws DataAccessException { + Owner owner; + try { + owner = this.simpleJdbcTemplate.queryForObject( + "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id=?", + ParameterizedBeanPropertyRowMapper.newInstance(Owner.class), + id); + } + catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Owner.class, new Integer(id)); + } + loadPetsAndVisits(owner); + return owner; + } + + @Transactional(readOnly = true) + public Pet loadPet(int id) throws DataAccessException { + JdbcPet pet; + try { + pet = this.simpleJdbcTemplate.queryForObject( + "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=?", + new JdbcPetRowMapper(), + id); + } + catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Pet.class, new Integer(id)); + } + Owner owner = loadOwner(pet.getOwnerId()); + owner.addPet(pet); + pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId())); + loadVisits(pet); + return pet; + } + + @Transactional + public void storeOwner(Owner owner) throws DataAccessException { + if (owner.isNew()) { + Number newKey = this.insertOwner.executeAndReturnKey( + new BeanPropertySqlParameterSource(owner)); + owner.setId(newKey.intValue()); + } + else { + this.simpleJdbcTemplate.update( + "UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " + + "city=:city, telephone=:telephone WHERE id=:id", + new BeanPropertySqlParameterSource(owner)); + } + } + + @Transactional + public void storePet(Pet pet) throws DataAccessException { + if (pet.isNew()) { + Number newKey = this.insertPet.executeAndReturnKey( + createPetParameterSource(pet)); + pet.setId(newKey.intValue()); + } + else { + this.simpleJdbcTemplate.update( + "UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " + + "owner_id=:owner_id WHERE id=:id", + createPetParameterSource(pet)); + } + } + + @Transactional + public void storeVisit(Visit visit) throws DataAccessException { + if (visit.isNew()) { + Number newKey = this.insertVisit.executeAndReturnKey( + createVisitParameterSource(visit)); + visit.setId(newKey.intValue()); + } + else { + throw new UnsupportedOperationException("Visit update not supported"); + } + } + + public void deletePet(int id) throws DataAccessException { + this.simpleJdbcTemplate.update("DELETE FROM pets WHERE id=?", id); + } + + // END of Clinic implementation section ************************************ + + + /** + * Creates a {@link MapSqlParameterSource} based on data values from the + * supplied {@link Pet} instance. + */ + private MapSqlParameterSource createPetParameterSource(Pet pet) { + return new MapSqlParameterSource() + .addValue("id", pet.getId()) + .addValue("name", pet.getName()) + .addValue("birth_date", pet.getBirthDate()) + .addValue("type_id", pet.getType().getId()) + .addValue("owner_id", pet.getOwner().getId()); + } + + /** + * Creates a {@link MapSqlParameterSource} based on data values from the + * supplied {@link Visit} instance. + */ + private MapSqlParameterSource createVisitParameterSource(Visit visit) { + return new MapSqlParameterSource() + .addValue("id", visit.getId()) + .addValue("visit_date", visit.getDate()) + .addValue("description", visit.getDescription()) + .addValue("pet_id", visit.getPet().getId()); + } + + /** + * Loads the {@link Visit} data for the supplied {@link Pet}. + */ + private void loadVisits(JdbcPet pet) { + final List visits = this.simpleJdbcTemplate.query( + "SELECT id, visit_date, description FROM visits WHERE pet_id=?", + new ParameterizedRowMapper() { + public Visit mapRow(ResultSet rs, int row) throws SQLException { + Visit visit = new Visit(); + visit.setId(rs.getInt("id")); + visit.setDate(rs.getTimestamp("visit_date")); + visit.setDescription(rs.getString("description")); + return visit; + } + }, + pet.getId().intValue()); + for (Visit visit : visits) { + pet.addVisit(visit); + } + } + + /** + * Loads the {@link Pet} and {@link Visit} data for the supplied + * {@link Owner}. + */ + private void loadPetsAndVisits(final Owner owner) { + final List pets = this.simpleJdbcTemplate.query( + "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=?", + new JdbcPetRowMapper(), + owner.getId().intValue()); + for (JdbcPet pet : pets) { + owner.addPet(pet); + pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId())); + loadVisits(pet); + } + } + + /** + * Loads the {@link Pet} and {@link Visit} data for the supplied + * {@link List} of {@link Owner Owners}. + * + * @param owners the list of owners for whom the pet and visit data should be loaded + * @see #loadPetsAndVisits(Owner) + */ + private void loadOwnersPetsAndVisits(List owners) { + for (Owner owner : owners) { + loadPetsAndVisits(owner); + } + } + + /** + * {@link ParameterizedRowMapper} implementation mapping data from a + * {@link ResultSet} to the corresponding properties of the {@link JdbcPet} class. + */ + private class JdbcPetRowMapper implements ParameterizedRowMapper { + + public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException { + JdbcPet pet = new JdbcPet(); + pet.setId(rs.getInt("id")); + pet.setName(rs.getString("name")); + pet.setBirthDate(rs.getDate("birth_date")); + pet.setTypeId(rs.getInt("type_id")); + pet.setOwnerId(rs.getInt("owner_id")); + return pet; + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java new file mode 100644 index 000000000..c9a7a7847 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java @@ -0,0 +1,20 @@ +package org.springframework.samples.petclinic.jdbc; + +/** + * Interface that defines a cache refresh operation. + * To be exposed for management via JMX. + * + * @author Rob Harrop + * @author Juergen Hoeller + * @see SimpleJdbcClinic + */ +public interface SimpleJdbcClinicMBean { + + /** + * Refresh the cache of Vets that the Clinic is holding. + * @see org.springframework.samples.petclinic.Clinic#getVets() + * @see SimpleJdbcClinic#refreshVetsCache() + */ + void refreshVetsCache(); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java b/src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java new file mode 100644 index 000000000..6ec278b44 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java @@ -0,0 +1,9 @@ + +/** + * + * The classes in this package represent the JDBC implementation + * of PetClinic's persistence layer. + * + */ +package org.springframework.samples.petclinic.jdbc; + diff --git a/src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java b/src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java new file mode 100644 index 000000000..92fe1e247 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java @@ -0,0 +1,96 @@ +package org.springframework.samples.petclinic.jpa; + +import java.util.Collection; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.Vet; +import org.springframework.samples.petclinic.Visit; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.dao.DataAccessException; + +/** + * JPA implementation of the Clinic interface using EntityManager. + * + *

    The mappings are defined in "orm.xml" located in the META-INF directory. + * + * @author Mike Keith + * @author Rod Johnson + * @author Sam Brannen + * @since 22.4.2006 + */ +@Repository +@Transactional +public class EntityManagerClinic implements Clinic { + + @PersistenceContext + private EntityManager em; + + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public Collection getVets() { + return this.em.createQuery("SELECT vet FROM Vet vet ORDER BY vet.lastName, vet.firstName").getResultList(); + } + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public Collection getPetTypes() { + return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList(); + } + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public Collection findOwners(String lastName) { + Query query = this.em.createQuery("SELECT owner FROM Owner owner WHERE owner.lastName LIKE :lastName"); + query.setParameter("lastName", lastName + "%"); + return query.getResultList(); + } + + @Transactional(readOnly = true) + public Owner loadOwner(int id) { + return this.em.find(Owner.class, id); + } + + @Transactional(readOnly = true) + public Pet loadPet(int id) { + return this.em.find(Pet.class, id); + } + + public void storeOwner(Owner owner) { + // Consider returning the persistent object here, for exposing + // a newly assigned id using any persistence provider... + Owner merged = this.em.merge(owner); + this.em.flush(); + owner.setId(merged.getId()); + } + + public void storePet(Pet pet) { + // Consider returning the persistent object here, for exposing + // a newly assigned id using any persistence provider... + Pet merged = this.em.merge(pet); + this.em.flush(); + pet.setId(merged.getId()); + } + + public void storeVisit(Visit visit) { + // Consider returning the persistent object here, for exposing + // a newly assigned id using any persistence provider... + Visit merged = this.em.merge(visit); + this.em.flush(); + visit.setId(merged.getId()); + } + + public void deletePet(int id) throws DataAccessException { + Pet pet = loadPet(id); + this.em.remove(pet); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/jpa/package-info.java b/src/main/java/org/springframework/samples/petclinic/jpa/package-info.java new file mode 100644 index 000000000..8093784ec --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/jpa/package-info.java @@ -0,0 +1,9 @@ + +/** + * + * The classes in this package represent the JPA implementation + * of PetClinic's persistence layer. + * + */ +package org.springframework.samples.petclinic.jpa; + diff --git a/src/main/java/org/springframework/samples/petclinic/package-info.java b/src/main/java/org/springframework/samples/petclinic/package-info.java new file mode 100644 index 000000000..f2cc36915 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/package-info.java @@ -0,0 +1,8 @@ + +/** + * + * The classes in this package represent PetClinic's business layer. + * + */ +package org.springframework.samples.petclinic; + diff --git a/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java b/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java new file mode 100644 index 000000000..1086591de --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java @@ -0,0 +1,56 @@ +package org.springframework.samples.petclinic.toplink; + +import java.io.IOException; +import java.io.Writer; + +import oracle.toplink.essentials.exceptions.ValidationException; +import oracle.toplink.essentials.platform.database.HSQLPlatform; +import oracle.toplink.essentials.queryframework.ValueReadQuery; + +/** + * Subclass of the TopLink Essentials default HSQLPlatform class, using native + * HSQLDB identity columns for id generation. + * + *

    Necessary for PetClinic's default data model, which relies on identity + * columns: this is uniformly used across all persistence layer implementations + * (JDBC, Hibernate, and JPA). + * + * @author Juergen Hoeller + * @author James Clark + * @since 1.2 + */ +public class EssentialsHSQLPlatformWithNativeSequence extends HSQLPlatform { + + private static final long serialVersionUID = -55658009691346735L; + + + public EssentialsHSQLPlatformWithNativeSequence() { + // setUsesNativeSequencing(true); + } + + @Override + public boolean supportsNativeSequenceNumbers() { + return true; + } + + @Override + public boolean shouldNativeSequenceAcquireValueAfterInsert() { + return true; + } + + @Override + public ValueReadQuery buildSelectQueryForNativeSequence() { + return new ValueReadQuery("CALL IDENTITY()"); + } + + @Override + public void printFieldIdentityClause(Writer writer) throws ValidationException { + try { + writer.write(" IDENTITY"); + } + catch (IOException ex) { + throw ValidationException.fileError(ex); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java b/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java new file mode 100644 index 000000000..3bcc9add7 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java @@ -0,0 +1,10 @@ + +/** + * + * The classes in this package provide support for using the TopLink + * implementation with PetClinic's EntityManagerClinic. + * + * + */ +package org.springframework.samples.petclinic.toplink; + diff --git a/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java b/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java new file mode 100644 index 000000000..16df5fa9a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java @@ -0,0 +1,41 @@ + +package org.springframework.samples.petclinic.util; + +import java.util.Collection; + +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.BaseEntity; + +/** + * Utility methods for handling entities. Separate from the BaseEntity class + * mainly because of dependency on the ORM-associated + * ObjectRetrievalFailureException. + * + * @author Juergen Hoeller + * @author Sam Brannen + * @since 29.10.2003 + * @see org.springframework.samples.petclinic.BaseEntity + */ +public abstract class EntityUtils { + + /** + * Look up the entity of the given class with the given id in the given + * collection. + * + * @param entities the collection to search + * @param entityClass the entity class to look up + * @param entityId the entity id to look up + * @return the found entity + * @throws ObjectRetrievalFailureException if the entity was not found + */ + public static T getById(Collection entities, Class entityClass, int entityId) + throws ObjectRetrievalFailureException { + for (T entity : entities) { + if (entity.getId().intValue() == entityId && entityClass.isInstance(entity)) { + return entity; + } + } + throw new ObjectRetrievalFailureException(entityClass, new Integer(entityId)); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java b/src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java new file mode 100644 index 000000000..04b6b7d58 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java @@ -0,0 +1,43 @@ +package org.springframework.samples.petclinic.validation; + +import org.springframework.samples.petclinic.Owner; +import org.springframework.util.StringUtils; +import org.springframework.validation.Errors; + +/** + * Validator for Owner forms. + * + * @author Ken Krebs + * @author Juergen Hoeller + */ +public class OwnerValidator { + + public void validate(Owner owner, Errors errors) { + if (!StringUtils.hasLength(owner.getFirstName())) { + errors.rejectValue("firstName", "required", "required"); + } + if (!StringUtils.hasLength(owner.getLastName())) { + errors.rejectValue("lastName", "required", "required"); + } + if (!StringUtils.hasLength(owner.getAddress())) { + errors.rejectValue("address", "required", "required"); + } + if (!StringUtils.hasLength(owner.getCity())) { + errors.rejectValue("city", "required", "required"); + } + + String telephone = owner.getTelephone(); + if (!StringUtils.hasLength(telephone)) { + errors.rejectValue("telephone", "required", "required"); + } + else { + for (int i = 0; i < telephone.length(); ++i) { + if ((Character.isDigit(telephone.charAt(i))) == false) { + errors.rejectValue("telephone", "nonNumeric", "non-numeric"); + break; + } + } + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java new file mode 100644 index 000000000..8ad6eb0ac --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java @@ -0,0 +1,25 @@ +package org.springframework.samples.petclinic.validation; + +import org.springframework.samples.petclinic.Pet; +import org.springframework.util.StringUtils; +import org.springframework.validation.Errors; + +/** + * Validator for Pet forms. + * + * @author Ken Krebs + * @author Juergen Hoeller + */ +public class PetValidator { + + public void validate(Pet pet, Errors errors) { + String name = pet.getName(); + if (!StringUtils.hasLength(name)) { + errors.rejectValue("name", "required", "required"); + } + else if (pet.isNew() && pet.getOwner().getPet(name, true) != null) { + errors.rejectValue("name", "duplicate", "already exists"); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java b/src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java new file mode 100644 index 000000000..35c80bafa --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java @@ -0,0 +1,21 @@ +package org.springframework.samples.petclinic.validation; + +import org.springframework.samples.petclinic.Visit; +import org.springframework.util.StringUtils; +import org.springframework.validation.Errors; + +/** + * Validator for Visit forms. + * + * @author Ken Krebs + * @author Juergen Hoeller + */ +public class VisitValidator { + + public void validate(Visit visit, Errors errors) { + if (!StringUtils.hasLength(visit.getDescription())) { + errors.rejectValue("description", "required", "required"); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/validation/package-info.java b/src/main/java/org/springframework/samples/petclinic/validation/package-info.java new file mode 100644 index 000000000..7db2ee521 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/validation/package-info.java @@ -0,0 +1,9 @@ + +/** + * + * The classes in this package represent the set of Validator objects + * the Business Layer makes available to the Presentation Layer. + * + */ +package org.springframework.samples.petclinic.validation; + diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java new file mode 100644 index 000000000..cd830aff6 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java @@ -0,0 +1,65 @@ + +package org.springframework.samples.petclinic.web; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.validation.OwnerValidator; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.bind.support.SessionStatus; + +/** + * JavaBean form controller that is used to add a new Owner to the + * system. + * + * @author Juergen Hoeller + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +@RequestMapping("/owners/new") +@SessionAttributes(types = Owner.class) +public class AddOwnerForm { + + private final Clinic clinic; + + + @Autowired + public AddOwnerForm(Clinic clinic) { + this.clinic = clinic; + } + + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } + + @RequestMapping(method = RequestMethod.GET) + public String setupForm(Model model) { + Owner owner = new Owner(); + model.addAttribute(owner); + return "owners/form"; + } + + @RequestMapping(method = RequestMethod.POST) + public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) { + new OwnerValidator().validate(owner, result); + if (result.hasErrors()) { + return "owners/form"; + } + else { + this.clinic.storeOwner(owner); + status.setComplete(); + return "redirect:/owners/" + owner.getId(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java new file mode 100644 index 000000000..586cf3d67 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java @@ -0,0 +1,77 @@ + +package org.springframework.samples.petclinic.web; + +import java.util.Collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.validation.PetValidator; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.bind.support.SessionStatus; + +/** + * JavaBean form controller that is used to add a new Pet to the + * system. + * + * @author Juergen Hoeller + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +@RequestMapping("/owners/{ownerId}/pets/new") +@SessionAttributes("pet") +public class AddPetForm { + + private final Clinic clinic; + + + @Autowired + public AddPetForm(Clinic clinic) { + this.clinic = clinic; + } + + @ModelAttribute("types") + public Collection populatePetTypes() { + return this.clinic.getPetTypes(); + } + + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } + + @RequestMapping(method = RequestMethod.GET) + public String setupForm(@PathVariable("ownerId") int ownerId, Model model) { + Owner owner = this.clinic.loadOwner(ownerId); + Pet pet = new Pet(); + owner.addPet(pet); + model.addAttribute("pet", pet); + return "pets/form"; + } + + @RequestMapping(method = RequestMethod.POST) + public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { + new PetValidator().validate(pet, result); + if (result.hasErrors()) { + return "pets/form"; + } + else { + this.clinic.storePet(pet); + status.setComplete(); + return "redirect:/owners/" + pet.getOwner().getId(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java new file mode 100644 index 000000000..683686440 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java @@ -0,0 +1,69 @@ + +package org.springframework.samples.petclinic.web; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.Visit; +import org.springframework.samples.petclinic.validation.VisitValidator; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.bind.support.SessionStatus; + +/** + * JavaBean form controller that is used to add a new Visit to the + * system. + * + * @author Juergen Hoeller + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +@RequestMapping("/owners/*/pets/{petId}/visits/new") +@SessionAttributes("visit") +public class AddVisitForm { + + private final Clinic clinic; + + + @Autowired + public AddVisitForm(Clinic clinic) { + this.clinic = clinic; + } + + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } + + @RequestMapping(method = RequestMethod.GET) + public String setupForm(@PathVariable("petId") int petId, Model model) { + Pet pet = this.clinic.loadPet(petId); + Visit visit = new Visit(); + pet.addVisit(visit); + model.addAttribute("visit", visit); + return "pets/visitForm"; + } + + @RequestMapping(method = RequestMethod.POST) + public String processSubmit(@ModelAttribute("visit") Visit visit, BindingResult result, SessionStatus status) { + new VisitValidator().validate(visit, result); + if (result.hasErrors()) { + return "pets/visitForm"; + } + else { + this.clinic.storeVisit(visit); + status.setComplete(); + return "redirect:/owners/" + visit.getPet().getOwner().getId(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java b/src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java new file mode 100644 index 000000000..2d2a8bdc1 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java @@ -0,0 +1,37 @@ +package org.springframework.samples.petclinic.web; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.propertyeditors.CustomDateEditor; +import org.springframework.beans.propertyeditors.StringTrimmerEditor; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.PetType; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.support.WebBindingInitializer; +import org.springframework.web.context.request.WebRequest; + +/** + * Shared WebBindingInitializer for PetClinic's custom editors. + * + *

    Alternatively, such init-binder code may be put into + * {@link org.springframework.web.bind.annotation.InitBinder} + * annotated methods on the controller classes themselves. + * + * @author Juergen Hoeller + */ +public class ClinicBindingInitializer implements WebBindingInitializer { + + @Autowired + private Clinic clinic; + + public void initBinder(WebDataBinder binder, WebRequest request) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + dateFormat.setLenient(false); + binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); + binder.registerCustomEditor(String.class, new StringTrimmerEditor(false)); + binder.registerCustomEditor(PetType.class, new PetTypeEditor(this.clinic)); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java b/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java new file mode 100644 index 000000000..e93ae8f66 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java @@ -0,0 +1,89 @@ + +package org.springframework.samples.petclinic.web; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Vets; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +/** + * Annotation-driven MultiActionController that handles all non-form + * URL's. + * + * @author Juergen Hoeller + * @author Mark Fisher + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +public class ClinicController { + + private final Clinic clinic; + + + @Autowired + public ClinicController(Clinic clinic) { + this.clinic = clinic; + } + + /** + * Custom handler for the welcome view. + *

    + * Note that this handler relies on the RequestToViewNameTranslator to + * determine the logical view name based on the request URL: "/welcome.do" + * -> "welcome". + */ + @RequestMapping("/") + public String welcomeHandler() { + return "welcome"; + } + + /** + * Custom handler for displaying vets. + * + *

    Note that this handler returns a plain {@link ModelMap} object instead of + * a ModelAndView, thus leveraging convention-based model attribute names. + * It relies on the RequestToViewNameTranslator to determine the logical + * view name based on the request URL: "/vets.do" -> "vets". + * + * @return a ModelMap with the model attributes for the view + */ + @RequestMapping("/vets") + public ModelMap vetsHandler() { + Vets vets = new Vets(); + vets.getVetList().addAll(this.clinic.getVets()); + return new ModelMap(vets); + } + + /** + * Custom handler for displaying an owner. + * + * @param ownerId the ID of the owner to display + * @return a ModelMap with the model attributes for the view + */ + @RequestMapping("/owners/{ownerId}") + public ModelAndView ownerHandler(@PathVariable("ownerId") int ownerId) { + ModelAndView mav = new ModelAndView("owners/show"); + mav.addObject(this.clinic.loadOwner(ownerId)); + return mav; + } + + /** + * Custom handler for displaying an list of visits. + * + * @param petId the ID of the pet whose visits to display + * @return a ModelMap with the model attributes for the view + */ + @RequestMapping(value="/owners/*/pets/{petId}/visits", method=RequestMethod.GET) + public ModelAndView visitsHandler(@PathVariable int petId) { + ModelAndView mav = new ModelAndView("visits"); + mav.addObject("visits", this.clinic.loadPet(petId).getVisits()); + return mav; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java b/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java new file mode 100644 index 000000000..0b65de51b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java @@ -0,0 +1,65 @@ + +package org.springframework.samples.petclinic.web; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.validation.OwnerValidator; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.bind.support.SessionStatus; + +/** + * JavaBean Form controller that is used to edit an existing Owner. + * + * @author Juergen Hoeller + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +@RequestMapping("/owners/{ownerId}/edit") +@SessionAttributes(types = Owner.class) +public class EditOwnerForm { + + private final Clinic clinic; + + + @Autowired + public EditOwnerForm(Clinic clinic) { + this.clinic = clinic; + } + + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } + + @RequestMapping(method = RequestMethod.GET) + public String setupForm(@PathVariable("ownerId") int ownerId, Model model) { + Owner owner = this.clinic.loadOwner(ownerId); + model.addAttribute(owner); + return "owners/form"; + } + + @RequestMapping(method = RequestMethod.PUT) + public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) { + new OwnerValidator().validate(owner, result); + if (result.hasErrors()) { + return "owners/form"; + } + else { + this.clinic.storeOwner(owner); + status.setComplete(); + return "redirect:/owners/" + owner.getId(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java b/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java new file mode 100644 index 000000000..1a7fd6ed3 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java @@ -0,0 +1,80 @@ + +package org.springframework.samples.petclinic.web; + +import java.util.Collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.validation.PetValidator; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.bind.support.SessionStatus; + +/** + * JavaBean Form controller that is used to edit an existing Pet. + * + * @author Juergen Hoeller + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +@RequestMapping("/owners/*/pets/{petId}/edit") +@SessionAttributes("pet") +public class EditPetForm { + + private final Clinic clinic; + + + @Autowired + public EditPetForm(Clinic clinic) { + this.clinic = clinic; + } + + @ModelAttribute("types") + public Collection populatePetTypes() { + return this.clinic.getPetTypes(); + } + + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } + + @RequestMapping(method = RequestMethod.GET) + public String setupForm(@PathVariable("petId") int petId, Model model) { + Pet pet = this.clinic.loadPet(petId); + model.addAttribute("pet", pet); + return "pets/form"; + } + + @RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST }) + public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { + new PetValidator().validate(pet, result); + if (result.hasErrors()) { + return "pets/form"; + } + else { + this.clinic.storePet(pet); + status.setComplete(); + return "redirect:/owners/" + pet.getOwner().getId(); + } + } + + @RequestMapping(method = RequestMethod.DELETE) + public String deletePet(@PathVariable int petId) { + Pet pet = this.clinic.loadPet(petId); + this.clinic.deletePet(petId); + return "redirect:/owners/" + pet.getOwner().getId(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java b/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java new file mode 100644 index 000000000..eb93fabad --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java @@ -0,0 +1,74 @@ + +package org.springframework.samples.petclinic.web; + +import java.util.Collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * JavaBean Form controller that is used to search for Owners by + * last name. + * + * @author Juergen Hoeller + * @author Ken Krebs + * @author Arjen Poutsma + */ +@Controller +public class FindOwnersForm { + + private final Clinic clinic; + + + @Autowired + public FindOwnersForm(Clinic clinic) { + this.clinic = clinic; + } + + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } + + @RequestMapping(value = "/owners/search", method = RequestMethod.GET) + public String setupForm(Model model) { + model.addAttribute("owner", new Owner()); + return "owners/search"; + } + + @RequestMapping(value = "/owners", method = RequestMethod.GET) + public String processSubmit(Owner owner, BindingResult result, Model model) { + + // allow parameterless GET request for /owners to return all records + if (owner.getLastName() == null) { + owner.setLastName(""); // empty string signifies broadest possible search + } + + // find owners by last name + Collection results = this.clinic.findOwners(owner.getLastName()); + if (results.size() < 1) { + // no owners found + result.rejectValue("lastName", "notFound", "not found"); + return "owners/search"; + } + if (results.size() > 1) { + // multiple owners found + model.addAttribute("selections", results); + return "owners/list"; + } + else { + // 1 owner found + owner = results.iterator().next(); + return "redirect:/owners/" + owner.getId(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java b/src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java new file mode 100644 index 000000000..812b648d7 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java @@ -0,0 +1,30 @@ +package org.springframework.samples.petclinic.web; + +import java.beans.PropertyEditorSupport; + +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.PetType; + +/** + * @author Mark Fisher + * @author Juergen Hoeller + */ +public class PetTypeEditor extends PropertyEditorSupport { + + private final Clinic clinic; + + + public PetTypeEditor(Clinic clinic) { + this.clinic = clinic; + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + for (PetType type : this.clinic.getPetTypes()) { + if (type.getName().equals(text)) { + setValue(type); + } + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java b/src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java new file mode 100644 index 000000000..e9da832e4 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java @@ -0,0 +1,82 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.web; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.sun.syndication.feed.atom.Content; +import com.sun.syndication.feed.atom.Entry; +import com.sun.syndication.feed.atom.Feed; + +import org.springframework.samples.petclinic.Visit; +import org.springframework.web.servlet.view.feed.AbstractAtomFeedView; + +/** + * A view creating a Atom representation from a list of Visit objects. + * + * @author Alef Arendsen + * @author Arjen Poutsma + */ +public class VisitsAtomView extends AbstractAtomFeedView { + + @Override + protected void buildFeedMetadata(Map model, Feed feed, HttpServletRequest request) { + feed.setId("tag:springsource.com"); + feed.setTitle("Pet Clinic Visits"); + @SuppressWarnings("unchecked") + List visits = (List) model.get("visits"); + for (Visit visit : visits) { + Date date = visit.getDate(); + if (feed.getUpdated() == null || date.compareTo(feed.getUpdated()) > 0) { + feed.setUpdated(date); + } + } + } + + @Override + protected List buildFeedEntries(Map model, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + @SuppressWarnings("unchecked") + List visits = (List) model.get("visits"); + List entries = new ArrayList(visits.size()); + + for (Visit visit : visits) { + Entry entry = new Entry(); + String date = String.format("%1$tY-%1$tm-%1$td", visit.getDate()); + // see http://diveintomark.org/archives/2004/05/28/howto-atom-id#other + entry.setId(String.format("tag:springsource.com,%s:%d", date, visit.getId())); + entry.setTitle(String.format("%s visit on %s", visit.getPet().getName(), date)); + entry.setUpdated(visit.getDate()); + + Content summary = new Content(); + summary.setValue(visit.getDescription()); + entry.setSummary(summary); + + entries.add(entry); + } + + return entries; + + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/package-info.java b/src/main/java/org/springframework/samples/petclinic/web/package-info.java new file mode 100644 index 000000000..c909ccf7f --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/web/package-info.java @@ -0,0 +1,8 @@ + +/** + * + * The classes in this package represent PetClinic's web presentation layer. + * + */ +package org.springframework.samples.petclinic.web; + diff --git a/src/main/java/overview.html b/src/main/java/overview.html new file mode 100644 index 000000000..1eb7a2e8c --- /dev/null +++ b/src/main/java/overview.html @@ -0,0 +1,7 @@ + + +

    +The Spring Data Binding framework, an internal library used by Spring Web Flow. +

    + + \ No newline at end of file diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties new file mode 100644 index 000000000..e039cdf1b --- /dev/null +++ b/src/main/resources/jdbc.properties @@ -0,0 +1,63 @@ +# Properties file with JDBC and JPA settings. +# +# Applied by from +# various application context XML files (e.g., "applicationContext-*.xml"). +# Targeted at system administrators, to avoid touching the context XML files. + + +#------------------------------------------------------------------------------- +# Common Settings + +hibernate.generate_statistics=true +hibernate.show_sql=true +jpa.showSql=true + + +#------------------------------------------------------------------------------- +# HSQL Settings + +jdbc.driverClassName=org.hsqldb.jdbcDriver +jdbc.url=jdbc:hsqldb:mem:petclinic +jdbc.username=sa +jdbc.password= + +# Properties that control the population of schema and data for a new data source +jdbc.populate=true +jdbc.schemaLocation=classpath:/META-INF/hsqldb/initDB.txt +jdbc.dataLocation=classpath:/META-INF/hsqldb/populateDB.txt +jdbc.dropLocation=classpath:/META-INF/hsqldb/dropTables.txt + +# Property that determines which Hibernate dialect to use +# (only applied with "applicationContext-hibernate.xml") +hibernate.dialect=org.hibernate.dialect.HSQLDialect + +# Property that determines which JPA DatabasePlatform to use with TopLink Essentials +jpa.databasePlatform=org.springframework.samples.petclinic.toplink.EssentialsHSQLPlatformWithNativeSequence + +# Property that determines which database to use with an AbstractJpaVendorAdapter +jpa.database=HSQL + + +#------------------------------------------------------------------------------- +# MySQL Settings + +#jdbc.driverClassName=com.mysql.jdbc.Driver +#jdbc.url=jdbc:mysql://localhost:3306/petclinic +#jdbc.username=pc +#jdbc.password=pc + +# Properties that control the population of schema and data for a new data source +#jdbc.populate=false +#jdbc.schemaLocation= +#jdbc.dataLocation= +#jdbc.dropLocation= + +# Property that determines which Hibernate dialect to use +# (only applied with "applicationContext-hibernate.xml") +#hibernate.dialect=org.hibernate.dialect.MySQLDialect + +# Property that determines which JPA DatabasePlatform to use with TopLink Essentials +#jpa.databasePlatform=oracle.toplink.essentials.platform.database.MySQL4Platform + +# Property that determines which database to use with an AbstractJpaVendorAdapter +#jpa.database=MYSQL diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 000000000..ebee551aa --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,18 @@ +# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml! +# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J. +log4j.rootLogger=INFO, stdout, logfile + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n + +log4j.appender.logfile=org.apache.log4j.RollingFileAppender +log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log +log4j.appender.logfile.MaxFileSize=512KB +# Keep three backup files. +log4j.appender.logfile.MaxBackupIndex=3 +# Pattern to output: date priority [category] - message +log4j.appender.logfile.layout=org.apache.log4j.PatternLayout +log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n + +log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties new file mode 100644 index 000000000..173417a10 --- /dev/null +++ b/src/main/resources/messages.properties @@ -0,0 +1,8 @@ +welcome=Welcome +required=is required +notFound=has not been found +duplicate=is already in use +nonNumeric=must be all numeric +duplicateFormSubmission=Duplicate form submission is not allowed +typeMismatch.date=invalid date +typeMismatch.birthDate=invalid date diff --git a/src/main/resources/messages_de.properties b/src/main/resources/messages_de.properties new file mode 100644 index 000000000..124bee48b --- /dev/null +++ b/src/main/resources/messages_de.properties @@ -0,0 +1,8 @@ +welcome=Willkommen +required=muss angegeben werden +notFound=wurde nicht gefunden +duplicate=ist bereits vergeben +nonNumeric=darf nur numerisch sein +duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt +typeMismatch.date=ungltiges Datum +typeMismatch.birthDate=ungltiges Datum diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties new file mode 100644 index 000000000..05d519bb8 --- /dev/null +++ b/src/main/resources/messages_en.properties @@ -0,0 +1 @@ +# This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file. \ No newline at end of file diff --git a/src/main/resources/petclinic.hbm.xml b/src/main/resources/petclinic.hbm.xml new file mode 100644 index 000000000..f9a993cf1 --- /dev/null +++ b/src/main/resources/petclinic.hbm.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/META-INF/aop.xml b/src/main/webapp/META-INF/aop.xml new file mode 100644 index 000000000..b49ffd8b1 --- /dev/null +++ b/src/main/webapp/META-INF/aop.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml new file mode 100644 index 000000000..d5deabaf7 --- /dev/null +++ b/src/main/webapp/META-INF/context.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/src/main/webapp/META-INF/hsqldb/dropTables.txt b/src/main/webapp/META-INF/hsqldb/dropTables.txt new file mode 100644 index 000000000..90ae6329f --- /dev/null +++ b/src/main/webapp/META-INF/hsqldb/dropTables.txt @@ -0,0 +1,7 @@ +DROP TABLE visits; +DROP TABLE pets; +DROP TABLE owners; +DROP TABLE types; +DROP TABLE vet_specialties; +DROP TABLE specialties; +DROP TABLE vets; diff --git a/src/main/webapp/META-INF/hsqldb/initDB.txt b/src/main/webapp/META-INF/hsqldb/initDB.txt new file mode 100644 index 000000000..a75bfbbd8 --- /dev/null +++ b/src/main/webapp/META-INF/hsqldb/initDB.txt @@ -0,0 +1,55 @@ +CREATE TABLE vets ( + id INTEGER NOT NULL IDENTITY PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30) +); +CREATE INDEX vets_last_name ON vets(last_name); + +CREATE TABLE specialties ( + id INTEGER NOT NULL IDENTITY PRIMARY KEY, + name VARCHAR(80) +); +CREATE INDEX specialties_name ON specialties(name); + +CREATE TABLE vet_specialties ( + vet_id INTEGER NOT NULL, + specialty_id INTEGER NOT NULL +); +alter table vet_specialties add constraint fk_vet_specialties_vets foreign key (vet_id) references vets(id); +alter table vet_specialties add constraint fk_vet_specialties_specialties foreign key (specialty_id) references specialties(id); + +CREATE TABLE types ( + id INTEGER NOT NULL IDENTITY PRIMARY KEY, + name VARCHAR(80) +); +CREATE INDEX types_name ON types(name); + +CREATE TABLE owners ( + id INTEGER NOT NULL IDENTITY PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30), + address VARCHAR(255), + city VARCHAR(80), + telephone VARCHAR(20) +); +CREATE INDEX owners_last_name ON owners(last_name); + +CREATE TABLE pets ( + id INTEGER NOT NULL IDENTITY PRIMARY KEY, + name VARCHAR(30), + birth_date DATE, + type_id INTEGER NOT NULL, + owner_id INTEGER NOT NULL +); +alter table pets add constraint fk_pets_owners foreign key (owner_id) references owners(id); +alter table pets add constraint fk_pets_types foreign key (type_id) references types(id); +CREATE INDEX pets_name ON pets(name); + +CREATE TABLE visits ( + id INTEGER NOT NULL IDENTITY PRIMARY KEY, + pet_id INTEGER NOT NULL, + visit_date DATE, + description VARCHAR(255) +); +alter table visits add constraint fk_visits_pets foreign key (pet_id) references pets(id); +CREATE INDEX visits_pet_id ON visits(pet_id); diff --git a/src/main/webapp/META-INF/hsqldb/populateDB.txt b/src/main/webapp/META-INF/hsqldb/populateDB.txt new file mode 100644 index 000000000..1bf0c4a6e --- /dev/null +++ b/src/main/webapp/META-INF/hsqldb/populateDB.txt @@ -0,0 +1,53 @@ +INSERT INTO vets VALUES (1, 'James', 'Carter'); +INSERT INTO vets VALUES (2, 'Helen', 'Leary'); +INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); +INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); +INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); +INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); + +INSERT INTO specialties VALUES (1, 'radiology'); +INSERT INTO specialties VALUES (2, 'surgery'); +INSERT INTO specialties VALUES (3, 'dentistry'); + +INSERT INTO vet_specialties VALUES (2, 1); +INSERT INTO vet_specialties VALUES (3, 2); +INSERT INTO vet_specialties VALUES (3, 3); +INSERT INTO vet_specialties VALUES (4, 2); +INSERT INTO vet_specialties VALUES (5, 1); + +INSERT INTO types VALUES (1, 'cat'); +INSERT INTO types VALUES (2, 'dog'); +INSERT INTO types VALUES (3, 'lizard'); +INSERT INTO types VALUES (4, 'snake'); +INSERT INTO types VALUES (5, 'bird'); +INSERT INTO types VALUES (6, 'hamster'); + +INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); + +INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1); +INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2); +INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3); +INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3); +INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4); +INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5); +INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6); +INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6); +INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7); +INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8); +INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9); +INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10); +INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10); + +INSERT INTO visits VALUES (1, 7, '1996-03-04', 'rabies shot'); +INSERT INTO visits VALUES (2, 8, '1996-03-04', 'rabies shot'); +INSERT INTO visits VALUES (3, 8, '1996-06-04', 'neutered'); +INSERT INTO visits VALUES (4, 7, '1996-09-04', 'spayed'); diff --git a/src/main/webapp/META-INF/orm.xml b/src/main/webapp/META-INF/orm.xml new file mode 100644 index 000000000..d7c8f7040 --- /dev/null +++ b/src/main/webapp/META-INF/orm.xml @@ -0,0 +1,122 @@ + + + + + + + PROPERTY + + + + org.springframework.samples.petclinic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + + + + + + + + + +
    + + + + DATE + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + DATE + + + + + + + + + + diff --git a/src/main/webapp/META-INF/persistence.xml b/src/main/webapp/META-INF/persistence.xml new file mode 100644 index 000000000..86bf7c115 --- /dev/null +++ b/src/main/webapp/META-INF/persistence.xml @@ -0,0 +1,16 @@ + + + + + + META-INF/orm.xml + + + true + + + + diff --git a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml new file mode 100644 index 000000000..bfc166db6 --- /dev/null +++ b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + ${hibernate.dialect} + ${hibernate.show_sql} + ${hibernate.generate_statistics} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/applicationContext-jdbc.xml b/src/main/webapp/WEB-INF/applicationContext-jdbc.xml new file mode 100644 index 000000000..69a2b1f5d --- /dev/null +++ b/src/main/webapp/WEB-INF/applicationContext-jdbc.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/applicationContext-jpa.xml b/src/main/webapp/WEB-INF/applicationContext-jpa.xml new file mode 100644 index 000000000..25374e9ab --- /dev/null +++ b/src/main/webapp/WEB-INF/applicationContext-jpa.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/classes/log4j.properties b/src/main/webapp/WEB-INF/classes/log4j.properties new file mode 100644 index 000000000..ebee551aa --- /dev/null +++ b/src/main/webapp/WEB-INF/classes/log4j.properties @@ -0,0 +1,18 @@ +# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml! +# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J. +log4j.rootLogger=INFO, stdout, logfile + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n + +log4j.appender.logfile=org.apache.log4j.RollingFileAppender +log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log +log4j.appender.logfile.MaxFileSize=512KB +# Keep three backup files. +log4j.appender.logfile.MaxBackupIndex=3 +# Pattern to output: date priority [category] - message +log4j.appender.logfile.layout=org.apache.log4j.PatternLayout +log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n + +log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG diff --git a/src/main/webapp/WEB-INF/classes/messages.properties b/src/main/webapp/WEB-INF/classes/messages.properties new file mode 100644 index 000000000..173417a10 --- /dev/null +++ b/src/main/webapp/WEB-INF/classes/messages.properties @@ -0,0 +1,8 @@ +welcome=Welcome +required=is required +notFound=has not been found +duplicate=is already in use +nonNumeric=must be all numeric +duplicateFormSubmission=Duplicate form submission is not allowed +typeMismatch.date=invalid date +typeMismatch.birthDate=invalid date diff --git a/src/main/webapp/WEB-INF/classes/messages_de.properties b/src/main/webapp/WEB-INF/classes/messages_de.properties new file mode 100644 index 000000000..124bee48b --- /dev/null +++ b/src/main/webapp/WEB-INF/classes/messages_de.properties @@ -0,0 +1,8 @@ +welcome=Willkommen +required=muss angegeben werden +notFound=wurde nicht gefunden +duplicate=ist bereits vergeben +nonNumeric=darf nur numerisch sein +duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt +typeMismatch.date=ungltiges Datum +typeMismatch.birthDate=ungltiges Datum diff --git a/src/main/webapp/WEB-INF/classes/messages_en.properties b/src/main/webapp/WEB-INF/classes/messages_en.properties new file mode 100644 index 000000000..05d519bb8 --- /dev/null +++ b/src/main/webapp/WEB-INF/classes/messages_en.properties @@ -0,0 +1 @@ +# This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file. \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/geronimo-web.xml b/src/main/webapp/WEB-INF/geronimo-web.xml new file mode 100644 index 000000000..b5d88e1ec --- /dev/null +++ b/src/main/webapp/WEB-INF/geronimo-web.xml @@ -0,0 +1,6 @@ + + + /petclinic + true + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp b/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp new file mode 100644 index 000000000..256cca177 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp @@ -0,0 +1,19 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + +<% +Exception ex = (Exception) request.getAttribute("exception"); +%> + +

    Data access failure: <%= ex.getMessage() %>

    +

    + +<% +ex.printStackTrace(new java.io.PrintWriter(out)); +%> + +

    +
    +">Home + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/footer.jsp b/src/main/webapp/WEB-INF/jsp/footer.jsp new file mode 100644 index 000000000..52aaffc47 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/footer.jsp @@ -0,0 +1,12 @@ + +

    + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp new file mode 100644 index 000000000..49393d364 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/header.jsp @@ -0,0 +1,14 @@ + + + + + + " type="text/css"/> + PetClinic :: a Spring Framework demonstration + + + + +
    diff --git a/src/main/webapp/WEB-INF/jsp/includes.jsp b/src/main/webapp/WEB-INF/jsp/includes.jsp new file mode 100644 index 000000000..96c3e304c --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/includes.jsp @@ -0,0 +1,5 @@ +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> diff --git a/src/main/webapp/WEB-INF/jsp/owners/form.jsp b/src/main/webapp/WEB-INF/jsp/owners/form.jsp new file mode 100644 index 000000000..1670a7c1b --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/owners/form.jsp @@ -0,0 +1,61 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + + + + + +

    New Owner:

    + + + + + + + + + + + + + + + + + + + + +
    + First Name: +
    + +
    + Last Name: +
    + +
    + Address: +
    + +
    + City: +
    + +
    + Telephone: +
    + +
    + + +

    +
    + +

    +
    +
    +
    +
    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/owners/list.jsp b/src/main/webapp/WEB-INF/jsp/owners/list.jsp new file mode 100644 index 000000000..44fc3cac0 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/owners/list.jsp @@ -0,0 +1,34 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + +

    Owners:

    + + + + + + + + + + + + + + + + + + +
    NameAddressCityTelephonePets
    + + + + ${owner.firstName} ${owner.lastName} + ${owner.address}${owner.city}${owner.telephone} + + ${pet.name}   + +
    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/owners/search.jsp b/src/main/webapp/WEB-INF/jsp/owners/search.jsp new file mode 100644 index 000000000..b972390a1 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/owners/search.jsp @@ -0,0 +1,26 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + + +

    Find Owners:

    + + + + + + + + + + +
    + Last Name: +
    + +

    +
    + +
    +Add Owner + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/owners/show.jsp b/src/main/webapp/WEB-INF/jsp/owners/show.jsp new file mode 100644 index 000000000..9767c18ae --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/owners/show.jsp @@ -0,0 +1,108 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + +

    Owner Information

    + + + + + + + + + + + + + + + + + + +
    Name${owner.firstName} ${owner.lastName}
    Address${owner.address}
    City${owner.city}
    Telephone ${owner.telephone}
    + + + + + +
    + + + + Edit Owner + + + + + Add New Pet +
    + +

    Pets and Visits

    + + + + + + + +
    + + + + + + + + + + + + + +
    Name${pet.name}
    Birth Date
    Type${pet.type.name}
    +
    + + + + + + + + + + + +
    Visit DateDescription
    ${visit.description}
    +
    + + + + + + + + +
    + + + + + Edit Pet + + + + + + Add Visit + + + + + + Atom Feed +
    +
    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/pets/form.jsp b/src/main/webapp/WEB-INF/jsp/pets/form.jsp new file mode 100644 index 000000000..459ec63b3 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/pets/form.jsp @@ -0,0 +1,56 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + + + + + +

    New Pet

    + +Owner: ${pet.owner.firstName} ${pet.owner.lastName} +
    + + + + + + + + + + + + + + +
    + Name: +
    + +
    + Birth Date: +
    + (yyyy-mm-dd) +
    + Type: +
    + +
    + + +

    +
    + +

    +
    +
    +
    +
    + + + +

    +
    +
    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp new file mode 100644 index 000000000..b1207a00f --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp @@ -0,0 +1,68 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + +

    New Visit:

    + + + Pet: + + + + + + + + + + + + + +
    NameBirth DateTypeOwner
    ${visit.pet.name}${visit.pet.type.name}${visit.pet.owner.firstName} ${visit.pet.owner.lastName}
    + + + + + + + + + + + + + +
    + Date: +
    +
    + (yyyy-mm-dd) +
    + Description: +
    +
    + +
    + +

    +
    +
    + +
    +Previous Visits: + + + + + + + + + + + + + +
    DateDescription
    ${visit.description}
    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp b/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp new file mode 100644 index 000000000..e97fdf378 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp @@ -0,0 +1,49 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + +

    Internal error

    +

    + +<% +try { + // The Servlet spec guarantees this attribute will be available + Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); + + if (exception != null) { + if (exception instanceof ServletException) { + // It's a ServletException: we should extract the root cause + ServletException sex = (ServletException) exception; + Throwable rootCause = sex.getRootCause(); + if (rootCause == null) + rootCause = sex; + out.println("** Root cause is: "+ rootCause.getMessage()); + rootCause.printStackTrace(new java.io.PrintWriter(out)); + } + else { + // It's not a ServletException, so we'll just show it + exception.printStackTrace(new java.io.PrintWriter(out)); + } + } + else { + out.println("No error information available"); + } + + // Display cookies + out.println("\nCookies:\n"); + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + out.println(cookies[i].getName() + "=[" + cookies[i].getValue() + "]"); + } + } + +} catch (Exception ex) { + ex.printStackTrace(new java.io.PrintWriter(out)); +} +%> + +

    +
    + + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/vets.jsp b/src/main/webapp/WEB-INF/jsp/vets.jsp new file mode 100644 index 000000000..cff2154f2 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/vets.jsp @@ -0,0 +1,31 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + +

    Veterinarians:

    + + + + + + + + + + + + +
    NameSpecialties
    ${vet.firstName} ${vet.lastName} + + ${specialty.name} + + none +
    + + + + +
    + ">View as XML +
    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp new file mode 100644 index 000000000..1b07c65c3 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp @@ -0,0 +1,15 @@ +<%@ include file="/WEB-INF/jsp/includes.jsp" %> +<%@ include file="/WEB-INF/jsp/header.jsp" %> + +" align="right" style="position:relative;right:30px;"> +

    + + + +

     

    + +<%@ include file="/WEB-INF/jsp/footer.jsp" %> diff --git a/src/main/webapp/WEB-INF/petclinic-servlet.xml b/src/main/webapp/WEB-INF/petclinic-servlet.xml new file mode 100644 index 000000000..3c05fc300 --- /dev/null +++ b/src/main/webapp/WEB-INF/petclinic-servlet.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + pageNotFound + dataAccessFailure + dataAccessFailure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..06a6a3110 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,161 @@ + + + + Spring PetClinic + + Spring PetClinic sample application + + + + webAppRootKey + petclinic.root + + + + + + + log4jConfigLocation + /WEB-INF/classes/log4j.properties + + + + + contextConfigLocation + + /WEB-INF/applicationContext-jdbc.xml + + + + + + + + + + + + org.springframework.web.context.ContextLoaderListener + + + + + default + /static/* + + + + + petclinic + org.springframework.web.servlet.DispatcherServlet + 2 + + + + + petclinic + / + + + + httpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + + httpMethodFilter + petclinic + + + + 10 + + + + java.lang.Exception + + /WEB-INF/jsp/uncaughtException.jsp + + + + + + diff --git a/src/main/webapp/html/tutorial.html b/src/main/webapp/html/tutorial.html new file mode 100644 index 000000000..acc261fb1 --- /dev/null +++ b/src/main/webapp/html/tutorial.html @@ -0,0 +1,1153 @@ + + + + The Spring PetClinic Application + + + + + + +
    + +

    The Spring PetClinic Application

    + + + + +

    Introduction

    + +

    + The Spring Framework is a collection of small, well-focused, loosely coupled Java + frameworks that can be used independently or collectively to build + industrial strength applications of many different types. The PetClinic + sample application is designed to show how the Spring + application frameworks can be used to build simple, but powerful + database-oriented applications. It will demonstrate the use + of Spring's core functionality: +

    + +
      +
    • JavaBeans based application configuration using Inversion-Of-Control
    • +
    • Model-View-Controller web Presentation Layer
    • +
    • Practical database access through JDBC, Hibernate, or Java Persistence API
    • +
    • Application monitoring based on JMX
    • +
    • Declarative Transaction Management using AOP
    • +
    • Data Validation that supports but is not dependent on the Presentation Layer
    • +
    + +

    + The Spring frameworks provide a great deal of useful infrastructure to + simplify the tasks faced by application developers. This infrastructure + helps developers to create applications that are: +

    + +
      +
    • + concise + by handling a lot of the complex control flow that is needed to use the + Java API's, such as JDBC, JNDI, JTA, RMI, and EJB. +
    • +
    • + flexible + by simplifying the process of external application configuration + through the use of Reflection and JavaBeans. This allows the developer to + achieve a clean separation of configuration data from application code. + All application and web application objects, including validators, + workflow controllers, and views, are JavaBeans that can be configured + externally.
    • +
    • + testable + by supplying an interface based design to maximize pluggability. This + facilitates unit testing of Business Logic without requiring the + presence of application or live database servers.
    • +
    • + maintainable + by facilitating a clean separation of the application layers. It most + importantly helps maintain the independence of the Business Layer + from the Presentation layer. PetClinic demonstrates the use of a + Model-View-Controller + based web presentation framework that can work seamlessly with many + different types of view technologies. The Spring web application + framework helps developers to implement their Presentation as a clean + and thin layer focused on its main missions of translating user actions + into application events and rendering model data.
    • +
    + +

    + It is assumed that users of this tutorial will have a basic knowledge + of object-oriented design, Java, Servlets, JSP, and relational + databases. It also assumes a basic knowledge of the use of a Java EE web + application container. +

    + +

    + Since the purpose of the sample application is tutorial in nature, the + implementation presented here will of course provide only a small + subset of the functionality that would be needed by a real world version of a + PetClinic application. +

    + + +

    PetClinic Sample Application Requirements

    + +

    + The application requirement is for an information system that is + accessible through a web browser. The users of the application are + employees of the clinic who in the course of their work need to view + and manage information regarding the veterinarians, the clients, and their + pets. The sample application supports the following: +

    + +

    Use Cases

    +
      +
    • View a list of veterinarians and their specialties
    • +
    • View information pertaining to a pet owner
    • +
    • Update the information pertaining to a pet owner
    • +
    • Add a new pet owner to the system
    • +
    • View information pertaining to a pet
    • +
    • Update the information pertaining to a pet
    • +
    • Add a new pet to the system
    • +
    • View information pertaining to a pet's visitation history
    • +
    • Add information pertaining to a visit to the pet's visitation history
    • +
    + +

    Business Rules

    +
      +
    1. An owner may not have multiple pets with the same case-insensitive name.
    2. +
    + + +

    PetClinic Sample Application Design & Implementation

    + +

    Server Technology

    +

    + The sample application should be usable with any Java EE web application + container that is compatible with the Servlet 2.4 and JSP 2.0 + specifications. Some of the deployment files provided are designed + specifically for Apache Tomcat. These files specify container-supplied + connection-pooled data sources. It is not necessary to use these files. + The application has been configured by default to use a data source + with connection pooling. Configuration details are + provided in the Developer Instructions section. The view technologies + that are to be used for rendering the application are Java Server Pages + (JSP) along with the Java Standard Tag Library (JSTL). +

    + +

    Database Technology

    +

    + The sample application uses a relational database for data storage. + Support has been provided for a choice of 1 of 2 database selections, + MySql or HypersonicSQL. HypersonicSQL version 1.8.0 is the default + choice. It is possible to + easily configure the application to use either database. Configuration + details are provided in the Developer Instructions section. +

    + +

    Development Environment

    +

    + A copy of the Spring runtime library jar file is provided with the + sample application along with some of the other required jar files. The + developer will need to obtain the following tools externally, all of + which are freely available: +

    + +
      +
    • Java SDK 1.5.x
    • +
    • Maven 2.0.10+
    • +
    • Ant 1.7.1 (for executing scripts, if needed, against the in-memory database)
    • +
    • Tomcat 6.x.x, or some other Java Servlet container
    • +
    • (Optional) MySQL 5.x with MySQL Connector/J 5.x
    • +
    + +

    + NOTE: The version numbers listed are those that were used + in the development of the PetClinic application. Other versions of the same + tools may or may not work. +

    + +

    + Download links for the various tools needed are provided in the Developer + Instructions section. +

    + +

    PetClinic Database

    +

    + The following is an overview of the database schema used in PetClinic. + Detailed field descriptions can be found in the + "initDB.txt" + SQL script files in the database-specific "db" sub-directories. All "id" key + fields are of Java type int. +

    + +

    + TABLE: owners
    +     PRIMARY KEY id +

    + +

    + TABLE: types
    +     PRIMARY KEY id +

    + +

    + TABLE: pets
    +     PRIMARY KEY id
    +     FOREIGN KEY type_id + references the types + table id field
    +     FOREIGN KEY owner_id + references the owners + table id field +

    + +

    + TABLE: vets
    +     PRIMARY KEY id +

    + +

    + TABLE: specialties
    +     PRIMARY KEY id
    +

    + +

    + TABLE: vet_specialties - + a link table for vets + and their specialties
    +     FOREIGN KEY vet_id + references the vets + table id field
    +     FOREIGN KEY specialty_id + references the specialties + table id field +

    + +

    + TABLE: visits
    +     PRIMARY KEY id
    +     FOREIGN KEY pet_id + references the pets + table id field +

    + +

    Directory Structure

    + +

    + d-- indicates a directory holding source code, configuration files, etc.
    + D-- indicates a directory that is created by the build script +

    + +

    + d-- petclinic: + the root directory of the project contains build related files
    + +     d-- src: contains + Java source code files and ORM configuration files
    + +     d-- war: contains + the web application resource files
    + +         d-- html: contains + tutorial files
    + +         D-- docs: contains + Javadoc files
    + +         d-- web-inf: + contains web application configuration files and application context + files
    + +               + d-- jsp: + contains Java Server Page files
    + +               + D-- lib: + contains application dependencies
    + +     d-- test: contains + testing related + Java source code files
    + +     d-- db: contains + database SQL scripts and other related files/directories
    + +         d-- hsqldb: + contains files related to HSQL, contains scripts and a Tomcat + context definition file
    + +         d-- mysql: + contains files related to MySQL, contains scripts and a Tomcat context + definition file
    + +     D-- .classes: + contains compiled Java class files
    + +     D-- .testclasses: + contains compiled testing related Java class files
    + +     D-- junit-reports: + contains generated xml-formatted test reports
    + +          D-- reports/html: + contains generated html-formatted test reports
    + +     D-- dist: contains + packaged archives of files +

    + + +

    PetClinic Application Design

    + +

    Logging

    +

    + Spring supports the use of the Apache Commons Logging API. This API + provides the ability to use Java 1.4 loggers, the simple Commons loggers, + and Apache log4j loggers. PetClinic uses log4j to provide sophisticated + and configurable logging capabilities. The file, + src/main/resources/log4j.properties + configures the definition of log4jloggers. +

    + +

    Business Layer

    +

    + The Business Layer consists of a number of basic JavaBean classes + representing the application domain objects and associated validation + objects that are used by the Presentation Layer. The validation objects + used in PetClinic are all implementations of the + org.springframework.validation.Validator interface. +

    + +
      +
    • org.springframework.samples.petclinic.Entity + is a simple JavaBean superclass used for all persistable objects.
    • +
    • org.springframework.samples.petclinic.NamedEntity + is an extension of Entity that adds a name property.
    • +
    • org.springframework.samples.petclinic.Specialty + is an extension of NamedEntity.
    • +
    • org.springframework.samples.petclinic.PetType + is an extension of NamedEntity.
    • +
    • org.springframework.samples.petclinic.Person is + an extension of Entity that provides a superclass for all objects that + implement the notion of a person.
    • +
    • org.springframework.samples.petclinic.Vet is + an extension of Person that implements a + veterinarian. It holds a List of + specialties that the Vet is capable of.
    • +
    • org.springframework.samples.petclinic.Owner + is an extension of Person that implements a pet owner. + It holds a List of pets owned.
    • +
    • org.springframework.samples.petclinic.Pet + is an extension of NamedEntity that + implements a pet. It holds a List of + visits made concerning the pet.
    • +
    • org.springframework.samples.petclinic.Visit + is a simple JavaBean that implements the notion of a clinic visit + for a pet.
    • +
    • org.springframework.samples.petclinic.util.EntityUtils + provides utility methods for handling entities.
    • +
    + +
      +
    • org.springframework.samples.petclinic.validation.OwnerValidator + is a Spring Validator that + verifies correct data entry for the Add and Edit Owner forms.
    • +
    • org.springframework.samples.petclinic.validation.PetValidator + is a Spring Validator that + verifies correct data entry for the Add and Edit Pet forms.
    • +
    • org.springframework.samples.petclinic.validation.VisitValidator + is a Spring Validator that + verifies correct data entry for the AddVisit form.
    • +
    + +

    Business / Persistence Layer

    + +

    + Since the PetClinic application is all about database access and there is + very little business logic in the application outside of that, there is + no separation of the primary Business and Persistence Layer API's. + While this design technique should not be used for an application with more + complex business logic, it is acceptable here because all of the + non-persistence related business rules have been implemented in + business objects and have not leaked into the Persistence Layer. The most + important facet of the design is that the Business and Persistence + Layers are COMPLETELY independent of the Presentation Layer. +

    + +

    + The Persistence Layer can be configured to use either HSQL or MySQL + with any one of the following data access technologies aided by + infrastructure provided by Spring: +

    + +
      +
    • JDBC
    • +
    • Hibernate 3
    • +
    • Java Persistence API
    • +
    + +

    + NOTE: Spring also provides + infrastructure for using other + Object/Relational Mapping + frameworks such as JDO and iBATIS SqlMaps, but these are not demonstrated in PetClinic. + (See the 'jpetstore' sample application that ships with the full Spring Framework + distribution for an example of using iBatis and Spring.) +

    + +

    + One of the key elements provided by Spring is the use of a common set + of meaningful data access exceptions that can be used regardless of + which database or access strategy is used. All of these exceptions + derive from org.springframework.dao.DataAccessException. + Since most exceptions encountered during database access are indicative + of programming errors, DataAccessException is an + abstract RuntimeException whose derivatives only need + to be caught by application code to handle recoverable errors when it + makes sense to do so. This greatly simplifies application code compared + to, for example, code using JDBC directly where SqlExceptions + must be caught and database specific error codes must be decoded. + Examination of the PetClinic source code will show that the + persistence-oriented code is completely focused on the relevant + transfer of data to/from the referenced objects without extraneous + error handling. +

    + +

    + The high-level business/persistence API for PetClinic is the + org.springframework.samples.petclinic.Clinic + interface. Each persistence strategy in PetClinic is a different implementation of the + Clinic interface. In each case, the + Clinic implementation is fronted by + a transactional proxy, configured via the + @Transactional annotation, that also + implements Clinic. These objects + are standard Java dynamic proxies which are created by an instance of + org.springframework.transaction.interceptor.TransactionProxyFactoryBean. + These proxies are configured in the respective application context file + via <tx:annotation-driven /> and specify that all + Clinic methods are run in a + transactional context. The transaction managers used in PetClinic are all + implementations of the + org.springframework.transaction.PlatformTransactionManager + interface. All of the implementations are by default configured + to use a local DataSource that + will work in any environment through the use of an instance of + org.springframework.jdbc.datasource.DriverManagerDataSource. + While this is appropriate for use in a demo or single user + program, a connection pooling DataSource, + such as an instance of org.apache.commons.dbcp.BasicDataSource, + is more appropriate for use in a multi-user application. Another + alternative is to obtain one through the Java EE environment + using an instance of + org.springframework.jndi.JndiObjectFactoryBean. +

    + +

    JDBC Clinic Implementation

    +

    + Spring provides a number of high-level database + access convenience classes in the package + org.springframework.jdbc.object. + These classes and the lower-level Spring classes that they use in the + org.springframework.jdbc.core package + provide a higher level of abstraction for using JDBC that keeps the developer + from having to correctly implement the handling of the checked + SqlExceptions with ugly error-prone + nested try-catch-finally blocks. Using the classes in this package + allows the developer to focus efforts on the functionality being + implemented rather than the mechanics of error handling. When using + these classes, it is the responsibility of the developer to provide the + SQL needed and to map the parameters to/from the respective domain + object. This typically is done by extending one of the + org.springframework.jdbc.object classes, + initializing its SQL, and overriding a method that takes care of + the mapping. In this way, the developer gets to focus on implementing + functionality rather than application plumbing. These classes also + take care of closing connections to prevent hard to find resource + leakage problems. It should be noted that instances of these classes + are lightweight, reusable, and threadsafe. +

    + +

    + The JDBC implementation of the Clinic interface is + org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic, + which uses Java 5 language features, + org.springframework.jdbc.core.simple.SimpleJdbcTemplate, and + org.springframework.jdbc.core.simple.SimpleJdbcInsert. + It also takes advantage of classes like + org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource and + org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper + which provide automatic mapping between JavaBean properties and JDBC + parameters or query results. SimpleJdbcClinic is a rewrite of the + AbstractJdbcClinic which was the base class for JDBC implementations of + the Clinic interface for Spring 2.0. +

    + +

    + The transaction manager used in the JDBC Clinic Implementation is an + instance of org.springframework.jdbc.datasource.DataSourceTransactionManager + that can be used for local transactions. +

    + +

    Hibernate 3 Clinic Implementation

    +

    + The Hibernate 3 implementation of the Clinic + interface is + org.springframework.samples.petclinic.hibernate.HibernateClinic. + To simplify using Hibernate, Spring provides the + org.springframework.orm.hibernate3.LocalSessionFactoryBean. + The Hibernate configuration is provided by the file src/main/resources/petclinic.hbm.xml. +

    + +

    Java Persistence API (JPA) Clinic Implementation

    +

    + The JPA implementation of the Clinic + interface is + org.springframework.samples.petclinic.jpa.EntityManagerClinic, + which is based on native JPA usage combined with Spring's + @Repository and + @Transactional annotations but + otherwise has no dependencies on any Spring API's. + To simplify JPA usage, Spring provides (among other classes) the + org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean. + The JPA configuration is provided by + src/main/resources/META-INF/orm.xml and + src/main/resources/META-INF/persistence.xml. +

    + +

    ApplicationContext

    +

    + A Spring org.springframework.context.ApplicationContext object + provides a map of user-defined JavaBeans that specify either a singleton + object or the initial construction of prototype instances. These beans + constitute the Business/Persistence + Layer of PetClinic. The following beans are defined in all 3 + versions (1 per access strategy) of the PetClinic + src/main/webapp/WEB-INF/applicationContext-*.xml + file: +

    + +
      +
    1. A PropertyPlaceholderConfigurer, + which is configured via + <context:property-placeholder ... /> and + is a singleton bean that replaces ${...} placeholders with values from a + properties file, in this case, JDBC-related settings for the + dataSource bean + described below + (see src/main/resources/jdbc.properties). +
    2. +
    3. dataSource, + which is a singleton bean that defines the implementation of the source + of database connections used by the application. +
    4. +
    5. transactionManager, + which is a singleton bean that defines the implementation of the transaction + management strategy for the application. +
    6. +
    7. clinic, + which is a singleton bean that defines the implementation of the + Clinic interface that provides the + primary Business Layer API of the application. +
    8. +
    + +

    Presentation Layer

    +

    + The Presentation Layer is implemented as a Java EE Web Application and + provides a very thin and concise Model-View-Controller type user + interface to the Business and Persistence Layers. +

    + +

    + The PetClinic web application is configured via the following files: +

    + +
      +
    • src/main/webapp/WEB-INF/web.xml: + the web application configuration file.
    • +
    • src/main/webapp/WEB-INF/petclinic-servlet.xml: + configures the petclinic dispatcher servlet and the other controllers + and forms that it uses. The beans defined in this file reference the + Business/Persistence Layer beans defined in + applicationContext-*.xml.
    • +
    • src/main/resources/messages*.properties: + configures the definition of internationalizable message resources.
    • +
    + +

    + Examine the comments provided in each of these files for a more + in-depth understanding of the details of how the application is + configured. +

    + +

    General

    + +
      +
    • In web.xml, + a context-param, "webAppRootkey", + provides the key for a system property that specifies the root directory + for the web application. This parameter, + "petclinic.root", can be used to aid + in configuring the application.
    • +
    • In web.xml, + a org.springframework.web.context.ContextLoaderListener + is defined that loads the root ApplicationContext + object of this webapp at startup, by default from the designated + /WEB-INF/applicationContext-*.xml. + The root org.springframework.web.context.WebApplicationContext + of PetClinic is an instance of + org.springframework.web.context.support.XmlWebApplicationContext + and is the parent of all servlet-specific ApplicationContexts. + The Spring root ApplicationContext object + provides a map of user-defined JavaBeans that can be used in any and + all layers of the application. Beans defined in the root + ApplicationContext are automatically + available in all child ApplicationContext + objects as (external) bean references. Beans defined in an + ApplicationContext can also be + accessed directly by Java code through + getBean(name) method calls. +
    • + +
    • In web.xml, + a Servlet named + "petclinic" is specified to act as + a dispatcher for the entire application. This + org.springframework.web.servlet.DispatcherServlet + is used to handle all URL's matching the pattern "*.do". + As with any Servlet, multiple URL mappings may + be defined. It is also possible to define multiple instances of + DispatcherServlet. Each + DispatcherServlet dispatches + requests to registered handlers (Controller + interface implementations or POJOs annotated with @Controller) + indirectly through a + org.springframework.web.servlet.handler.HandlerMapping + implementation. Each DispatcherServlet + has its own ApplicationContext, + by default defined in "{servlet-name}-servlet.xml". + In this case, it is in the file "petclinic-servlet.xml". + This ApplicationContext is + used to specify the various web application user interface beans and + the URL mappings that are used by the DispatcherServlet + to control the handling of requests. +
    • +
    + +

    + The files web.xml and + log4j.properties specify + the configuration of logging in the system: +

    + +
      +
    • In web.xml, + a "log4jConfigLocation" context-param + is specified that sets the location of the + log4j configuration file. The + default location for this file is + /WEB-INF/classes/log4j.properties. + Specifying this parameter explicitly allows the location to be changed + from the default and is also used to cause periodic + log4j configuration refresh checks.
    • +
    • In web.xml, + a Log4jConfigListener is + specified that will initialize log4j using + the specified configuration file when the web app starts. The + Log4jConfigListener is commented out + in the file because of a conflict when using JBoss. It should also be + noted that if the container initializes Servlets before Listeners as + some pre-Servlet 2.4 containers do, a Log4jConfigServlet should + be used instead.
    • +
    • In log4j.properties, + the following loggers are specified: +
        +
      • "stdout" provides + logging messages to the container's log file.
      • +
      • "logfile" provides + logging messages to a rolling file that is specified using the + previously defined "petclinic.root".
      • +
      +
    • +
    + +

    + Examination and study of these logging files will provide insight into + the operation of the Spring framework and the application as well as + valuable troubleshooting information should something not work + correctly. +

    + +

    DispatcherServlet

    +

    + The following beans are accessible to the + DispatcherServlet and are defined + in the PetClinic + petclinic-servlet.xml + file. This dispatcher uses these definitions to delegate actual display + and form processing tasks to implementations of the Spring + org.springframework.web.servlet.mvc.Controller + interface. The DispatcherServlet + acts as the main application Front Controller + and is responsible for dispatching all requests to the appropriate + Controller indirectly through a URL + mapping handler. These Controllers are + responsible for the mechanics of interaction with the user and ultimately + delegate action to the Business/Persistence Layers. +

    + +
      +
    • + messageSource + is a singleton bean that defines a message source for this + ApplicationContext. Messages are + loaded from localized "messages_xx" + files in the classpath, such as + "/WEB-INF/classes/messages.properties" + or "/WEB-INF/classes/messages_de.properties". + getMessage() calls to this context + will use this source. Child contexts can have their own message sources, + which will inherit all messages from this source and are able to define new + messages and override ones defined in the primary message source. +
    • +
    • + InternalResourceViewResolver + is a singleton bean that defines the view mappings used by the dispatcher. + Specifically, logical view names returned by Controllers will be mapped to + physical paths using the configured 'prefix' and 'suffix' properties. For + example, a logical view name of "vets" will be mapped to "/WEB-INF/jsp/vets.jsp". +
    • +
    • + SimpleMappingExceptionResolver + is a singleton bean that defines how exceptions are propagated. Exceptions + encountered that are not specified are propagated to the servlet container. +
    • +
    • + <context:component-scan ... /> + is used to autodetect the controllers in the + org.springframework.samples.petclinic.web package, which + are POJOs labeled with the @Controller annotation. +
        +
      • + ClinicController is a singleton, annotation-driven + MultiActionController that is used by the dispatcher to handle + non-form based display tasks. A method is provided to handle each + type of request that is supported. +
      • +
      • + In addition, there are 6 singleton, annotation-driven Form controllers, + which are used to handle the various Search, Add and Edit form processing + tasks for the dispatcher. +
      • +
      +
    • +
    • + The form-based controllers within the PetClinic application provide + @RequestMapping annotations at the type level for path + mapping URLs and @RequestMapping at the method level for request type + mappings (e.g., GET and POST). In contrast, ClinicController + – which is not form-based – provides @RequestMapping only at + the method level for path mapping URLs. + DefaultAnnotationHandlerMapping is driven by these + annotations and is enabled by default with Java 5+. +
    • +
    + +

    Views

    +

    + The Controllers used by the + dispatcher handle the work flow of the application. The actual display + tasks are delegated by the Controllers + to implementations of the Spring View + interface. These View objects are + themselves beans that can render a particular type of view. The + handling Controller supplies the + View with a data model to render. + The data model is provided to the View + as a Map of objects. + Views are only responsible for + rendering a display of the data model and performing any display logic + that is particular to the type of View + being rendered. Spring provides support for rendering many different types of + views: JSP, XSLT, PDF, Velocity templates, Excel files, and others. By + using a View mapping strategy, + Spring supplies the developer with a great deal of flexibility in supporting + easily configurable view substitution. +

    +

    + ClinicController relies on + RequestToViewNameTranslator to automatically infer the + logical view name from the incoming request URL; whereas, all Form + controllers in the PetClinic application return logical view names as Strings. + These logical view names are then mapped to physical paths via the + configured InternalResourceViewResolver (see the + DispatcherServlet section above for further details). Logical view names that + are prepended with "redirect:" will be resolved to instances + of RedirectView, which simply redirects to another URL. + The other resolved Views will be instances of + JstlView, which provides some handy support for + internationalization & localization in JSP pages that use JSTL. +

    + +

    Messages

    +

    + The messages*.properties + files are loaded from the classpath to provide localized messages for + the supported languages. PetClinic supplies a localized + "welcome" message as well as localized form entry error + messages in the default (i.e., English) and German properties files. + See the "countries" sample application for a more detailed example of Spring's + support for internationalization. +

    + +

    Presentation Layer classes

    +
      +
    • + org.springframework.samples.petclinic.web.ClinicController + is an annotation-driven, POJO MultiActionController + that is used to handle simple display-oriented URLs. +
    • +
    • + org.springframework.samples.petclinic.web.FindOwnersForm + is an annotation-driven, POJO Form controller that is used to search for + Owners by last name. +
    • +
    • + org.springframework.samples.petclinic.web.AddOwnerForm + is an annotation-driven, POJO Form controller that is used to add a new Owner + to the system. +
    • +
    • + org.springframework.samples.petclinic.web.EditOwnerForm + is an annotation-driven, POJO Form controller that is used to edit an existing Owner. + A copy of the existing Owner is used for editing. +
    • +
    • + org.springframework.samples.petclinic.web.AddPetForm + is an annotation-driven, POJO Form controller that is used to add a new Pet + to an existing Owner. +
    • +
    • + org.springframework.samples.petclinic.web.EditPetForm + is an annotation-driven, POJO Form controller that is used to edit an existing Pet. + A copy of the existing Pet is used for editing. +
    • +
    • + org.springframework.samples.petclinic.web.AddVisitForm + is an annotation-driven, POJO Form controller that is used to add a new Visit + to an existing Pet. +
    • +
    + +

    Logical Views & Implemented Use Cases

    + +
      +
    • welcome is + the "home" screen. It provides links to display a list of all vets, + find an owner, or view documentation.
    • +
    • vets displays + all vets and their specialties.
    • +
    • findOwners + is used to find owners by last name.
    • +
    • findOwnersRedirect + redirects to findOwner.
    • +
    • selectOwner + allows user to select from a list of multiple owners with the same last + name.
    • +
    • owner displays + a owner's data and a list of the owner's pets and their data.
    • +
    • ownerRedirect + redirects to owner.
    • +
    • owner supports + AddOwnerForm + and EditOwnerForm
    • +
    • pet supports + AddPetForm + and web.EditPetForm
    • +
    • visit supports + AddVisitForm
    • +
    • dataAccessFailure + displays a stacktrace
    • +
    + +

    Java Server Pages

    + +
      +
    • index.jsp + redirects to the "welcome" page.
    • +
    • includes.jsp is + statically included in all + JSP's used in the application. It specifies the taglibs that are in use.
    • +
    • header.jsp and + footer.jsp + display info common to virtually all pages. Spring also supplies + support for the integration of Tiles + (included in Struts) but this is not used in PetClinic.
    • +
    • dataAccessFailure.jsp + is the error page configured via + SimpleMappingExceptionResolver, + which displays a stack trace and normally wouldn't be used in a production + version of an application. It can be seen in action by entering a URL of + "editOwner.do" or "editPet.do" with an invalid request parameter, for example: + /petclinic/owner.do?ownerId=-1. + The handlers for these URLs normally expect to see a respective "ownerId" or "petId" + request parameter corresponding to an Owner or Pet in the database. Thus, + these handlers will throw a DataAccessException when such + a request parameter is provided which references a non-existing entity.
    • +
    • uncaughtException.jsp + is the web.xml configured + "error-page". It displays a stack trace and normally wouldn't be used + in a production version of an application. It can be seen in action by + entering a URL of "editOwner.do" or "editPet.do" without a valid request + parameter, for example: + /petclinic/owner.do. + The handlers for these URLs normally expect to see a respective "ownerId" or "petId" + request parameter and throw a ServletException when such + a request parameter is not found.
    • +
    • welcome.jsp implements + welcome.
    • +
    • vets.jsp implements + vets.
    • +
    • findOwners.jsp implements + findOwners.
    • +
    • owners.jsp implements + selectOwner.
    • +
    • owner.jsp implements + owner.
    • +
    • ownerForm.jsp implements + ownerForm.
    • +
    • petForm.jsp implements + petForm.
    • +
    • visitForm.jsp implements + visitForm.
    • +
    + +

    + The following items should be noted regarding the web application + implementation design: +

    + +
      +
    1. all JSP's are stored under /WEB-INF/jsp except + for index.jsp which + is the configured "welcome-file"
    2. +
    3. The use of JSP technology in the application is not exposed to + the user, i.e., the end user never sees a URL ending in + ".jsp".
    4. +
    5. By convention, all URL's in the application ending in + ".do" are + handled by web application controllers. Static html pages ending in + ".html", such as + Javadoc, will be directly served to the end user.
    6. +
    7. The results of all form entries are handled using browser round + trip redirection to minimize possible end user confusion.
    8. +
    9. All pages are extremely simple JSP implementations that focus + only on providing the necessary functionality.
    10. +
    11. References to Entity objects + are passed around in the application by supplying the object's ID + as a request parameter.
    12. +
    + +

    Testing

    +
      +
    • org.springframework.samples.petclinic.OwnerTests + is a simple JUnit 4 based TestCase that supports Business Rule #1.
    • +
    • org.springframework.samples.petclinic.AbstractClinicTests + is a JUnit 4 based TestCase requiring a live database connection that is + used to confirm correct operation of the database access objects in the + various implementations of the Clinic interface. + "AbstractClinicTests-context.xml" declares a common + javax.sql.DataSource. Subclasses specify additional + context locations which declare a + org.springframework.transaction.PlatformTransactionManager + and a concrete implementation of Clinic. +

      + AbstractClinicTests extends + AbstractTransactionalJUnit4SpringContextTests, + one of the valuable testing support classes provided by the + Spring TestContext Framework found in the + org.springframework.test.context package. The + annotation-driven configuration used here represents best practice for + integration tests with Spring. Note, however, that + AbstractTransactionalJUnit4SpringContextTests serves only as a convenience + for extension. For example, if you do not wish for your test classes to be + tied to a Spring-specific class hierarchy, you may configure your tests with + annotations such as @ContextConfiguration, + @TestExecutionListeners, @Transactional, etc. +

      +

      + AbstractClinicTests and its subclasses benefit from the following services + provided by the Spring TestContext Framework: +

      +
        +
      • Spring IoC container caching which spares us + unnecessary set up time between test execution.
      • +
      • Dependency Injection of test fixture instances, + meaning that we don't need to perform application context lookups. See the + use of @Autowired on the clinic instance + variable, which uses autowiring by type. As an alternative, we + could annotate clinic with JSR 250's + @Resource to achieve dependency injection by name. + (see: @ContextConfiguration, + DependencyInjectionTestExecutionListener)
      • +
      • Transaction management, meaning each test method is + executed in its own transaction, which is automatically rolled back by + default. Thus, even if tests insert or otherwise change database state, there + is no need for a teardown or cleanup script. + (see: @TransactionConfiguration, + @Transactional, TransactionalTestExecutionListener)
      • +
      • Useful inherited protected fields, such as a + SimpleJdbcTemplate that can be used to verify + database state after test operations or to verify the results of + queries performed by application code. An + ApplicationContext is also inherited and can be + used for explicit bean lookup if necessary. + (see: AbstractJUnit4SpringContextTests, + AbstractTransactionalJUnit4SpringContextTests)
      • +
      +

      + The Spring TestContext Framework and related unit and + integration testing support classes are shipped in + spring-test.jar. +

      + +
    • +
    + +

    Downloads

    +
      +
    • Download and install the + Spring Framework + (the PetClinic sample application is included)
    • +
    • Download and install a Java + Software Developer Kit, version 1.5 or later
    • +
    • Download and install Apache Maven, + preferably version 2.0.10 or later
    • +
    • Download and install Apache Ant, + preferably version 1.7.1 or later
    • +
    • Download and install Apache Tomcat, + preferably version 6.0.20 or later
    • +
    • Download and install MySQL, + preferably version 5.1.x or later (optional)
    • +
    • Hypersonic SQL, and + Hibernate are provided with the + application.
    • +
    • PetClinic and Spring use the Apache + Commons Logging + and log4j + packages.
    • +
    + +

    Maven Setup

    +

    + Make sure that the Maven executable is in your command shell path. +

    + +

    MYSQL Setup (optional)

    +

    + Add the PetClinic database to a running MySQL server by following the + explicit instructions found in + db/mysql/petclinic_db_setup_mysql.txt. + PetClinic expects by default to be able to access the server via the + standard port 3306. To use a different port, it will be + necessary to change the PetClinic Database Setup. +

    + +

    PetClinic Database Setup

    +

    + To use a Java EE server supplied connection-pooled data source with + Tomcat, it will be necessary to use and possibly edit the appropriate + context definition file for the petclinic webapp. To use it, deploy a + copy of the appropriate context definition file in Tomcat's webapps + directory and restart the server. Consult the Tomcat log files if + something goes wrong when starting either Tomcat or the PetClinic + application. The context files are named + petclinic_tomcat_*.xml, + where * is either "hsqldb" or "mysql". + There is a context file supplied for each + database in its respective directory. There is also a context file + db/petclinic_tomcat_all.xml + that will provide a JNDI connection-pooled DataSource for all supported + databases. Should you use this file, you must of course make sure that all the + database servers are running when you restart Tomcat. +

    + +

    + + NOTES: +

    + +
      +
    1. Should you deploy one of the context files or define a context in + Tomcat's server.xml, + Tomcat will not automatically deploy the webapp from the + petclinic.war file. + The webapp will then need to be manually extracted to the target + directory.
    2. +
    3. The context files will also configure logging to supply a + separate log file for the petclinic context. This will separate the + container logging for petclinic from that of the other webapps. This + should not be confused with the application log file provided through + log4j.
    4. +
    5. An Ant script (db/build.xml) + has been provided that can be used to re-initialize either database. To + select or configure the data source and database used for the webapp and + for testing, you will need to edit the following files: +
        +
      • src/main/webapp/WEB-INF/applicationContext-*.xml: + for configuring the DataSource in the webapp
      • +
      • src/main/resources/jdbc.properties: + for configuring JDBC connection settings for both the webapp and testing
      • +
      • build.properties: + for running the "tests" target in Ant
      • +
      +
    6. +
    + +

    Building the PetClinic Application

    +

    + Open a command line shell and navigate to the directory containing + PetClinic. Make sure the database is running and execute + "mvn clean package". This will run clean and compile everything + and execute the tests, including integration tests against an in-memory + database. +

    + +

    Deploying the PetClinic Application

    +

    + Deploy the web application to the server in the usual way (see + notes regarding database setup). If you need + instructions for web application deployment, see the Tomcat + documentation for details. The Web Application aRchive file is + org.springframework.samples.petclinic.war + and can be found in the + target/artifacts directory. +

    + +

    Using the PetClinic Application

    +

    + Make sure the PetClinic web application is running and browse to + http://localhost:8080/org.springframework.samples.petclinic/. +

    + + + + + + + +
    + + + \ No newline at end of file diff --git a/src/main/webapp/images/banner-graphic.png b/src/main/webapp/images/banner-graphic.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d01d5885266efbf4dc99431576a13dee5725e4 GIT binary patch literal 13773 zcmb_@1ykN!v~{rZ;BLiTiWaB1yF0}xt_2D$?(XjH?(XjHR$Pj^bD#H{`R*^cnMqEP z$t36Oy|eZ@YbPO!@)Ah!pWy)jK$4OaRR#b^E%3e!2ok&<$A>8aH*ofnT8;pKfbri7 z0i>qm0sy>%g@}lvqPd-uouj#(J&BZv2#NhqJ5vkm9{}LGnxSH*s&b6Y_po^@EEDV< zFJq^S1tL)v4)ey0p`s&&LzNCD%~`=x>Om6|gT^1u4u*=1^bW^TqDKscUxwWy&5iWS z3l1H9*>=mbT5Nwfn0Rkk;y*0E$*7xx?FJzxO0p`kdn1+z6QTX}8|ok2-eVN>fv2zs zP(gJjq>gXo5Wu4+FYgz!ZrDx$!gUS-1a!-#bu$wLeW08Or+kO-_J`p7+65FD00U~TgE_!E<1xhz0?>&k#e&F=0Z1@@1d9UZ z-+=Nd^-wWDlNrD?mFedOmKgwMDGgIept=d@oy8`|x z0H*l02Jh9EO4LI-u%%LJd0QyB#e8%?3=Xgw8jM6VlTtWeFgXk%4O0afdw-|kef42O z`Fk@C0NF8E;L+Z^xlSTiPEK+}HX`dYoOFHqATu)Beczudvlj$_Z70u}cY3C}&)(lY zdE30_Ql3Mb>mg)2KZKdqq6jts*~hCIH}?P8Ml2_~Wo2c5Z*N(;Us%U*RKw%ltXIEV zjzO1uT2OauY_}C{Zd9Pnsk`E zO6U%eqN(9GUkk`Wgkxz3C}%%RcDCqWp!m1gfoe;B2)7u9VqIgXdl_m}O{eai2LQNk zv+J3s0YQ12`)yCTd|U{;Nn}$3-lkHq4gjDhO2Mc)S|>0B0szr$AG&HG{M#N}`tDBz zJuvG%2(Jbl{=yXfy~3!%@Fv~_KMiQheT8WPC#nhQ44CEx3E8@p%md@>kr{i{nvwbJ zQJxJ!nLRY^K5)=N!ypVp($!!HqfkxqNDxj+z$0moBs6*$1<6P-rV^P<47((Ya;Pea znk3;h-%m*Hpzq?XG2e!PufDH=?Gh~UKDA1G^N0;1EybLl{l#+;rcIn!Qlqf5)24sc zf94D4$T^%YGe=pC;ujfW?mohWW$m|SW*qDjuHmAGi!&apAuC5L8~j|YUJlh3a%VhM z;{uKDBi0Sa0qr78Vn`$;sVS=|zbsiyLO{WWwhG4y2j#ESOHCG6EK^U_iuTlxYxI>R zNK=xYd=Whgg9+6wSfrnm0zE|JD|JgWq*P75>MZ)K_^hom`7wP-8k^*2^0<*z6RTQS z?s$5VFT(+Q8GC(utb6!-q}Mv|8AgH*`Hw0)G|Hov(s=u*`)vE4ek6YtQp-zK-YCvd zMPrZB7Ou!?RIXAAD#l=QPUW8P!;MuV4z3yW)p=Ym_6EL(^-7lt>a%FM~~FZnP9CB;rnldh4@9V=!O zK0!KxDgmF4NwuW3uynH&LG4CuOf{-RPsO8BT#Z#_w*+oJu}rNrL-C&qzKU7Nx8k5u zvtm0{fqYM`w~$X-eX@NDBKb<$HTt{lgCq#Xcy+Gyq*h2}fzCec{Zus*EAGGO+LGT0 z+rs!tOLDkHSfyDt>XdKdO$A_glN}z@o#f#TX^N6=JVQ4zFKBmY@eA2xTUdU4w<=9c zO4KZqEK@3z_}9Tvc~+EB*df-Y_2PppG$c*^om#>yY7!>nP-R7BqX@nTTaJ(Cu9C6T zssKNyP1L2!w&*-Lvs2GIQ`W9%^LNMLGl2)wo9dg*bJ3jyqUNVMM2b&qh?BUy1MCiV zyo5|cYgbAlx_yEo1%?TRN!$K0Ei=4%3*r&tDB%`^-*+i?Z3b-y^Qb;iky6RXoyeW1 zD$BJL(iVP`{U$p!F+Pzyv6#Z1#>cYs^)T%)Z7FT5$w1pxo4&EQvH6Eo?Vfg_)_G&Q zZGbknR)MCPwr-txMMeeXVp~O95n54;e4Kn)=Av0&^;P3YV@VTU_5SjwwaP}DMh`O7mNlj-LI9s{?D$4q9LQ>atR zthGi87gUW5@tANEslOS!C@gXzGI9@{ETV%gB!ygd(uvK4!YZaX74i6>e718 zir1>nInFK4gVwXg*|KOewOAde`-VmSD(%k*AY>&lTWytlDu^ifm^B=dGZ{0*XjCj! zHx;;)J{Vr$@ZalP`x~Zi<&e`2G+%%@pXP2oTuqEO}{$cX*=VJya@}`6^ zg9`Bx^3j2OdHmx}+7&6lv-ab@cI8YcJiA2*ODM{>!gs%?g4BHYG`fQH;V^kJX3_#V zK+*GPaT?a}z%Z=O6OlR~C_p1nAkscq^YaW#61&UHx`^YJ=(A{|=w_N3ivo8QgETuG ze<`CS?=H(FdY(i<*qgh2Inyt)KF-j4(YIq83j$>{7zi~FI?64%Yk3`hufgwP!F&l+|5VP~9NI`{v!GCR zrjb2Bd$Bd9 zqzRg}Hor!Zmb@&Ba;)~1XS}?Z&jaFInHM{8Vr{nZD-E$-P-TjP8Zg6+8^Hd zM>^NkAk^d*Oc#EwyS~XZ2UOTlqHZ9PuwgGeRay;neF? z@idjx7ab#=R)ul?nZ=XMKd%yN#3<=(yjs7dZ&XJtR*!w>;>@n6!ZQ*wJUkhn)(zHj z8{H0#C$}t7>@HeSowjGiKEe*awSSxZe%BBL8CgulcCMW4SDXz=Lz2NPn`yXD_ z+FQRj#&D~sN(`pa35%eo8UMcx*Q!k#;c7tM$HQ_Y>qbkR#3UR>M!tEU-m zuBrhOPT1AGF!_@e?DSPMOG`uMPvVFVk(Pimcn2xy&23C_yvSY><;rMZ0mg z)Mi_dGyisL*LPzL3pQdym50Vtc@%OK|Cky^wVb&S^LaELgWAYb$Sx8XF0&Y~>@d*X zNuk{;PcKtp)eX^SnP}E<171&mx2fmRn(v)x0)@W0`FJA4ru5a(+MlT-ehwhY`3tYsE zTu-n!Q3-~G0#D@pDU^kd>WoD1qgHxIOzO~k#C_dUaGO|;e*X?VEg#NBxe1Wv>^MgF zsy~S2|Cb5WM~E3hCyHFd&;6`9?-99XSN{17(EJ;_?zL`60$ zu1v32930_O$(S1QTj}L^pRBg~gQ0@jyC{o$ z`Wwyquf&q=&dZu;^SsjK1gu)vg)$A7QKO&=!en~SfJi0WuQr?y@>tah}drfJ^AnjAYTXFTte*D^ODm8 z0fTPHBu0@Q-bl|%ehdc{(i&dn!n94?=MJ0f93^y9RCG2f2PHOJLCKFVABVN;Z%}y0 zTSy5Lp&o65JI4g!RMb8(0 z(BEp%hNygOJ)lH1Ykik}eIWAWGh0Px-MSg_5Gb|bBI@PwZ@9cNgZE30<&Qoxzl^j$ z^}5LUCrv!qx>Y)UL)G;SE84*XT6ca+p;RHxgZL&RBgV61ruAbnvNqVP>+aWNJ*B6u z``)ds$WTk@317_ar80UE!^GO2<=HodES?WIfS_cBm3f&-zu|6s>A);O(u@D9Olxy7 z^(iy!ynX4%!wgM%z?LjMg;4Eum1(cNk3IcPE_od@bhOd9f-lUIvE&vnD+V%8Z zKeG91wp~u<#=zn|aO?doM2UYW497-Gz4{8rj*mc;dmyZ_y!D?&1kcFYr{{QH4{0Kx zT<5-hX8!iwj7cNoqd#&a((xyDD~-o2!Ev2%z$ty*pQ6$@rWv5kBxrIV(h$W`#D>#^KNbNbWeh; zn%wb~(>SIr?q&;tU;Q;#K8=xqR^Y0rFwznIgrbY4N4ZFDiBc|RQ9CgGi2bILRgb+P zW9~K!?Soh60kwN6Vi?012wmmY1t>ABy2hJux%XNSIC#ZOuL z2GL$bxTjtpmt$?n?@3`o;b9>tgZKrLF@DS>Dw?X*+e1<9J7?L@5*FTEe*R4# zeiNI}Q?H@CQ}xmmg9>`le~u-{^%OUc;9~%$SJrwxJ2>$`aL8gMc_%JDg9mA|#%PeD z&}5K3_b7eqM03mVVO(58{JEybH$b=b{g0QMoQA|k zg@=RD#pVU|Rx5ME(Q?}i03MdMlecYvf#?0`!99*1*#%CA;bH|8N5wD_`XCFxbPJjH>p7X(tg7}0!YB{K+PknluS`2c z83E|ua=h0g9c7-5ZiLOwn)AhRiwtg?1#Q6>z5CituUfxHE8i%0CodAS9##5lnF;C< zoZK*NL&J&u`)4Y`@jBDGag4eIk81mg^&i!2U~Im=?nZ`k-k%m1uP&Wa5@^?2-!x8C zeRC-<1H7r1E|yi>c}8&rHkrVkay3=WU|423SQ z#~)tsF2A#)i(sVMh8-i5UxR4y_@ewWL-fdq`!?l{5R~lSxFrapoLp9{;sb!o`9MMi zn`P3cfrrsE+`Kn}Q97A1I+=#le2*?pKrm=Vko%!HkG;lZ`zJHxui_z!xc2J{8Sez>%l)@){zs)81F3+rTP1( zzOycju6)mTbuBvQ@ocO@d@nT(v|hvvme811-u|sB_mF4a)==N+@rT!|KC@yB@GJYY z3%f=^UZ6zHFtMem-Puv^-o~4*x#T{dg=@NA9Ov|^p^;T5H*cJ3<>;0H-SwnJ={zB! z@9q|nlgGhG^T+2dHZdjN<>oehc+QtbF6`p9vdNb8JXM3sP55VT z4wU{M`{gEuEDf$SPg@qJ^w(GVsWtZ`jxS&MzA^0*yU{`N#jP}%jei+WWO_Pu3xbvP z>%2s>_hzF}k^Eb8QBnC`d;UEFw$5|QFKmvATIS+*f!cCv;X9E`pUX!orCC?&@}kjg z$4Y)lYdJSw5K8(ymHDE;ua8Y#SUC?<@!}e{nQOMN(4hX}1^QY@F6k%@{#1+V4m%9;@yyOfejN8j3j__vYXp)srz@XX_9&7_5(kBhjqS3(OmGuMtOhO^WO4Lgwh zJnr?h5rinuNpZrwb0%p{r|Ml=$@f}ec5{SlT|eEt>@P>zN0znLl*s@5J)#|}dQ)+C zlc}@M+_mXc?F0wGt3AO*|ATi^GyUeI;?7@EtsA(0l?H6|I-nT z?)!9LF2vkln>Z@S?vlKQBu0+?@eF=ew^S;|#-g^5(E#id1WrDsb)%!?QUw@ql_5)7 z5{+{0V&y#}mFBrX{VrNzC>`14rg({7!#G z!G1_tIR>&92In(utC3f(aV8Hc8mC6(zh9ilWW=}ITj-^8sQ4ju zKPNUS7&79D3Z0zq3BJAFok%1?b=Qcn<5=NS%PlbIDP>12U8;AUXr2wM4z|Fg)E$~? z20iY@=T}Z*{p zu}#-s)EV+G%XofOt}UxHyCSp4452JZcG^Fc!r-wMP0u0|bETxmR)aefkyK?mp5CkT z1oaZ->{6S4qWC0yIfV0!T=inhpN|_yb_-^|JrMDj+~iOSfm zyG5PH^%v@`5DHd&ziwQZBz%q9sY?2gg22QcQ<@OA^YX2aNrpj>h;oWvH?@iOC}zQZ ztbj=()LO7%TBl>i8T0tW!p8yvCo^MP7WwCc7uJH?D>0(S$!&dN;Qje|C)O97=IZK} z8jpih3lv+LljD=F%?-CF;juf$L%xoeitE$0qC+fG4)#Vg=+x$Auk#9AW-Zen+&4M% zN~IfKv{NbH_^O!W$XMm^Z>IRLO3fEWgA&;|>swT**ll(Ssl$#B!LMzmfa8E?Ip-LJ z!3ZA=)LWv$J)vBBa<%0dI=ol~N1^-HjCq5l*hq$RQPu0&6miw2tHN`*)Kc5?d8gg` z67{5h>vB8~?Ner~m|Vn}jYfopii&F)E>=P4EM;k~>IiMfS%q%PZ`Qb2jEA>36`;Av zWMN-&)vY?ycf!}!(QU1MSTl(MWdU(|4w{e}Pg(&)^ zsdRVyj~Qyu$4lxLfg+aK#l*?oAWPuyOc8Ok^jKQf(~^MKcjwdfd<$CG2jT@Pb91#r zY!j*?in9%8R6xB_E0$BBuHor3;H3MH&;9S-n^oev=TLbcto+yT0Cril>1-<@Ssf*H ztyNpLX#*;o)|&{L76hlD{oo8t3D(vKw$I(=x4cR5O49qIrBP(@0W~wL-7a`7lo#^@ zUqyzv!DQ=oUu8Ic^qG?Rtv)V^vKQ0jqcCp z8m?*{s`Or+7XrWt!rc8drvdzZO$q!RP)AKgO#*oU5hfFi1!#Zf0kVtQ^b6D>1WzzG z_HQPj3Wb=FIPh2B!ef5bugWbaWo2bFk(Akwq^H!)L6B%yKm&0W)k8u@k!9k5x!sv+ zNdh=C%v&z_7Bn$wTG|;WGqZHAEf;0+m$cP2tu5o@RHYQl$Y!KlH@p8)mlsztPAi#$ z1d>h=k6Ec^bSqu%Ri=Wx$5QzS(JI?IvM$rx$Zv65RV7MFg7Q@Vaa;oi&9kFAzm3i8 zbR4MxC;fjJyzG?RltP3BotjqJRJHb3=~61rfWZl;$}rwHH;8T?6V|&l4T0KMVVm7! zmAk;P3P#wo&P5pkf@Lpyt4O_C4{rK+c^UdqptHgxlW7OkRwHl`Qra#lt&-X(U zxW!BGzsdT?eBrhz)z6Xab70*fhY-n=ryJM9dm=>i{kK~cg2bQ9%RnxNRq%Y!bP>m! zi-2%;cq0o1&U*~3rV4pk5_c~W{afz=eSOk0=M2H2%Fg(1D5u|AEi3fv0?#}Svz>>z z{VbbmJ|Y9SEmWK~bUmo%44%W;0CQXOtc192UNWIz8o|Gqx#-pel*AI4IF|U-3UVnr z(NYmfoX55@CoX&W1U#1o1R9ujd1!X~51o$ownBv*N?@#vR8$!Bo<9}Sz;8o3N){|Lo50p(t(%kcNc8cPF;yRINc<-%xP-VdH#fJN+u*>my0XIh zEwwG==#Q&P)zf&%^GXYza`=p{Rtuh1%b&gi^^-l@E^-yZg3RRD+oL&@BQyE?ySAg# z-3oX0N+RF@+XT{ksC_zwR!ZUZa=Wo?5DX`b^Bm%0B@~Y%oO4v>^GYYI`no(ix>Z^G zyp{EQYC4WZo(Cp2zT#=wDSVuLBIGnGNB*z)Zu1_Kh0(#L28;9Rj}0~a`ejnBq$))3 zMu!KS59iD&Zi!fx8xL-MMRpH-%C%<;E{y@k)pPi~RUPe=3VHIgMF-Lz4DFpc&Qo2L8*zmN!(Gllr6HLELIMa-9r_jA08Ob|b$ARolKw!9z#5kN{ldMrGQ5ZPyil3uAv(cSB6oKs&g&wdl zKG&~XF1Yyn#Hx{Rf_I#uwdwBqBz&`vFfrL=0SPF&tagrVZ9XpR9fmsk1E}+xt{(a# z0p zr;fczuBKa7EmM^d)&*xQB1bOPyC<-oan3T>?DT$88>*btZBfYIm2b{U=tKpYA3(Y= zO8#sh0a`VyskPj~mG#9P#Vtwq^1O#-cAB4sdnyLYvY4>w9rG4*jzw!2hRWy?e~lKN z6uuuQx`PE&TSm{BrkVMo16z+r_TLrm)I~?=5()XAzi%h#qmVxv4=_c#atIe^?{d`D z&VKBM?8qr#3p5-4uFL5ts4<>L!37}D@X6F85oxQnd?w&|`_aBgxJH78`B|Yb<|43% z&;%~bpBToTt{x-9yN2_Du?mJUVfisj?L%G&i_0obn(e2H9JK=UXfock8wZhXDpCAQCAgj z8lQGNcQjN<1?3TPk1D*DlvQb+qa8ckl{kWJmi&~d3)>iULjN@R09T3s!=~?wyvRj{ zPuXep7ANynkiXmI{8p^BpVshe4>2r%VfgyjPt43sr*f&NuumXB+@Az>1uD^E9ps>Q zaiw&UFiSi!rCT{e!P{Usq*A*NmW{#gwere-SR@C}&KygQ*$6!_0lKpL4vqKLFgYi@ zC^osGqTQwhwZvIci@m%l#m>=>ce55T;#;WpM@by#k zhZnC}0Zlwz_mhp$6wSHL9~DR=1qmn-;&-0=GM*gYMy4NhvDx4sK;ek*4xYF+fD+OXZMoZG$0GNs7>kh6ao!Z6Alk>eI)*e3KGaqi$O7jDHu25>Elg{FBdgweot2jFn#V|7yYLf z4om5_%pAe~addie3uOQejfTBv()z>XobrIkK~(>!w^wHfN4n1J5p*KG<|=arCn;^M zP6FetEqX!{lAOrPr%rfi?05eUDKW=$EE8uuqk>*Mxr1YTe~IsK4FnN;{}Lt~aow#iNb z!6hCMgy&XupVoHVICHXmL?f3=CDucmZ|U^VWEfsxV~ctp&F6#RD4N*ayV;v;D@V)6 zXD316H<7iTk|t6|;HdbBd!c%=-eoMouejxq?Kz6MN! zXZOac(kkzeoSsyCwM*pXQ?U!eApvU_SdceO44G6KB%r=IyJ$n)pfy4}7i;zt#N7zp zAe@2erK9k{{_!szHHlZqE$x)NnCtD^|T2djx>P zP_l>HO;EqhHv0lXV|9`XULoF+mN3;)*xk~XN{fuA=N>c;Z9@m33d<(`+a4eihlc85 z)5U-g5;Z{KqoP7lrr{P`-v2TE4aBFg<}VW3H?KJL%KTXhD#i5Vrei?hg7G^N02aCO z(g&7Cgxf^B$zVmiiz6$=y#Waqy`qknsy{u^B~HTz>9 z7Q%a%%Le@Tb$=RXL|tKtKNu|HAT;44uU%v6RqI8co=r3qoV-O@*;IM~0^l|!B9|oj zQwDWB5vMd31_mKuF_D0m1&vr1%a^_d4fOb=NzltWR`pdzA#m+lrx zH)T_Jc52vW;H2Q1AiSNp>I#~s)+rq(_nQIKf>3a-nH8m$Zs>)^2#UhoC=3{YHb$i_ zV7c#x)x%XS%R9qwK4T2#4Kx=8xu%}Q0X?%-66%Mz4OARdLfVudcMSzF0!QwB9ZrMr zO)0@L6a|IZe`N_s4Ioga?ZNKGr+`{V-^ zZNEx}+yQ3~GXc{EO!~npWPIc_HY4_E4hRw*7NP`1!%_sfrP%L_6i+7_3=$01=c`^Q zrAbg`Fi7PBVS5_%a}kmH^Y3#D`kLpFfWHsP+sZS_+u7NrLZA8laEI)a8YJ8KP`esf z?s3-lg#?5=JR(y!hqflF6zzSI^Nx$5gldu3w5FBY=J*SPwlyx63qGkTB4kl|3?jRz z%ecR8TZjyjEX>|0alE%5Q=B$FeIj&YgZOhNbcpyzjSk?HMvOe?W=bKz` zjpW)ftkI4Eh9-f2H>NadbGgm9A1_aMQ26k!nzWj>UkHF9f%yb;H7te}Mgjn+{?IWG zVF9BwAq3E*bw5mc!!+}u(ILuvv%4--K?4I6XiAu|r4H(aVjtS1iT*I`vCOY@20rvzRml-x)(E9wYFIVu` zs;^x_pN3~W|C=-mc0mKtFKSWkFI@7zu_{JdNAZUYnLeEEk1W`mCPu9_%3=5`wo4i#9Hh;HSfr1qTNUqSk6L zM_7`LBOwLnW*c-H8-+UQ7YlEimPLOPD-1Tv!N-9Klf)#D%RqyOBSpsa#)Njz!~e{J z&8*H93?{_XlDCi&*TFQ`WM~%Xv;eC8Gu=#=I!l5uWe_&$vL!xzrayF8uB6owskn47 zO#{`RKcwBb#zjp1n~Ug(Ag*3=z@M4W6C;EG9R`^h5-}Oz_yP#-aVbd={Ka7DIc+pG z`V332>Z=^!8pC|OAxd8#Hv;!bmN^3=os03SGWuVTy*C#mh=xRr?C0`923?`i zn+gpf!>I}tRUydZU7Xa@d>JLt6P)6HtE?uU&B*We#e6gkj599jZ`*BtFB)9xIW|Z`#Oi{vuHMs#G z{D?tL6g3`Rk>+R#9XfJ3aAPWXSCqmPC7Fblp5E?D1Dtw*uoR~~F`h(;V#xxFp9oc; z6jfnxEFC;4a{dtR)nyzp)u%3Ii}!W6_^8VD_p~lgYE}9@<_MeBZIU!TvPCa-?1O&lzJ~+=S z3aUZ8^SUVDy)oD_uPPHB;a(4E$H?@vNmtH^?{y->&Yyypw@^rg@U4-|D<>$54tjx} zp|Uwh_^qdG!6n}_QaITU?M8q$sL&FB@KX_{DBf}DU{OZ2L{VxB5+fY={i2L(oFuBX z6)+b%12i~Y7c`;Lhmx5R!lfjW$@o$6+7n`&+SrB~-r%&3uk3xr5SzYHT_2TRkfVKD zSdtEaS0d30e9n4#-k5|R8JSM zQ9EPy`4xEY<>xm}ZIBz$|1oKApW>%1&N_7waxUHk!2aqbO-s0SF;XJg)S?NH*FCg0 zq9-U=tayE&`{y;{01pWMbai*$)+Z)@>q{9+=&4hra=~uZnd z1;=IH%}WI4+xpZfe!`F1^4;tKkt#XqTiIFdp;9kw1ytc0+gS*8A|xRTP304OoSVgl zgd7Kk860tjsv}$t;RIT|_v$E)Ve{WEi+oUfC^y#ceV_nH5TX3PVt-wNzn2B1#NKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0002BNkl%XvI?MxGcjNR-+zB#n0C;Q;qm+PDB_F{ z-k$#d`tuzO#k;TfFfcQ*GPr7%GFT}kK@@MkRQLbXgQX1kfQE!KLy$oac4wf28!z@U z9J@D3J00009a7bBm000XU z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z007NFNklw&kJWq2opp zw-F#fI!OKmNZd##Kn8RtjUed+Xawk_lelAd$L*FK%PqGp*|bGb6GckmOjfbTnuj}o z(;43P-FvSgKTeUFC{mmx#i|Wl;Cvr&?zwlr&slrzwVvl$=U;wf2 zQWtXXCFxv-JL;@tr z3ral#1AXhEZrWbF@QXkG%*TH6{>er4g$R>IBmzSKK=9aw*u`nw+`9d0$J_6F>amA! z99x~-m2)qxO{KKz?rx^73IZVEa{p*~`O(GE!;8Jc+0jG&^{07pcK(Np)TpNcTFoeZ%oLvG8oVqyM=YB7A`xrZl z`5Ro$zWO~8`_f1M{;&SCzjgQa0}aP1F3|y;5g8H59T7voz{H4?On2@+A9#Gv6AwRf z{RmJ)=u}3h2td=g-EPM!o>H$Wt~D~{9QO8RN0+Z3Jodx$cl=md9K8k8KNK|${K_9y z+1!2k;?}d9JI`(Jzo2Cu0)Z9>@8^49#xY83Am^&Hu`x86Cfhuw6VZ z+l$rRmrh^#)cW?9rqvy=R;I0+rQGMP2g1^vIT>_S)I$sytw~cQ(P_H|M@dvtcln4KpvrLe#&f^&)1UgtkKes@;&@07;6i-}fv}A*O|aRz zG%y5a=mO?sX5Id!M{hj!!W&=w!k1nj#_`dcm-pwd*7&vgxr3%N)fLe#ZF?aLT z#_L$FP<#uce<)(}xIWpOyng!&Kfk*5Y+2n^EumW=1>l*3HbE9jvw5rAW~$?wh`lxd zaz_zGG6Y8oE}|%{o#Xb*Pv4+>FNQRyZchDST3#h)2Qzb@&R=`(SAO-QAHI8UMYxFM zjuvuG6w)-}W`ku!H3qb%3^5UrS5qsSi`l{P+aG)S*1eZrxqbU=HN5lj>sOBV1B=%p zIuXU3Vg!^{Qiyv;$3^lBuiQF(Xph3|EsXvviDn0QGcXSq_wRn`V|QQt)$#21cz!1k zQA|WL2XZH30zg0>r>a09b*)ubj}cmJZiq~7MgZW>h$`CZhC(31ri!)lxS}xOXrPO&<2Lr3tTGK)ZV5U;l8OgwbV{iu*aT5o0aH*r#?R>FU%J}@tckVnG0%a4Q zYK@6QRxiyqL#Sf8HzRGzXn7VIRI85Ck}Co0>Osp3?-yQMhj`=gp{Wj=^~LSi&m7>U zSRbP~nAyd)z5LqQxUHA2UwY{Ar(b_?@qhaF|AU|U$3H%eRYU-JZ*T9>w>|!YKlH=@ z#$WnNKk)q@cniV*e}iTR$KBlz;NDB0dEsL}dH4B`Y2D^-h7`;U%-t0TF(fz9aRef9 zN7ooSBO;>KYOO_U5m6wF#M`2Yb9X{hyEuO^jTZ)Ra(eOl z-L*j^@Tru{vxK3n1}!aBfjR+sV2+U%`-}NuuWf8)FwS)xF!dl)Ill`404mcaaL8gH zxnVrN+uHD;pU;|NsdYO{>#?=gu08hdYj1n!fBED8&42d)`cHKlx>-U*1ip7~cyMy} znJ;|yW54`MfBkR#_y5hm_E(ql{w*B;fk*RKdLqL#z3|b0_{t~#$?D`aVh+q=Kwz~Q zxSFZC5n_yqD44rUle!@ykYq?1sllxN_gCWUywm`h7~9ylW*KuwV%r>U0a7MYQ$4Hrz2 z`wq;s6$dn6Rg#UjhU;xn!cvCyb}ME_SFXJ0U;EcYcj}UV7ohzwzJu8&5p(*jrHkgNkN%2Lwb1IKThKmwxI0`^qQ(SsgC`gPNE* zIiRzsQ3z%(wP~A(L(V;?epk6|rb*4T)-tI@cL7%nJWfLh2_Tg+s5C?lu`_Y?%9_oA zi6f)Pq*BcNe6=}S>CjjeOx3{Egvy#HPN@qy)M6{;;CP6+O!f5TTWQ`O?H^n^K!Cvj z&6OhSG}dv`=RhGis6$Yzni9kyCT(gSyfzo-)aR#v@JF9`>ia+XtDpJE&;0Zv;w*(l zpAYvIDJOI@^HMbr<-zS&{`0^6x1N9Dh5zZ_{GWZ```-5!ntyN6>|aS9@N3^+-sD0e zI)DM(dFcyZ{Mo;A|H~gQwEz*A0iZ~+aiW;rkyH`M9UNm7Yi)}(a$rOz1tXI>PSb$M z=!on9QCcCiI*CdvZHh56b5lbKrec!{v&e*q(i+EPo*$fCK-+SId^LIVYeg(R?Ykn9201yBG7{Cs=WWq#C<_2!uq_7o40yQKs+r?`@NJ=(3L(G@kqk|1 zK?Fn~qS<_Y^(q6N-#;BUW2p^8^vGR@q^fxyILDwmjO}b{rPwm_Ls2ue2tA{(M!abA zzUw#zPf-{YF{TI{#N5nUsjAglGi@RGWAAw4(Rcp<5dwIZBNH-XKcB_ir`&ONbXCWg zgodF^C5RH^>1zDgM}O{r_rKNu^?&g1f8cwcehbatt-$Pn4meJATA#}H#LcaabsDWr zBCXrIHf~O2b6>}E8BRsouwGr9yuLoacX56K$dq#_BRCj3z ziMlr1PLr4-X<}}m0PXR2KJoMq|C#0CWdI=N)b&KMi)k^NEoSrCY#w4nlO|1SBcwIr zb{IONOZ)xlcKp~c{OtebKm0%Z@Bh#L(PIxk^oO&j@?AzVVsjYI*W3HA>h}KX^-rk` zF?MZOmo`c*j0_a&cwu$prVe4d9X9LJQYJuj3;>1{+#R*W!~kf3;tZgO0YN!ZYi0%< zgM*ebMq<#Cs27zoPRLmm9b;|at+<5{le-|G)|E&>%qc~asx~4=g}BSkkt$F?03r%q zH=nnI=5bq8T|^ro=YWI`4rCEZwi0YwQtD$^kNDDwjShziuV0CA&ddFI454bge>QH; znot_cWZ-$mz!p2cdE>G7|L~uF_^BTuA^?bi4)*q9Od)a#0YtnO3XH_)6-*-&0)Yd@ z$gRyIX{L{S_(T8q|K$JnH~-y#_tMecTe0~&bJKG`12BbYbF#hv`sVKQ?d+wxy|+Gn ztqf5uJ^5ILZ$}5ub%n6!S=Zv?&ZV%*ez#y*2mlr z+YyG4z?E%JCwqnuUs!9w!u`@Cg*IEIIIJjAB zrdFAdkR3?W#`Q%AGmNn`RU4Q?Nb}O_RGKKJh)t@fx>#Unb?e#)^Eg%_4}^#e2&P+= z%7Lld6El;76w$$erD-)V#F)}@nVN35V{2wjlo6srtCPeS2nam}k4Ov_Qa?4Vn|0UG zG9IwCwmt`$e7Qetw&SQGKH6A-7-P4H`^S3^zwNQNf8U=zy8iHvxV>wC9_}yaiv?mu zL;{zoGGITShY;#C#ej1PE^R$+!7QYts`D9+_1$Qk^3@E;*3P8 z>!ntAjVU=&Eh8bOG*fM6O{AHWX`0MA&Gv`wh~f@7wwkl&J~L!FKbLBag$dLPV={BC z4P3y?ftg(c0RV>pft(YDq_tv795VtKI046QDYb1^=i=ZV0!U=fiB(mqlu<{hiI_NH zjH#RZFfz2rVL!CBY!2po9PQriGZE_cwBPsb(1yu9gvDNWbvbu5?$UB^|M92)#G~)| z{#}mo)lPm2j2wsr5D}R|0>D-#DWIx|=&A(Jg$Q#J)9pB7(|JyJZ@>B<{~!OutJkjn z(I5VSw_@|R7@Iexy#BdgzV(HlDJL(2tOx*NvNCzdQbfwOnVQjdn8d8>JC2s-2U?5T zn7TPIwqaD2m?J=yG5`{W9*I=cY*MLU1^{9X6w5RqS?-b>IOOei4c-igkmjk&o6T6N zEan|iH;q%yNe$2m6jUlRAppk^a~EQEYk-DCi0o#L(UAd6Wi%CL)+VNwVqDJ6z*`}A zu%eSgplz68S{^12(u#Z9)rA^w&P9j3`-a&%L(gv@LvQcLQ(oO*DJF?P$ngUhtpY}VT$h z$sv^@hPf$Vk$^Kc0P0E|#v}-Q($!jRYVJZIGLOULMWCN`I*!9s+*%GnfgBY%5OYi^#+16H=mg#<5P(b5rZvWn zW0!KKm=Pvxqo^W43_MHG<~|^L6GU^vh8|PUT0;s&`SbT%4fDjXnk0v?JW8|q%vE*V zgs|6V7T{sfmtVWL#{)_ME%;^?{x_}K1Wg@b8m7b?0wE!&SRKGZjI-2bB66TUgdEd@ z2d9-;Lol^j3LpOG|MbyEZvIdH=KuWi<)gP^^EX%qFcx`m=hfR^`n5Y>`naxcXEyg@ zZF1EZcI-B6A^;Oo*Ho+(aaLdhhnO6E8ZIcYn+u>AG1IK;Vhl)R)$=D^j8llr9MF_Q9;1HQYz!1R!(Ss4GT5A(CVh*dZTN(GxOV<4i%fl}A z&}?$2s;1+)31bdg^>nOjDji$IvVL$E-toTQlDaJyi_|Y%F3QxT_Xuun8tVXHdA67> z$pMiN%+!F%_m(qrv#qz%IIvCaAN~Cwf9T5Pzy3e?clP)8931^OYInZL7T9+wx_?L0 z`tZ$uvI3N*!|MF})^q2teReo~-L)Rh1ZJ0Y8r&9UJJtl7fs~0nXd4mHodlw2QY*CBgpK5e%Eh=f`j zARz|;=Zy+H3uN3kOA1$oY9ex+*>h2 zK%#(M3glR$N~z*jrGZN~pH*W`v!ou%n0lP|9kOpHZMBJEX;KL7+31Z`_D%l1eL zDbjD>?n{>rj~{yI?8SQ=Sk)?`D-osKceA~NZr&r3h%_}ba}n2;0(3dHmaE(TVt#gZ z_V@mazw_wBSN_DG`^(*O57BXVRsSZT`CWkWR~&Hgn|i}H_%epy{ny6_F9;0lE?QRdn38m`q!9r>Ut4fmOr+IU}QdVP1(N%_F zY~!{|*3Y`xe4i+&sX<245YgSVO#mnk6mu|hM5cgfCMF`epN*TfRwWLtPRt?Z4iJ$! z#^}g~fr6zJI5HwKNbEWcfkRN!kh+*N5~Ep&9U;T+Hf9J&Y9dWRgabuEGDbp=pypad zffzyD1BN0{n;_*ykC7#J00CF);dCpGnNli^jpKl-tum;CtLwpR?~%8^^Z22+{q}v| z-`l_W@Ds0p{$rwTwHfyIW`|cU&u5)(*KUePPApoi6?aD@B#K0PeMWaT+uGPgeEx-( z{{G+nFRxxYc*j#8$a{w|c8G}J@cW!e<5vLvo7Q?W+<$O(>y29%>-B8jT{<|t`q1^| za+wmpS-AAC_b(5>yAOtKmD?{p_uz$(ZEt^ibMi`Sf|RSoVJHr#PT7Enh-hkMnzn`6 z0i@JYY8|$tJEp|Mgl_I-7|Sr4itjBKgnD{*?rx7idOhZS2UfM#S{WxXBT4{jtu;|` zaMhG^%rj}DDFC@^(^_MSGD?V@iiikMGj}it25M|?($2TCZNLcv z5k#UGJK$=9F*4I~F?-MVyz2u$`qvJwKK9%9{pjf6-A_IBFaI%3b)02nB5yLRH(fuQ zb-7MMsg+|&{Q_Ja2x2q<8Ab+2S655SBgjWT{)zYh?9VRe`S{wSvx7@9&meX5&7k=^ zUFG|&IR4_7U;V@pFO#EceC9(XrIz@v3Gp+`n%rs?mzaUfBLESfA4%2 zc8B%vbXJ7lP0n{% zCU@}W4r*X3j)6jQ6#z$K4#5D-jF=TW;re|UrqB_ zowkO&+&iSysj5j;uoM#_Il-u6fMyQvvo5XH>!11XFTD4?@95@BN*O6o2#)cq;qfb; zD*jcRAu!@^kjH-)$UE-7E%nzv@wpHE)KC55FMQ;cmtU}2IPxrp5P}o64QwvXUw`eT zXFvUkPyEu)|M5TbV}Jgy{#%bdb`9ZoETVq{G>^4D_nD8q@GC!sc+*MOv82>w&S>-#v-b2la;D%fRJnT(vTCE z=EGDopsG3$g=8uSz!UF02}m6Y09z@l=7aHe6H9@}odKt2 zrKvHJD}jLX+SDgwOkLL@qlq+aZXOyW4>_d$-k*5vk%yl6V83_pJMI6IkKMTW$itui z*q0Axi@di#U+i^@4w?3juYgD$wjrgQlC~zb)HWGHK#oi~vuPSjlc~iJf9-S6{L(Ld z^y-a=`~6Ez1?t35kO&Z5Rm~B6N7p6V$Y71rmaLn+7eS;2}km06-=a zgO}|F(E%X$^E{hLo62@Q4zZRkM3`!=qiGY@upL|O%*j>6RS6g=qN}Q@DIgFNfHK8y zu|J$WsN*)J&a8$MlUb`m!HHPRnK}S#Zp6{uI0P^NZAwglfZSATt+|^uZ6Pv&#n`C| z5@X2V7(z!{RE%TqU|I$hk!Fx`Oc5Q-tPzJ`?y6=zc`dC>4L~FNR7^#42wk9z)tD%F zcAyYax7<6ra`SEPc>JjkKKXq=a^;aHzV7u4=6&ww^GVujyY9};^1NFfUjl$C;sn#U zvaM-ruIehSHK>)%yTBEV%|ajs-)!ZlKJ<(4dh*GmD>p)(n($Q;m+ zhyXM|0087&9Rz(>k449Cd>Q*q9;drn%I+ssy?y`UXMg4+Klxw(!_R#3Xp0#7lflygo9P+KvZUpm@9J2`!DzF80D-pPYcf8tmE>|gwgSC02>7oYvNUQff< zZ0o7C7r*qGPydU*cXs>vn)gOdj*t1-+E-%i{O>x(kfHr2XWyD2lZ+Uj;BWMmF~ z60N%o)XEt9PSDXgB+Rp}BS%?VYi*cJYQ)eGVu&&HW}!4UD{ht13`Co_DL8UW-K-CZ zRK_~49TSFLO8an23`4q%P{(R7DKYL7P=~WDapYORW_^Fhc@NL18FUk+Fy)1VUq&Waz|~ z^RAokA6$Fn+T%|@{yl%>%8kb^U47`_(&0CZd8Ns4e#T~Lwiu;eT$}~QakD}up$tA|Hj zUd9j>T{r7fh{?=T2=m1p3}>_`)6l7ACIA<(VXV)7?laFn_so?a{via!uXP;^znwF* zKD+nDkNx!XpZ>^pbvB=+$nE0ve5j$@zv0dgUVp8Y$qm|S&{_e}YOAe=n2k`Y>UyJY zfCLmd$BYV~;9KTin>E>pN$$HQ6}D&%yU6a)>a@BLW}o#PfrrS<6hm$z(yD4}l?Y>s z9mV-}HB4obVyd;MI#D11LZT4BoFl6{5>fyXMNmRFZ%)BnLzp2F5Fi1fgE=5TAXT&0 z)Lm4~mCXUso!zXKCgPm?@TQ{M4U~yP4#dQv3%S*4AczMX*0^cr95}}u2+^(YyW?v& zpZtLz`@TQ--@W$G!?Qm9?r&Hs=2EnbqBZ1vvfhl-u$*{e;2vXix6seQblGQ0y8Xu}F7Ll`dvkK;2%w-t1p;@|CP>Md)j`Yz2q`&Y>=H2oxT%4(X;V!S=ftxG zXj_DNO5^tIY+F`pnsb+OpYqHA+?t6qvAdaw8i$mLG0&DU#ySllXJ~qHu|X!)=2lbg zBO`MrLQ_#}h#X^ZG=~x*nt(d(3R`NLb05g1wHOePv`vQK4q(t)bxxq_*3`TSi?X=s zIJ!1O-dzXLK}vO^m?*~764gmP`d$d8B}G2E^3X$Xd;0Lo!+VF9k8V8n#QT2W(&fY7 zj$r?~$99<}l|~3<7!Yu|x71qJ!)3;@$$AozA17hShlE@KFb#d0y9 zqdOp{6irm50a({(5!he$%am5Q;h1ykcbmpv%d$Pdo1`rOzz26;`NU8EKkq*O35sc~ zI`5EOE-uc5m$PnpcIWi`!2>S}fG!4+fx(&>2My6Fs5|sIa&T#pIrkla#S~f{MXE|O zC*nC$L?d8Sni@L>0+%W+X`X6}42j$vTa#L=h~$2Luy>H6tCw-A(m-5^e74-5rU8r* zfn#zIb7E!y^4cI~VgeWePz?>iz>%2nso zG|^g%y8@s$B?LltvRx;R5s|&?=d?eoqT9{6Osh+W2k-ykKlQ#p^>1H#+q;(ew}oQ- zt&NGVJb~X@O}cmY&e_Eo#RMU3w;Kk(a`jr9hH-U@0Adzmn9UY>+2tIW$fbfvovJ!e zisN=NBq9W`Z`9l^yuRpVum?VKmasTSELXK4S^8c)CpC07h-f5azG*n zRN1MB91%$oi5v+K0SEwHw6&sbs>ABJ=f3z4|It7F(1$*Ja(e&xaBq2dJrH$~5h?Y3 zK$>OlQ|!9jcQNPa+6VyLQs7yaRVP<*7bcwdxeMv|==jprtGn#Qca>N8t$FjC`N#R` zozMN;-@o(xCmnbgYe=*Ce70TR+Kg>}aJ;z~&hDSI>P!)sAR(uyAckV(&g3x$4q&t^ z4g`>tnbTbBgiQlt6|4n>Ri@QqZ-yarmqPAfEFujU5Thyv#t;Zhx0^xTy7~UW!Lsj2 zUFt;BG}StUm}koa&>9m>!&YjIfr;a^S%HU;XIMp~AyUdSGxc5e3<%({>%pr^(>fs% zAaDrCff-_CS2w4Sv#G@{&k;FT*D1mrh{`w&>$QjjI1_V#oy_+_uJPnmS?{3g}Zm}F;hoGM+9{TbTDuP2RE}iZXVov`R9N3BY*!V{^=KzA&i7`hneeV+BR{r&yr{s9{}Xo^9lnrS5DkY%cXo@W_FZK_fxbO4cvFz*-deD`}F zdiW*)p!?VCPzC@rZ5I#T_}nl2#H}yJ4m_XtZqsILd2tmfU)(zzYxNi`1WwuA z!~r1FqDOad6j2a!ZO%w80;-!8)7so@s?wSu){EB8ZpX~IPv}AvV(#L+E@Cfra!_|A zAXQM2CKh9ub%9w$q&6AGIu1?EXMu?z=UJ!)5GG_5-5E`YsG&ee0kDXn1)`v~282Kf z(ZGZ_BDphh$Xy=@(Y119ty3wbiTG*_6mvfdDbEw_r+Mx&Gg*^ydvS4gy1Ll3Iym&e z5s8@*OtfvfetzSTw_jS)!Tuq3m-_w7T_%Qak>oH=<&E2S$D$!(4;TThwQZT|wAtI= zpDz#MY#~!|1V`}Z=I%&psOHsVY=Q*2OJ1hP3|jkH2WF+n?KfV3`%?xS9NZB|b*Gzf z_np!w5CgLAM8xjy=0v;$vYMG81DWs4qtNWlW+Z4CH_v_Hvp@M0Kk?uE^Pf9CTVJ_! z>C)j*2p))*^Zxkgc>myN)^}aX#OUsUh(jpTzyN_`b8s)9qdS<1nz^GWY_{d#==hKS z=|4U1;@9yT53c3zmp}gOFaP8FZ@dIx=Fp0yuHRea)#<6@teYKPtcS5S$}{RC@=gGX zZl#t=d`TOMDzv3GE^IzKsoaJJso z)-1$;6qy4-NL_buc+hcOJoZPfz3-1M_Id_K{}$WG?yjn4P+Kbqh91a5U=>?mtXeIL zgJUN=U!CvGW?c&Cie|^xZ?q=camckOI5L+u)oCL4qr<(cSFRlFFR$Eqd%rve0CSU8 z35l6ighNtS2DhEg)=bp^0ht_7w3(>6n>#8J8333mnwlx1ZO+er`R9NB|MOq{gHL_- z8D_qA`MArm)NL2~gXMg0G4EnvYkgjHeedpWY7Qx;Mc=VIB9`D&k=mwln6~Q;a02GB zwCecwC!T!&2fhyg42%K4=9Y%xkPR43n!E7^xvhKq5eMFh>Yx>Kwy3uBFt}_e|V2BPC9GQUJgZQUvf4 zm;wO;A)~9PO4F??#^52kdfRF4cW$7l9D)N*;{Yb$AX>$Cthi-Wo5~bI#t@{8nwVpD zAPRvw07X?5kr0_tkSK%@Vlpvwh#{y^mEvyGWEZPbsY4)0F{Cc{eYaR1<=JAkScVYO z`SyH0)>eU$sN=u{PAxScbB;Mj#$mew?m}7&q4Z@k>5b>H_X(9z|iuIuOX<NYEq>Zk!BRS zX&9%?ShiDtaQVIO|K6{30lyB1j=QF8Vj)CuZ05Po?y_F5xxbpagQ=VnQyGR~7|dK0 zw7R)rB0w-#B{Mc+j5#lt%lUj!RmVX~n^cOFNy#}!0upgiZvrNeD}>m)f;3Szb07m# zcXkR$0HC|;I0Cp-ZMAlNUd;P01=mVmi383SwF>AqAUG4pqzdjB^Bf(ePN_>^%CVou z74O>96hIn)qJyY1BVeqpsp>e^vvnOxq!637VU$Q5QcSaD%$dPNz0|3lZObq&50Co! ze$HXG*ehjHZSIg_<`54bd;g_}9}WELV}ialzFL>l+uruJ!=vN7w{LMsF@_XlMO3R4 zh!Ghh0``foJoIoNhyk?>2)XBEklSocg!KC9ZADn8@MvD zIe>_}ATbk>xudy?y_xhkRW~bW>Y(cGTD6Yn_ix>P?Zs!G{o==d?Q_q+^hWN|EN6x= z@47??0DE~cpU-j^m-AVOk(m1ZYYC{B!&v~9IEuNoQO z{^UE~_1<^=h7mWv1Da(i6%FqB~nzzRGJW2+K#veYHwKKJuv;OkmtoLVyp35i1L`k0~%K&e(VQa}(j zU^KUJ+Kkc)BZLs$%psYp89GD}E#n3~xqDz(E|)oHDQjyJGo`%fyBQ}WhE^tbjon<` z%P@Ac83h)>)}-%x0|$3iWk+*Vbwdh>-X^nSCa7esFl>$r$6e&pTs+cfISKPd)Yi2X}8* z(@h0%iyUG~sM4jlSnM5MzIJr^(*C96z2nPd-uHPN2MTe!UZ&waxo(ad?<> z7eYuWh8Pe5R8$+7QAE(@fbL3&s_Ke6a|QI>CD3;1GJv~IB2tFUomam6+~C6lu06 z(`d*J#HKUyI-7s+kNwG`!@UAPUq3eI#o?95-got?;39lhg;@Ba%= zJ^dbhQ=?W+@4s<+_w@&FynJ%^mDTyldb_PtMT5=i!7H!aJ2^YYX8Q{b9gUO35JR4& z&?7AfTveuVt>#S3yAof56nz}Gt(Cwb^>ZXt1v6D_$ONRVR8*GQVx*(XM_o>B9LqQ{ zI}w?-m@uYbEdjB+8UTVLnM!?=1?K1w+>zr9y#aumxPzG)5n*Z~<1`V6sn#k^)Fa2S z`Xqpu3M|$aHr>4iCP*;ryT0qXuFvr@x3v#$)Hp;#;t-jU&^czcW@^av?GtpKeBy0? z;V=ESKKrSUpIn@;Ceelm^FDE~W}vdzTV8wk<|B{4BXud|ezCUFoV%D49?uK#c6HIF zZRk4UsI8T8E1QdXM+3(zm)`!vfAUZ4GI;v>Y<&v(%A?U58ZK> zk&qLq6ah>z09q{@DH{L`DN{f&lRCLTokk>1{Vb*2q`9dX6O*t|dqEaia=IGsgUe#L}h?o$-9UKWLS}C9kNVDa#)lo&f9~J<8#k_B7J%r0Uw3SC0D#%?!i!#F-f59G zt5sM$cKz}9?sZ?AT+(-`f9T;~7yMkgad734XP$lLwU=Ikx?aS(K0hhrhRoest(##S z#?2bsQcNHNMRo)!VqoAN(lT`&5t*nNxN$8omP!OyuU^?dJZuW3in(saT1Km72qm=~ z=6!OE6aWBI?sD9;DgqQZ0l2#{2aItVS5*KhkbxUw>Y+>_MkR7r4rGpGgv6msK@^G% z&DRqYt#{T#5m@Y9&WmL^y)#TJT;7QDy}Nf`k_(M_Keme7GMgvnkkgD~L^tN|q>shb zE0@3b{U3bs%b%TuL=@c;1Ehp8E)MqhkB(}c#$g3yfY4FrCXQsLwTOx!SWGFU3;-ex z&{9ZV4Ya8YE+wQn0=t2um?)?s0rJkq2@nv?jhd?f0CEH(M??-+Z$A3|kT^uM&)&Ly z9~_VgfjDr?5x_zSL>OkX`QfERNU9K6N)-_l;n=0+K{s2}abRXfv}qe%SaEfBR>xw= zP9L0q;7|UkfBnz>=UuL1nXFA_j^824#=*ha4<}25(+_>>j0PN@eYStVO&C!fQ1}0Z^Gf>f15t$S141i+lV;twR`D2g0Z7SouOAk)Y zh&Xq1cj_X?7-9&0KvazYus~10g!AQo2+Tz8cyV?%4g(>Ux&>g@rmM}YLpso*^tFZN!4;S0ldqR`I|E-#nIoO7NnV&t<2ckaCS?Dq5y zfSHbJJI_}G#28};0le)W>|eQd#iVS`?_HcccyPKo-?k>E7((jz=JOo5G>0G#qh@2G zW|X=Nn8b__C}dS_WeBPBQgSyNHba3D)kTCTn4y^g5HY#$7^ozQqu5YXF{asKuZL-U zzFnV-nunl>X6^3lFD&OBBCJ+JzS;MgYEh0v2&N)Z%lfo6u`cb3xZft4nd$iW(v{;& zXQ$_zGHpfXk*;65^ys_axtK4QDW&W?(~VZDiGxe4`-g`i25*&!Qce`u(RP+j?%>j_ zRYc-E2O?<&9DoTCcdo*O;DF%n*1%C)m9j++k(m&PJjNVC4;=T8FTMLcPhUE|a_`Qa z)+)wsvl+EnAYyGfbr~WQ;e(Lo^S+G0CL&u)bw$=EK| zo0D;UHV(1tzUTXX@X7bQ`^{GN@1ijDCYoml*AE_gvVQUxMB(9g{qQ@Uen0QZ=HJq@ zxP0x#kNln+6afGf;OxQKc6EAjcJ|WefBBU!e`XrCZCHskX@cnH zHkEfbH&7EhneyX}2ruF%HJ;Z&U6J zqKsRaD!|To*UeEK0LjhV(ac<_shLw1t3qSbZh3U+<`b{oe*Ns;8|bD^#3@EZf?%zb zsZ2xcLF=4yVRj~VaC3K4na;=UI`^|g-;Q?w%~Mg;$}~lW5nE-`l6I55$p~(4kd@pu!##xFJCZJ#&y!+#4VVnlX}T za|B{G6Hs$g2W+*pI>a;wK$GSMKooL6+dE4A-h6qy*gHBnINokHMnR3HVH(z}x>@Hg zce4eBRHqU`u-w&YM9|dFwo`fV`m0t~@zKY_wHxF5e0{Q+O5Lcg%YNKA#swikV%v_g@X}t!`JF&2cv~Ybu2~?FL+_7Sm3~^Rha%gUi&> z&h-}&9llvb(pOE~kdrt!0A^AM-9;3pH>YwiV<0yZ6%{4gDNV%P-M~QA)XjI7NHbS8Bu1nVdxyrc zGenH(N{Au%<}?jub+MYZ>(!k%Knj3wPEOBXeW4E)4lZqrjMY-t<$m74F4pT&ULA^^ zuQwFJJo6)qMM`+>=GC{o_j|rVX8vaUG#qe#>G7N2`xm?8cfS3d@BFQ5nD3nHhkr$T zzPh-0<#WII`j>xoT%T-<4;+?x23Dr2atJ2Vb~T81-0d&YQXFpGU%zs1wVDJed%$TJ z5zDOWX4^&_5Tl7AB~c(S2N9LXxz@>D(P8J!%tR>#0CFI7;1EnzL={jWs$erLs%92* ze|-7+^+(R{t=G$bu4baD)C53HRp_kh^}iTpj=s0G4UoT%6D5^ALim1P&?2oHKNZ90(u=3Lya^p)(mV5wS@% zZ&nMZozk8O69Jnv(_Jx+ZKo742L}h+LEco$G!aEL^QPt|BBeD#>K6xxS00L~bC0nP-Y9dadh<9 z{c zIx>)IV;~HKgr>!TLh8*Mg&^vV><&^UgbvsN!OV%6C@_SoP({?CiLKV_R;J5G$7p_W z|5or;ThUg*w6-=)?Qk(aUIx%fRJcO~BtmlsA}|Ga+-dxO%eH(A`euh1;@+~);b6Xh zd~kI2==e&^Y1j@`EOqlP=iJS5P6)_>V+gU!F+~?cP!16}A_$WsBB+^HYXymr0|Fuv zQE=5A004WerS<2o6la0Zh$6h@yyqJ2N%WX_`Dz3=Xb4r;%EP zBZHZ$sDJ??Ga}u-^V;V=`^hKY{hk|FuYK+lFY0g(pu0&~2r%oqhYq{rIhjmKyQ`jo z8@P+K)}|(HDnf*We&kQoCb zlW0>FcQS*Ny4ZCbB2pwyL@XliMg&)HK7?jg3*H9MX;_`2D$b9b?_At_!y`~g2H@t~ z^%@yF@@{W$P&;1_r;B`ibaZ^}27Qx<+V8`JwKi?3auu(KgK&#YGIMH0071W7>L|dhl+cBzp3?P)s|glbPGF;ngJV_nh2AI6v*A& z5X__jqK6bh0yIQ4aS>CSC_qzp3lu`v^?fHN=ck|kwT}#&)A{n?^5v`dZx_=F?g-xH zbak)4c^DJaal4%@dP24x@sk4qAhN5Ps6oVU+riDuiRtP?k8~;K`J9-*9Uy>vLP8EH z_uyz!Q_B6U2QziGT6S?7z;`oYv8(p;0SIAfE3ZdOhQP+X-A_2bZt`ILvRkUOEINPk3E|E{_M^p!}){N*@>9zP-px5 zS08@3xu~eS1KQrA&t00PX>#vU980~wkxMr&U%K+pH=CgSKA?HKdT@68i!M`O1mUX6 zga?cH-lBJvp`VXK8LBGGsNXxjyiX~={NiRi6+}g*Qd$5d)e`%8o?VRXV)PWDCvdCi z=3-!yazMlwBNGocAcDIx0u#CcBD#UJf?#e)1VjNLM{j$5u5&eQBGaqSeR94$%*=az zYzm0PM9Um*9>&AY>aZqq4grbKk%+r~)-RTzRfcm$i%j%wA9Zz_ruD`C{xWsFnz$Jv zh8Q?zbW$?_h=D21nFF{H5xSXFtrbGx*ntWFNGq+32%5V&)KbR{n5r{|$RUCXGNXwj z)}nxn#3Bu?amYx)%}g3{3L&F|8vqgzfTOCSH;))Fz?rvWpKs#;=xwS@h;Ay@_o+&|7=}%AVB*{ZrNiqt4=x?SH_4~{y+*UD+AS)#aiaIAK>v@+}BR2nKD9$!DXxF`=!F(w3Z;w9}gt&Q4FfGcZVoz|nr-u=)cZx>}ia%3WBBtY!?#ntPN z+-u`zy4X))u9yNKK$8YB?#8XDiW!(GA_fYg(o|EIhy}M-)Ql&e7w> zx*SuLCL)9s$QIf55-t+txa;zAOo5pRnK?S{x)0_i)+Uwe)&YH6RzVIhO_R0~V>ELB z2r=io1#L(H9MLpO6D$ALIF&~|eU z?p&zvm)Zw z_vGSYjWHZvy)j&zbKv#)z0GDrvpq+aRvTz>Ya$Tn`u_eC?|ko*Pk$eN^QEBQQ#4Df zcVGDA$*nH|gjv5pCvW$M_3bvT43t9z*-+l=7l%?t6FZo(*Nc0%UcdIpW8>xR*~tTN z4V+?3qKfYGKF8P%+jB8AbJ*nq?yZ)Q41hzRCJlggV+%n|MVd&6GxX-}P6R5%&eQ-T zA~*=69^}wD!;Gg9s}h*y=zD$W2}8iZu5ChaVj@B$ba!-5F^RNs*u)2~jjQwJ{@%C0 zzZ3#L*{)YHMg-DY0C^fF z6ECHvuC6c6YOV9xTqfZ_-SSXc9oJ|5tk3rKbRSnEwb(mJuxH_-_y{cRI_VNsO5NWDSRgo}+7(xm$g!CrDT$@U3t*SI_O{KV7 z=w=3Gng%mOH_^IYtxIbmrdmc(2EbvxHZ#Mb`e1!=-b74v?HB#5SF>pxwT$z{KEns3nG)eXS3ZHMi&*#eO{lv+?(nzS-jk-Si9^V{Ja zA;MxgUo4l~3wcvl<^~9EI&D_Nu-ct7W?pNl(!QGgF zhz-CA`o2SeX)GxvL`1}C99Oq*o!!58?~Ru(9^9!?wna8&8kz>?o7XRW@cr-m3xDOm z^Yjn>(ODP2!jiy0h-em-*M9A%Z-4$@T-^Qg#p+xQLBQO0^Wt|pN+3c9VnXz(4o#Uk zVRVM=aV+n9cz-eL?wze_ZA8eZ8OYI6m-qWLV<&KvVg^i(1dM?Yz?^_}$3qE3$bcrT z#W+*d6ceB#IwOk6upMEZ%v4QGL7N5i&}Cu-bT>1pZXzZ-vnqE1uoz=X-E6U+y4+fs z#%-B4+=q}d*0bUE7t-P=&t~6pVFLkXU7jzN!)irLs?~?uCNz<0T#w_XP8DERUPu7N z&7{^^imF3tR9fnaNNu8CY8=O=>Z%T=06AtA3wgfYK5)m7I{+%#XuUA= z?Pi)PxbbQ)IQBF@Av0Jt3|~W%-pQ&c$qZ@ zW+ccfVctnpFsh&{FJ}(am#CA^N!4f=<#PhMWS7Ql`=fkOC1n zAchcBm{21HB;TbRF%U<}x$Dv#z-ueR=0aM@hnM$`Z{)>3)YGy)i~a0do6O)2?v=bU zlW1imCfw2Yrg5`fuZGRGi4f-|xGiF-6QJ{xdU1MDHs|v`UcP+1+?%_DI7rbdD|Zb{ zA;c6yg-XOSwQ(q>t;-4>OH~g94vt)_if>ZrE>;(t%@&u-i_`lQc(HdxA%KH$BPvLM zm;pQxI|X%fbY`5*W)t9c*t9y%`-qpXyh(aeUF$2^w##LD^x^B@`}BK0`29cpj;DVx zcb$RbjzEon@X#z;KmYUp@R^VNU7gO{Ntz6kASFVL?1-!;K(W?_&@d*TL?Pr5nxm?r zL!Qn1X>i-d6y{wRmuWM!%_vhf=D0|(%ornT6;X=@K!m{V3f71c07MR|>gK!R1G+Qs z#%1kb@2-^syP>HR$s1iEu)^~Ob^qbsHA z{rl%*uC**#3aPQquK78}~Wpys448xWQ`YuPVU7tEY^-_v#wrfV*tk({n@+=?{ zg|XDB$==@4Sf_ECN)tId3(SjB%QO;kNF9f$Ca8g25!IuH7|BTh6EicbYSa)YVV4&3 z+2t#juidzQaIjn+?BBcf>S8f_;_k&zL^ zn@X7`BA^h=D0|Blc?M~+3IU6 ziT%~R+|)`HH?37tidDTeqrj`xW^=Kc_1!L^S{yLPsNxee1n9atY=;LAPKNEpa?vAm zYqD8gAW_a8xFbRc%prq=NaL7@C`JM#FWBY8wA7YV8zM6Ed^t~q^FF-yagG*HML#mwW-n4`PWS7dB~lUpWH+5eW z07#m&R<%y+;uq(`_TDYuZW5<54Cb~PFTJ{DrgnLMR%=^doVQwc#;4;z0DiGrlLAmB z#>lhndfS?-wXR?0m`_hmYAxIC7M+>%RHpUC{hWJ5mO6nux)Bm_7h^&MRf)7~P8qld zW}>VF2mz1*AV$4@$cl z4qjVhW=1lyW=23r1dv4yumL21030Y}r=YF1Hc1gxm@SuSb}(yo9LBMZAuVIa+6qVm zhLi#ZL^MQlHy{85cbkT7?s_nC_1Mj(Iv^6o6o^_CQDr7#0i}~^O8%*w2yMA%$=Hv5& z{m71AVP$*^zEIyqG&{ik7e9UfxnFGKg|@118c32mAaTwex)KMo+C+$gqX0UGL?L+y zE{Xu!*2Az`4|`WG-+e7DnI}i1P?KAh_uUkT&e4jL!DaFX_&^KH87@}nE+6o0RRIt61G~^Y}WxqBqT-- zDoxF2{cLX;QpkX$s@95nC``yW-hC!tdHZ~M`0K+!eq%xPE21}d16OOK$>6dp#vo$| zA*Pr@jM@MRp$1hGF%hjzMI|Oew^m!X*jrwCM2{3)W8md-At~QoZ%>O%Mdz7gjO+EP zmJ&F)`eqmchxK;obDqYgx=A?!SxO|JWt>E7bC~yeZ*Nb`&$sP-D`>03Wq#-y=9pTO zl$zF7c>-oYBx0tHIXIwdbpv8XA~j`nA_gMlD6QDIKD>5wdFf_M5z+D6<{^LEQ{#WL zfNJ;4aoFB|<|CWaH$>bps0*l@Hbfu}F+|5G>JAaf0iBVso5ehj{R}8N;xuhd8$)Qr z=H%r5)oa%l`^VeuIIK2OwiHt6GR267W}+g5NEBfA0SsLiQtpi6jye%zaxG3|h_UNf zodYvtE6tSqE^uH(0QWGFZq?1W%LeKOU6)b}h&wWAPF-iJP7Iuw19L2`uFlWfu!&Jy ziqblBN6zjpsxVCi9{kSs_0Q#Z{z%vjD)~(*$1aE&$mrU@9aLPjwYuxn+fMi5Kpad> zrGW!6JEN$HXcI|^59jH0m>ks6V&atM^W|a~w`Zq!(9Nce+ngyfGa~O8pXX&9r;>ui zNEo}-X53q{qlU<}8M0Hz^M1a!oMXthR(|iI-Mw{tJiEU*Jbd&WkGJgam}%}sv zOzV}lMgYtKLkx`QXuw1}FG%v8K7a#~E)I@xxm+II=;nQ(Uk}W`pJ>LfrLB15*^i#Q z^7+=JsW<|2RBH~Ha%7H#)J$5drjEoE*nt3fHwy{anateGi~=R+VS90Y(e3qdK1))m z6mb*xWbObaBDGckXO8Zm?i6F!cOfJ(MPzg1z=oMXwM?`N%7K}o0XNF!oIAO@)}stA}< zA0nfO?#_e|98gSMQ4y6X2q=3>GY)R*>M>GsA7kXc3u=UD=nf83DNS16rJR!?AT=b6 z5dk2?IdUl53#Ao%NkJ z+U5cP>w0za`YYYuA#sd*mn^5VvwMr4`ab#0QrF8g5ivzXV&63bcmHQZ2S9Wt2r1>< z#~63&gYSse={t;OQUCHU|C9T#JtM6mGKS<u(o|GU)x0^S()V3A>(jPPYeZs3aMNla7MKjcRBIJSH^(N8Bdchw+ElR_5UDsK z6>)So7mgvPU@GnbY_}1}A#{BfLEM>9s=K3tk5d&=>n>uuTF~$(w?e5w7ep_y;j6*5IwoRp)l3QG@&(BtQ@9$5+Lt>JDI6%aDH34khLEw!14xYMCBa|HLMqT(@N>as|iwik8SAey_Yv{Gs*5~h|y z?2eYX>$=*SI-t?cFFQt4a}hID7Xnrhb8uutGIs}(CWruzMvUwx3ZTT)YBkdkC=f`i z=EfnVsOX}OCbF|7@h0Rf;H^2f5<@t+bTu!QoI7yXu1;2~^MDjP5HV35$Bjd;UVOF( zxkq)WV$(LzYukHY-n(=uG9pr~Wg0KEj5|>@hr~>+$?iJnhU#WbRI9u0jIaPfMN9-? zH!4c4RVF+-x+H4jb{*IszH$7}L*UH-Au=HX&6g8S#63ql1o(sCU-=O zhM7r3y-#T7rlwMx4I6c;WZusf-6KzIXG;-5#O3kj<)y3hqvP8ArI()BEBEF%-+__G zGSKNgS0%)rX*UB0iRsOWYz{krDPm-Zk-rnxlix`+|2mZK-g@zcU;XLz#RDm$yQ!JG zMI{6H#dmiIEkdx~ZttTAJwj`Ge&$&t{!UDYXFQ z5TcqlH62kM+y!=eQZu5s`<|&aLM|d;4LQ};09nn{9b2o z-JbcEoaR^F{uB}oo3pmrsy0MGL~j#721GMM2Qjr>q;6HUnQETRW6G@-@HbT+Atq5N zn{}}v_p_rbm#sCaQ%E_b%!uZ&8MbXJwUuF-w$pUJ8OL#QFmpBlHw(;8Xb4SoG@s40 zsMc0!KA!N3me>P94` zi8L{A2WHHHA>ddBAZ%g|-lQRi{~vRI@+?`BrFUXyQq_B}nZ3!U7;;1bU`bVh-R!1N z(9Pz8A`~tt!heAOABAgTK?+wO8-#Qd1eyR*s0M1ttjvte7<_tzncb_ZXW&B3qarh_ z3hc~C7JU)n5&k^Fp7}AoN6-1b-{C_yHFE%RM{)>^ASnh|yBTP$z4zK$ay{RF z`5N-VxYM;0Lon{1-OYMMIpxECH}U%Z%f}!8@pq=S+fR@8@5;-U^X^dQT`mQgwQWMe zk_3a00!Q8uFcC`0r6hs)&4``4~LA_&PMRGXP;>)sVeIPq?t zC?)MZpc4~#bk!uxoIhlPhFJq2xhY`gVHV+!r}p-7ld`+I-tBf*j?!CovbL!P0Rl7Qy_l#`t!$kZ>C8C>HYl~nU?tkuDO)M?%-zo!wrQIgp>mYhMA!Wt>m>n zJzB32;U3Hv!k2}EIU<-@*RFjFSBU7XdI+b?xj2Apj{wOt_ihkEv%%JSLjplI=)@#a zy4mZmKL7Ibugu`I^*8Sxk84v4kAX@wVxjSVkst{O4}wCtySh(K2W7Cmrm7s zyEVm<$s!04 zzp=pRcX$gtZ|hJ0-G8$^ybcVH?hxV8H6kD!gG7?#l8|ZJPS$FW^bP==61u5c7sx;e zjz~l#?zQ(80VEtq5zxE6e*M+ESI?K}`DkZr^S0G+a|-|vA>l#Vrj#-fwx(-qb!%?X z)N40WMIdlr+ZiL4K*H`p9voJR{S>2w-b0EAPfBwg*9Lnu04`mW}k1%E#w`5myXsW8( zv^TA5xJ7_s0P(Wy&yUmA8n|;xoD$Skdu`jPH*0k}#rvElA*gEWTA!Ydr}MTodsy4k z+Rjyl(LEf15C{Pgh$zAdFtH#85}mgyX_|NY<@Oo*=}N1-KYjl2a5Q;RIDYvHo-#8n zv3-1Ol}l#I?0z+dO4D52UAvkEMi4XS88DsC?@y=o>G7nK?056w`WnG%x2LD$ z?cEK!nYxszwbiwSyO0x#S@Xv?)A2nmSIpwp9Eg&bRpvD2SgNYMYOiM9BL;&=fx9UX z=6Tk>YU_d|sf>CMP9d??x~|){y~>ezSMw}ax969S=l2iCho{rll}UF~zBw#6*9T!-*X_m2=imAM z_Yc?4Sqe)^^Da#@5&`lMw#JAP9%?{A#z25?Y0CU9RP$f$W*;8j{q*1dvwFS{Z`xa! zBZ8YkxLc4g3rDy}j);_&5DI9Z9Rng zUw!rJlTTjV-R5nxI6{C$xOE{(MUo&Qma-#~b8Dy7YSXsW?x7kW83~)#9v*-Qz-kUr-O*w_z598&`8Wzf1kngbBy)3f3=DMZ8Zm?o-Bc}D!L%zvq%?6^ z%#Nl?EUC<<8sY(vJzDoXu?FdR?Oh*^=W2f3{NYsHkuW@hgmcb0PwtIp&eJ3!D2WJq zul2mS_j#JHraqNWr9AJK-EO}>KYM=LwsosDLJ^6GJ;ETCW!WurPC1p#ImadnzXnU?^Rl0%G3n5d)uPP({Zmaq7 z3eM~L<)8h_e!dSkvrsb+40l8sSO!WHKyST*hM7fRLJAr7QZt%TDSPYIdjv2E_N{*P<(JRzZk}HkP6QRzHNcR4fV7!QV60m`o?9SGp4F5|ya%TO zh*7gz_aNaUfLrT{7*V^!aSH_fYFzs$;?#Pr&anlhHl}nLQ>Uu_^QWhGy!c+D8$J1%+=4-R=E+Xa*;6O;s0O;;H zr<96F8TqUp!Nf?gp4Z3Y`LLAMYMxTv+WC0Sa}e>oKe%;fU@nA^B$a8pdvhBn(OLjXO3V_fB59iDoEN0jTEjs!>xRStaN63rc416g zzmNO#>GAH_-Mk#mPY>$0+wT(#6YUR&!~Sr%xt2UJOPUI&Oe{Q1X3Ru`o;ucoga|~x zlREwus(IbkFaG>rwewRDSZLP<$bkU>+B@fjBE3~@77mnzv-H}60vtU6kljH&aQK`k znQrdLv@~1Q4N3AOx$I8IqmBGD5R&8$4m{1f?dd)uc1v0IOUja`skh!v_IPfNWhsS| zSaS+M$$`*nqdZN#w6;+Sft4IZJdV7D))cKP+=% zYiA;064Nfi5ZK)yd_A9*-M((CTOTP(roF!TagS zX9^f1=?st)A(TLj4Lmdv^d#z`4yy6)&AU=^nFuhh)KX?r)E)$$M0UHY-Qke)lG7xT zL<*ACgXIz1Q3q~;~NG2ZOJr#yJ~*>*`Gap@#h4=EY&RnV60m$L^2VX z4tF0D2NHmrFc3kjuC4^kX#yl_k3fWgx^5QSn?}7)#uykQB5O4iqHu#JTa#Xfe02QCqNRB0n>+ozV$Uu5s}NnoUNW2K!zLG z{k(1yV@|xa4R|^}t@T_FhyC^4v#AszyuP~L@AqZiO}oRqJLGx6l#mngsOC|~aA}uW zL}XAVZEGNMDyHrp#O$En2ovW#wNOMbi*RKMvko*Q zIny+iG|lSP+qqWTs=Idp5J~H{ZcS^A)+0zj%mAjjnA)~Je)0KF_vJeQEV+0<@6JLg zNmxgK=P#ar`M%YT-KiP|XX2#Y!=SeA;0^$shy)nBqas?euD-So0Lw($EdV^gJhs-u zHEmv7eLTmzr+z*ky{~f?3*M>{g=!ZD5eJ~&R*{qm2S&QrjYv49&~Qj<-s+a>mN*k4 z0U~jL+u+(efxBr9M3Ko{)odW{8O3SzViW>^V#{%QRzzc6WCfa9<)s4(~_;=n*|knKGpugJrQjZEM|{5hp^9P}2aQlqP^6 z_SSoANSG!zD)ZXx&6~Hk*L(Kv7-czV@5i+kZDEQ`x$xmIt%|j|BlqS4iY%@78lXLh zC36nKRl6!SrPfrt_SP}*F!MA~xVyu{>C_FL-|Ut`?%L|<>FK`LbyxB{<*7)Rx+|nb z1J|{cX|jm(=?VAOYSw!PH-wEk&(j=8TixXNg!|J(S%lq7ZEF(t za7PScjxciv2&DaPDbwU;(^PWelv2s%=H_;HeVfWI=PV+G0>sSB#6y7%02D!tOh`O- z?TCnR8E1F|BJ$sP-+cKbJ-z;kZjT<}29oF2JA~(49L22x1EHup_|P8{z#z522P(v5F802(9LVx+)YxJG)=pM_O+YkX)fL9c+M%$(@fhD z)O+nIiFMbuQDP=C>%@#0fG*5AWhm-Opun7R4(Kf>!XZC(xV}2f%TAc*DPLb*-Mx6e zTwj%WNx6s!2veCP=Wz-n4kW$<2_hm9(lECD)nV-ZAy5Rry`0eBxYG!L$Jak?>tlE) zM&hKVK-AR(J9rRLa0+!6cC7&#;D8J;px#pu31))6-+hdyz?X1q-z}uG_m6dy?9=x~^`v?E11lh@?q! z$$6{wd_F5Q?Y-6-fZn_J9-M=+W73E)I5(%1MCg1vZ`;v=-#%^TkR%BsaSn(86v+`v zj1YD@Jtj^mm8YU+lg@5 z@3kE_>jXS*AcZ{(iSX`lxVgT0@#@vp_3gaurezV~T$WU3PK+c>g2;q|!}Eto1VQ8U z7iM8*`oLu$$1@@${(qmG_B*a-b8Y9xP-CJ%RBNVvAlkwe9E8}y0hpPYQ?K1M!qmbD zP|YYn%?cufj}?`wx86_d2}zb^uUZiaSzOyRm8`LzdSHm4t({R2ffCRAy`I2!4Kt*-MlBZO)N;>@XUYlxHs z_SUCVM6!qX-k8YT!wn4Uh=L-q9@^E+hIJqSfY`&w)+x{X0%S2Dvk(ZWOn6?8r-!Z9 zh~cS;VQD$9>%1(SOE^>wp&&DNB^Ehv*6sSm-Q&aCuBQt`jfk0-xlBc_ulCPhynO!r z<^J~B?r@8Y2q-D@AkXm_Ei(`g2RjfTB}qwmq?s}!ezQ5o;lT_*yj%o-dBpMm^J@0q z`*s9?H1CKdRu_>3ShwEIlH_qiA1{zNb*PAtQi;B)T5BEADNh;5wYi2ySJhTE0&+?W zsHQ2Gx}7jQ39WVQy-LZ`3{zDNIj`+UKl{Sr)iO_Yd*}``lO&{+LF{~f+D|uGidq8) z)vmp-rza0Y0!{(|+FGxzI}iaA6A@t$qm&#Rt*!x7yPdW(L}VUtd(hU=daKHW2-7@G za!rc&BDx^+7~Wnm^X?VHsOUZzF13Uwn&%AJ|b72N@X2{2EICDgiBH8dc1 z7oy=!K^(TDAYqy2(LI~lSgdd=A`%elu4+gK$Pvg)wb$*w?hl7)+B3^&xKVO0bD4I) za(sIH;`J9{c73>tAePw8d~?{}-Co^XA8u}MuWs+=!)>0Xi&Z%lAVd~op|8(h7Uskv zITevCiG;^R7b4=D)%+`V(r@b`_?vbbVG+(85oTaOl2WR*_FgY`Wgr;)Ym{2oajwL; zwi6R`!1(5+qqKHvtzYOnIkW1iKS)YrsKAoI986i*0{}SZQqO(uzQyt8_GT*iaJ7H? zem!-&U1lM=+ReLVD|zWi#7V6ofV!&T2nvCQ1HZu{6B1KONeH7`>~{NU-n$;F+NOT4 zZEby$6etGhagi}fDz){;r$D4-Nvqm5@0O`|=*pYcd z?X`Q7l#5 zLqw#K%QU4@IE@ua0wiD{M54qj#3+)OQ_3Qg#@_E&#>u~SLc_OpD*rY!4Me~(BX8AP ztJ==nx@qss;sI(Q!b2VhAjAnF+}7@Zw>$;i3QlS*ZOo?Z?BiyqiJ~1`^Wz5_UihI@9y-edoD$!Tn3zo5hy|dNK6x{PrR;VQsvVpJ`v%?s9Ei5sr^Gqu-d$C5NgkxN zqSbkS&BEGSFmuU5A%oDNr(RbN0yhVf;R$43@}4F2y19iDn*l-~v%9%zKoBxAfrpu? zX#fJanYlS4=ViB#Shreho9B5h=aRT}XQX*r7@3GuO3Sj_>bhTckEhe?H(!SJ-daiW z{Pspf%)AK9S@yg6+4E;t*N6SQ+wBh1a!92}nUMukCQgWigrg^BPDzA_$KH=9kQ{>I zZ=S)8I{rJ?Xil!-vZOjR{JSa^(a0DvTu zdO~7Gx8BWwQmdQ010W%`Au#hMsYH-B7e=J0$J6JZe{pwng~;8kYMjn}cevVLEg!w$ zw}1II?GC$T=RU`WXN5rkAR!5XT0fs2kEf?FODVDBySuApPQrXPIM!|uT~%^<{^HfN zl=b}Jroha!^ajyS6u>0r#zc^E+s*_Q0cPglw4G9#APGhUu(_FPE;+29p6;nAA%rP` zm#N5da5w9SVO=dK1@J&4LyS%uJuG^R10_ax;}+V@BftYB1x@k05}Ah zbps;cG?54+DvI{1)-NMcQ*TCeCz6P{EIS|>7N51Xfmo}xdW57|)mm%JI6+d!+AK^V z93fb+uIJA`e{=Wj4pF++lBcalR=T^ry?c9l{qC(WpSHD|BImixg@@bERr}N9yZ86+ z)gepb#D``7>gC;GF5%X?pN^Y*kmPyUmy($xCo#sgwzX+yPNfi75o94ZMTl@;Pp7FA z>y0o0idkn8CN!-U;k~Q1oOeAQ>bdgB1&&U9ODwIeY)OdBeOQ@wpt@*y3<6!_;(>J^ zRbpl_*z1%^Cgj82^HSzA&kRw!nZ>#Gb5%3N!Gm&B_2c71=vo-3d6`NnWzM;zEW5%} z;c1%YWyg|;MRF zKeG^;`S2sevYrMHXW7-BDWaeG6Ey{THLI*`14`Ekm; zZf89Auxh#yn422FZsC%rF=1`BsoJ0kZnc%EFd_hzX~uBX$}|@E60X)ageMQ~Zb(pa zLCUH|lp?5m044x1)c_~rFmS!JLpWUhj1)n{$ccc$eO$tbrKBZI#W5Vb6rG1Z)c*s= z?+|C??oipzIZ0n-XLC4v6|#3IWRJ6*l~Xb+JEn-=A=w zyL-Gp@7H>wHMV>Fl{^U|io=9Z5|C(6@%FjTZMhX34%7v25cO-Y^75|Ca7hNJTbAas-LH^0xc&M%8?ZD)PQi$Z-R7Y;A|zRjQ9t zu8}<@BcJFTVEpo^08gq{jG$L5Pp@J{1QEKw=3Voi*M`C2gV@K1Ud0eEFRy{C)D2z_ z{dD`UV{ip#NC#%s2NdObq1KZ$+pfVjSfdayT7uW{YiyH0n+u!8^IaabY?)Yz!HX0d z=3MU$Fj76UHor=;oFlqFu6WxbK(%sA{9X>Qc#|k*I^I^hTI=NzoG)pZ=)Zsv7Bf{+ z99(&+r_-&Z#&*lGoJ;aGZm;Dr3Lt=pGaeG!1g9PHvKI>)`Gh!!VEFk{UhtoE1OZtj z6P?+TL0DuTh8n`iJLjc{sTR(XgKk!OYgadivA2i)H7Y8tbp_Okn0Oxe?EAY&3%)3L>l^%NmeyB|W|PtejrafmPa&MRV9 zB|&|7zlNsUa$~exFq~gr*yg-7$##?qs@?J9H6g59@H>;ZI7eI~KMf3`%CfN;ta#T& zl%QT4hQtNPkn)t8D?HT;7elsV(?I-BtcQxy-7LR8R1?zH>m8d~T*SXv8S>il(i?Q& zyf{C_@6fkEY2tE%s4&}dBaSlAXnU$wgHdIv=V>_DvjqOnWkpLULtK_$FddDqV4YXf zZ9~ZQ`HHG)=l~LgiAm&#^?&0@6u#!jDInia2#)Rvrgr+2taZ|yRVMEQ+4;JWAGI$m z`Fb~Gs_b6_#h1^qeBKh-+!}WH)r-rwufHfgXMOpz^&1zoe;E4oY{CoO5VA8u-rQUB zk>;tCyM{&HOrO_!rk4}9x&@^)_@Hy@nSA1TeMkR2JYDbEJ6iC*IFq@%IvZZ2G#ifC zi{_hMlJLO4a9{v*c7AA<5QtGH+4&jLU+bdAOh>d&k(lYQ{t*6Za?Sd4c3fdOJw4!~ zRh+>w0Qfv3}n5LH|@@;FoFMtWD9^pqd%Y zrgX-%+IuZ3={NlHbsJkF4tfvUE=RPgVEgmu%|UjymtWP!k|6`XPCek|BR# z4?L~au{M5L)nXs43*bJt_4>YdP1TK&ZHf~GUm{^Bhi&ctpN%5ILqFAUSV2faItL(; zJzh&>E_jPB`MFe=6^4yAV4=G6_mJ&r>|9Zue+~@-^K)+;SJ}jT~IBOMB#fS1qm)Es#o(px+r79W9wXoiCX^->RPF z;hTxt*~{nQ;|nz(tvoNRJ*cy^XYENZ)E8dffD~&waz2Sp6kN%Tr>6%&b$+vH+bU2Y z?~?*OQWmj-paqfpL;t;TEAaxr8XJ0Cxu~yjK)*QaxTRlRkj}ZR8e1@`^&K+(nTram3Hlcaeb8&J&JUAYBVFVts*SVdG zDl8DwQ|rL8uPZbmjNvdkCzMU~zaJ*_o%)2dkd0#y0C;)Q+FP|@(v}z2tznZ8#iPe~ z5u~*5Z8re&2|nnZYCnr=ltv5+R{*r>`w2YJR^|GJ5@_j{F}KoL;#1~dT9U3;lpfIj z%yk9dds5I!F(u383|R#*Sueq8d|8FjsXEJ-yj>b*i*+KDCi-2V(hg$S$nl#Ro0V=K zo)IqbVy`aGs06>*)mXRJMElj{Ho6`ynx}GkgeTd|&Wwhh92;Gn&7V(^j~YB5n^1#d zRs*k+gm<1~Xt2!Bd8%&`uZ!SxU0v~80NnGCeKNL_4Mrn)Lx*K7tbEbg;Hm0nfZ>Ws zMWBF>N38wrL{>i?mqA?WL$2hUEQQ^tggDInDy4Mfdc8YISkRGS+y@DL zAr=eLMxs(#9;>p!a>Kp{+Io!Eye-CYRE8Y|DJvU4A^0zZWFPyyW#Pw_hOi^WcIIU6 zTO>8lCTO4m&$yDZ*+nthAf4YD?|YqWshy(2&<*lPb__KjUN^gP%Z^A0ye%oly2AU{ z!+-^K3kTbN&%Hb{%(Us3X`LBw;q(4WLtCZ~9pfF=WjJ|A_m!U{O{pJd&j>2$LG0zx?Fi67=7K?kEwT_uOtpDZ>YUy6K15h znuR2B2)bPLi~mL)sFroVxYhmX6es&n?lBNFOSt$G$)`G4N1fmRGPSnGzvh=gc?MxMmCCqGD-5X_m6JPWEAe2F^uV{7b zN5&IxZFoe@*C%;>eyMgk5{@5p#!N`H*85gr>jdQ0KTP~sj=S|aFsg(&U_bMqE3%M9 z2h0C>!|PL~0#pxueRZ8^WksO*SmB}cwqJG1)l<6WP!-?uHMDL<9!T$W&0s0AYdSplxe->l-;gZa7h z0}t(FP)OnELV*4P4AUJTM)~ zb0X(>owr8wAw-j{o4=f?pxyoU#bjR)S~3uALKrML*{-ZQtcp4#%|sk`8ATpxp+!|L z#B`%)HA;MsMeoY+ePBydvx&Cw^BU{tmJ9K81@hJg7D^UX>+3C~mq>V3&^i+*%l?Ud z{wPe7NL|Vq^J+0rAKiVC^TpI~jyb7gPG`8qU8%ll;MZW7 zf|3~u4q=+D6WWGdqX89Q#H0)1 zG&Eaxuv2>>Zfw1-t|`x&l>3~TLBNEiw=5@zQ6boNpf1SJw68ipgZj(<40Sk-9dPl! zr2V9G@yO5Q+ti4g41C3CzMCz8j%cs7JNk03tIiF!W=4hwI!um+fA6uY$iZw^!%&J2 z?d(#@GO^@qTbOPUz!R+Y^B-k|Y2aH>CqIZ*_wBF_JH0q4G{&UpsmMAK~46*=M+^=DzJER<(VV$yWnXEd&fF?_T+;Cl;)BrM1mi$a7 zQ)*iAJ|e^UQ)_HxNSs-Glfr$5jbapv=;~T|TP_98L3{l9o(KX6%QDfebcOb_nT=YR zNIGzC&?lIcH$sD5X9grqEYS6f#X<6UL+izpafz1f{3S^=7>V?DOYEYf(eQmeWo~A4 zWB+w#j6PhXGbzI~aYQ5qB@A~-K9>0Gsw%G0fkwa z3TY?Ti~P1=GV~(Zl`}(*5YP~Md`?mE)!~ksh3WqE z_bcXzu7E;M4{P0MIx*)v^N^d+9->Ckis=K=%s{B#Q;hCcDm1YH6 z44q`6K5u~|4GQA!PD>c+XM7h*&G(DRC8)D-GRMuE&|0Ld`svD-jXn53G_@&93n>2hD@%2^T1b=1|B>?{b``^hfyk=OVmV;SUngkz zLcK9***uTrWq$ay|8}!cHp6t?Kl{GYezcQ+K6P+(uy(Q8EUMhzHlq}E{Hda(DesJe zSW*r-kE+QG4yN|6CJ~Z)3xB!9s1HdpZh*V zMus2rGgAr*8zs)AmQ2{3);()R_|g^Xvv2jusba>SZ;4>NaL=_qnmIv}W`+!|i3`LW z)EvG9U3n0ky4d@$+)eh6m6o*rmBf+eXL9`Mh)!VLHABNjY0p-=R59A_mUhRiP*SBP zT!e{c-j&(m?Fi6^Ca;MTD*rMS;9!VI)HV&vOhd5I*1r=A0waZ3D3cIs)Ub4^x;u-< zGA+xqpIlAUuivBvb%0*L=#Y|+Xt@Nq;(XBPBnK#}slPixj0KtsfQpI4K-*`M&O+C@ zqg@}!oPW=-KU*E55S60#A1}Oy*I5natH2fp$geMsW=ob&d`{bSH6qd6O%0J3Z;dYJ z+D{fQPx2x6?U=0z_j7Ntddt0{{!<$kOfXyzMa&5Cn}3`ldUXqb<;&k1g<51*3p8aF zN{}RKi*1!+WXWCwhQdX;H)+8UbundTa8+}xiq z$wQIePTQA>!v#6+BwYUsGtdSAEP4JY0+M*jei2@lvv4dz&L zT~oi!nI+l=LLDtpq_1roE2ipTuCb7Q1B@S|0x*TfroS+`k7{`2gzyEBt`YbRw7DIz z`njR)gtM*e@%8(9q0d)TQZQPIQWxu;84YgOkbh`*|Ze1rLlRy|L&R5WN z9}eTpGPgMX7%hxbuVkdf;uQczeU04y(sU|Q5l#8wLPi$xJDbh*RrXQjMU_)lh1Mbc z%F632_~Xr~L*|C{i(~tjb|Z)g7j*s2s#ABMA8HG zRr)F;`p(`pNcp{W0qjo%fRg-~r$G`SP4NnPx_IvSV)=be_bK*2S7{j=URqlJExHNAX`z>*!4a610s8u|vbkdftP z+sK3AsHFU%{-P!HAz0<|yXYAHfmMPV?zkXj#s9_I`P0)!9-7_x=M(M6l$%R&dX&)U z8IVEtJmqrba_SWAJ$tq~dlLwE6mH!3lU&J@D7Y}OcSCe5C^Ygzg}XGvd)HTJsY4s-RpxkG?z_uS36NPH7k3XJ0cP)27r~%9cpnhl%~#)!0DuUN>*PHC zOgTwnzZw&u+fCMgAQt|l0MT#tkghA}XY7^EA1gtGE ztdhybv{EJ=dieuz=p!7)E28249g!}OKpgBq?0TE55wM5feZ~XdIB20?FKZn5O zN>03Cxq1*!N=TWhf8@yn06%xzJEfD?;*xehrnWZ@P8QAi&R<*-+m)3FHD;dD#!*r7 zeC5Rni)fW|L!Z#oi}`_}i`}E`i-Y6xSsm%9^JB^Y^g;e*)g}6J;c~zIa$)H5nuUov zG4cD?e2kCXL4HdpZKxt2slF+1$SB1~>!Cv4RHG$Q?RM?K*dOY|M4iOMQrQA(Ks8;m zNHK^q+`1TsGz_6a-O9Spotx<7oRZS^GE3~rg2hjqbCy;4OA0m_K_2TL{lxkumYNj? z@<+$NU^mFi8?+{%`a0}@6sUI`L=|hRekWCmk@GW5opN1Yj9f_i0h$MPVt#fCFLyX! zpKP`il2TL2leT^AYFr_rVS%Md)E_oU;gQ`FI@zGj|FrjsT^GhU4D<+X+QElJ@{^a;kHTGJlnpQ54XyY zTCN7fl54U?tuBkN9oE0Ou?ncKQodN_yI52?KfJ8tnSIPGdDTf<@Y?Yzo+M)Ob&r}6 z5$l#GrsMH$=b|Ogo^Qyg#Dpcg_)oK^t%fY4gxSqO7hE?s%i@gsbMxpw;G{I<2kUDH zm5p&;h7!Fni)zwdhUK61XyYt6yoD8+Nv3HWZ>ULT^3UOv7t1VlwEsL6yn^kEY6W25aDQ;Jc1>Uqu?GG$18 z{lAdHM;hL*O>|v2oz>7n04E?7pY9U~x7kzQ?)O}~| zDE>2x)t1OPF3ye9uK4HHr`xGYeTiV+V6QNLVb~p{SZil8xV6+woU)nPxYYr`uAYeDl28I7#u8 zPYWZ-%!)PTS+`+J;-ky&R()KVDLFK$tOIe|`wtho)#hojt^nGuJo(UUkQ&NFfW`y? z)xTkyTUw0c0Z#t_O?(A1VY{C6?og-vg1U%^_8>)n6srW=sLgeG9}@$&$Cak)$4^O@ za|tS!YqK}JRgQZfAEp?wzADelo0+v8P&sOyz1*6;H0lfY0mK}URSETPbe5UzBX%fx zk*!fQ_c6gdU+L}1;-Wa?*@()?x6$PF5Xq{D^4h%mI(Kjl)}iAssifVUSg{sT-h&_e zgL&uiu|^wuQ()B=C|?5!M6Ri|CywP6f18B0cJ)a0z(Q300)Ghxta*&^7_sx(+6?T z%`~?NLoK}+cmqpS{7JC=M+KT! z=DjW#!uWVv)vr*(IiyRYi=ElauFJC%3a>p5br$%%$-4qCTeVWTdGK8iSIu2{XpXKr z93t7Zoeuh+Y%zM3px5zSo)x1NbquONiwe&`k2`;;V@z;UE)*`v{Cr`VX+f!F>U~-# zVm|;QP%#c^LO5PO^zn$(j~N^NW=+V;+d?mbwLK;V<_Z`bl}el=Bx}k0OQG=ICM9=# zE?WHkq>`xuz`d%qQkzNlU-GiDKBKf+I=$U`d>ACGm-l|Z&;uL1}nHmrJ0*8{b+;04H{t=n$=dgFV!~y+PtE* z9@@JM#mupcDZpuA1y>85GJ)S9%UQx-wq1l|)Ae~vKi)<`5}VWjJFC&r7>JuQBmY(7 z!;gWmhL1Ya3I$?T&}gb(DZ7`|G-WdUki|$BQsv`+z$$W-=o0(B~IEATW^Pp^ojnC8z@Lw^Eef+)|Dd~9WW-Y-+UOVaeGbyuDzp2Kr6Jb-Z^LUjaUoLcp`rE? zzi=}LJX@F!92uR(09T9G2F%aRtxn3b^Ox48nVQ+YwVzhVRo|mz=Rysbg0S`~v$-rP8=6zjR6SXpH9mfDYZoNsFu;JLuTQS2y zzicERw=!v?gNi5-48Q^VwzR5RjX|@2UJ-YnAIw$q3Sj$%sS+e&)Nv26E#4#Tzy2Sp z&=_&ef4voITwp<(AN={VH&GZ_d-bEnQ3sN4(Z@~|P_Ms@g}&MyFurKQA2l7`vQ$1_ z{jffD1M=Ylx&x=;hf$&U9*@}zyr!hq<*2gdEdW;&6ve+FKA#Sqo~Kw7VA{XAzcAEj zAxY56z^)FrNsj%^LJ!8x$546)uulrbSK{B|>G)DwN(Qm>cXuY5WEYo~lPU2N#UwHA z9F7A+6sXm+XWp4NvKg>CSyKJ+fV?mJ)t-FzHIJ9N188u*zL{Po0R@nUp~@e&uv91` z4^MZ|8U!s37*PY;6^UsJ0nahg+yZ>-KqjW%|KT5pmk{++&LgPrcH(M1e@;7aRmQ8b zaX=9$eu|UHKJhITwj3W9=3OlChtXQ8NnKY55&P=E%=Xw%N5F4){#klA+-sG0M1iJ( zMm_ToMh^zwTW50yV4U8@f1kGYSbNV4LkCLgZa^~twG@Oln2Dk7ug?w(U2+HWjrUjo zYV;+ve?p$PD62x$oh0h{Tm50&H$J^Ujz+ImU6cD&|J$_z{OEzrRs-rujxyy#@+rYz z6Y6;HbWjH<)J{&C)i;&-L4@-7CqtCzKFh6se37>DIC(X0RRlZ7OC;Qx{)|qr(ufnx zXnEpcIATj5%bK7rX>F|b+-Gy$j5v{&npHOpV$l`ux)`21+1}DIzV7JL1=i)_nq@JT zW!bj)DE>IzY0~mjsghz|)nR`YftsJ?#v31V zlS9`sf+-G(#OYM{>QWy(B?8$in4?u**!Zy^kU$Nq8brJp_Xp`zL}zcnUvmyf*56O8 zP=`2$Y9_}1TXj1YJ7OrO1>YNmFTxjpXC~Djjh~zHMN)wxABesbWMVe$8P1BKyWF}r zRlu7eEWnbY45f$fp8>XTuAA3lYS-3wJgY*LdBTuYf$PtV@26sIK2SGcs5O{Wlfq=< zCH-WZ=%}FB*b}2%|D+_NMHW)K&7{ugCA~L`H;utbj}Me^^^Qt@?M;otxGua!Ls)g`hE@ z`br}9eqU0@zpasqnC$HT>@U#VBZ}$$emclM?yM;wZNcV{JmMH<%m+#42i%3%xn3%< zxsBh<{n0kq)zNc`D$AyL8(1H{1ZDuP2Z{7UX4+RL(0N1v&Q)%qRQ`yEuOiz*?g`8f z7chtS6jiWe>1ZywbR=fgq^IKFZS(7A0ocE}e--czs@XdxgkBPN=G{C8{tUb?zj6~k zHq(K1(|lv~u!rk*78cmqH4vc>h82{n9i{)8_j&zlf2KZttb+1pk3_^P;0*&!9;SDO zkSr`180Y{JjSAJpc>PuIgR{nCPe7<|N$QdM24|on{`#PJ>p5=n-$XpGisf6N`gw}v z0ZG!)sL?n-`&D?f{)H3%>{K-6-`yWyz%>j34M$@=!@J(mp5a{e9jfk}zCOUNCQO~C z1%R6r6&Zf|qDfkki@kkckd1_!hVylutd)`&x^Umkl0h4=@ zOm~>v+MjZH)n>m0D$_3m)bueZoB$+RF@{_GFCoo8`>@rsw14l(fU^76l^d(D^j*#d8Yu*fs-(Cx$Z2s2hyS=)q4I@ zmg_iPJ6{Vx!FtcWePa+FLQPwHE*_iQ+{&4{=|-B&n`u8N=R#{a3s2mlWMs_%+dg`{ zz;LK11?gHDq15O`vV~ZAxV|ZAtp9;6=7FXOhrTwovNkb{zLFa1VG07o)x2t)82?X+ zt6aG~?tlUjhO42H^lq|T?UC!8D-EW(LTxKgY$s;6iX1<|a^AJy`=;5USQy^UH9B&1 zPuU^a=SXP;0!Ryu_-lB$1qH^bVp=_BLjh41xwtZTU9+v7$E=id(&T2fBPZ2_uPXzd z>{W05yxe`%U%ERpqeY*!VYHZ+ASGKOaSa@RpO5t6`#>+i0taY06sL~_OxW||j{~GO z`{9V zh9ZsWvSSr>l)@MSUg$QFhAl+>^wI@k?iWvd?dqU6aMABJwxsplKig-v)U|nQxKimE zXAPgL^Qx`ft9}(7@Kvm)qEgUcWzRB{s<5u&^!#=9=nOO$SWI|VVI3@{+Ut@H25O_W zW=<23hDb1&ODXPIiYHu5lJ=QAyjP=f9y1>uH^<8-F%DAuA$;K&>~C3mHku6iMmwiM^L!iW^V~K7CwI2aq2v)BIPI^`KbCAzMPyeSFVss&OR*>PjtU z0&~`u{jH`vjZ%awT1dbJ@x6*I>T#1A1)p58w{X$MK3@Py4h`&gJE>uqC%tg`pGjiV zJ*pu62h|&IggY}Gj!22Os7xQK%NaoWlKR)yE*#~Qm7*>bNe6O9{Z5m>TvkbOe!8pH zOiUKlId0|M`Z!T6e~o9@Z!egMtOYw&u3?XlebA|uwYM!cz;28jN4MWW3H0e&vX7HD zDBTjd60gmj9Vm55&*H^rbks^RzU76n-#bdu7Y~&a|B|3C%b$pC93`XJa~S~o_*_5n z8U(#1ZI19VlLI8pf8G>jjO)i`YMOJmcMGxO(-^&p3q_Am0LYL2oqBfLs3~`|=I#Bn z1zQXNu(vso@4ce6Ir?b0slbw&4)KP&t~A+Fo&kq(i@PH!dZ&W$VBI|ON|z^BL0g?$ZiSK?y?udpPcxS&g>IcvqO z<_i>;lvx}1d})c7S2G%y)nM~yiye@O!gLV)`=q`Q=~FXGa!qOzzObytH?((l zawC6}IU%Pxqi6$>vA1|y$NS4`){3-FsY4EQmg=kNoQ7nhak?rqCF$JL(;VU@iE+Pv z=4*Z$Wu%H>rGnCw_=<)5hp|8i%79e(Lf8CDws_wFzxLP~IXL7`Yfg6K@pkHekorZV zA^VHNK!t;*rtCvvs}+fNuF`$}28Zau3=0**haN<@|My_CK=$n&Bt4DEfXm_T2NGYU z*GZ66z#y)3B)5z3fdk}1b*&K2QBa;>scyi(9NY3E%p85~%?Rg})PJk*{UKH_hiSF1 z&)q_?q{pzxHd)fZaJIXF7%bE&`%S5sraE#{cU90xSVP#@m?{9y>bOp{yW%XHtwbj0YIpcx*S0NVi&u? z_2YrX2paZ|X0$i_%pI)(EPks8Trcoc$#BUFlB+5?90HsFsSmWha}uHyadB*9e0!t9 zSvc`kE5^mlmMkJy^wl1qUty)xnJY*tc)L4V(>3}_{GX06T^wZS*WKw>G!-pK=53Jq zVxb@oj7fg*X@8)!hBJWdSR#l5BaxJHd(AKji}Y#q36fq{r+>6H511L-8@gED8Av$^ z3NWenssrweJk{sjas>dACc{N;>G<_=B*y#7q|tsYD<^}bwH`*1-;%;lx@LvE0Ucq6VzYv_R-_;xZB{3k!BhJ)9LURcC^$H%hh{!=-LDg99Y4Y9OxNjJyDOPjZ z^C|&ROh{J*q-C5-h=!%{*FpeVPEgJFBR`Ta)f841WjO z6!T8;AvI#8^Rump-s2M@^I1d1iseodIF)nBr`FqAdfnzZ*{h=Hn;0EC$2D;b zzT1APeI7o`?vHaUJgkWA(wO6eN~H_O2)=Y4^3F&4tl4&|k3Qx8wMD$HI+fFIK^fsF zyB3{k`ST(6$@r+6(mjw9jf2b$u|uo_oCXb9N*Xhc>(}cDlCP>g8Qn9A+6G_Zr*807 zl!Sd?DSiJ5rS;w_EHKdL#r=J5H}5Zk6e#%2Ams0)++cqQ72w?;Te7wFmYAOPDuhptiybEA~3e0ua-q?Ic?nCLp}G1p&4OqLlLoDLbQkO`a&f z!-eIV8&w;nYjt&X%ceiagRG=K=NYX|`ZY#ft`;Yhm!CVTer!M55L!Q8JKlS|bChY~ zK81HglY7g}^TYQaJS?A*>wL9Msah$L`dSJl_;KXxP{gnKf5o1UU9;Z&$7m$XuWO0u zw5YyzXqV81Ni@m2RiuYe+`IB$=)@jtM^SnLa2Ll0K?PWPzUVeh-B!uN9b1n$a(}L` zd&~Q^T;NJ|g%McgVx^=+l)%>FbW6zTv3Za=8iWu+VJHNrQKc9lCY2`>tAWdcsu}Kn zOxxY!qv(tmgR`fxb}7Fz3JVFTP%NF%ZIB`+m74prkJ@Kgp1A0kyv1k}5Z0i|0Fb~V zVOoss{lEJu2S@I}$VTj(njd^)9IuT2ruV^tm z?;&Y6oP4rZUp4C)D1c%J-y6-SvWsZkc$0Qpon0?W*D8NTY0XTo_h8?`CCu7z$*tcog4jkSW6H%$~>Ib{_=7L2+~2lM$PjlHEzWBzA6=a=4WT3eR1!Z z0k_!kOFa%iT^&#RNlk*vd3z<;-gH{Et?Pt%Zgg>6$3uAV5DH17M@GCt4Ahx2+{6|D zFOv!;6)-Ckkx2-bcz=af51%HHd95N<` zZ7bSXv9vVE9Au(i`wY?Tx8v{|^OhR$m;DEZE;U6Q^h=*(*TLr6bxkc)Kodp;7;d<| z;TjStV40fu?KZ&4ib~L8I45fm-y$-ufz4c59y~b+uxbxK4K}2IFjic`Y1Fpm(OT?? zP%T7Zqg@G5G48<<%86IMve(;X)U$ZrwRoDKC7r*b#A1vy*u0T{xv;fmXuMV7?p~DM zyk5SDKe?c|QfaF=iKtMkZ}(gI=g-d{!NWq(tqL0{djS!Fth~0HYr$=85p60q;D!gi zCVhe>i6&|v%>Dx`xiNzl;<|50<%y+<)ug18Is=vB!}_j7Q?&IT3AR_V92y1z1UMkB z3v(CU$(YFp`3Q2+xwM_Vw5U~4R(iT3;L9*bK){6s zJ^vG+7F|XPzm8R{cvu_QQ~Bijyp`1WST0LK02fz>4|QOEaTj^>MbBZCkr6m>YMS#I zc`S6@wme=d&K8&3Bft?$qsiwuhr;>AV30fm95$|bj})!}h|%m@%9`GSmLdQoQopNF z&Q*&y8VF*7FkKJM+~$jvKcB-#4C3N!D?C{sw0>o-twx{HZe5!%kl4(Ggui7Vq3aU} zxL-T-!J$!q5=KiY`0j_B4>QeGTy;eLy4wzo)sZ)I#(R3`kP?TBYXLLabWmT9N~YZE z=KMO>gCM(`lqNK8Ps(73R5?pf@v3FPD-OJil+QO@VTF9Hq>N_ew}opOoAO{|ms%da z+27tC%|F}WBN5Mb7mdK<lB5q|uv$PRK(;lNU zxb$~RRABf$Ng~^ltL)bsk75!r)Gn;i^Q*M|-`2+8W7-I|bH_Ua=9H)3dQlS<8ork? z6?D%8bbp1YGY~xz3(!HB#NbOc|B_oo_n0BYMLF&s=U?lJKjv|--(4xT5mravN0(Gu z)1(vT11=AQj1Jvt=iG+xQ8zW!@wzYC@HV}9NAT|{_{<)T=G{|8h)@S6Wi)}$I=(RM z|2hkKl1Ue_2LH}+uL;2IHS|lBnZHscTqlb3AsrEl$2h6h@~nq4^j&>kw^fL%QY193 z9t1~*h7LR#+Oo4FOiwFE-MgdZIW<*c{}rw5vWvV*nr!rh`%TvMB%CfTMm#aut0f~E z$0prJy{z#_a zkoTj3Fn#KlQ~bM5@{ODIxXVO)$f=Nug0ix*Qfu&qP5m|fy)!yDyJ>;fEH{3BOQnM{ zT+Q%g;p{Rxgn<`CIFy)_wMW>T`bF!^B%LuxCsfNV%O6RP3I<$0>q9OQ;`%PZl|=H+ zz+;M^ynUf{`BZ5pzn(I=mWIKGp#y1e@#@1Je>ecHr5QI4;%8w0LIjB@lRTWj)Xq~w zL=3Q>iHBf0&_tf(9M0VvJaHX}wzOcdEu@lqa#dg7{#S)&>Mii3LX#cxuNV@Vd<#XR zjbVezeilWj>utHmnlD!>o-_coUVMR4F&%=9pRWEJx^Z$&n)BM7RD1NhA$j|BF{l0P z#n40Y@vrssdFI{dz8dDRw6BwR`-?N6O>EWgybMBH|AETM>Ffm4&`F&M$FvnO4mDLr z83J0dk2uzVy~zcM`zlwJ_^D&|2yFXfs@tXr?EfdIMaA~qt; zoO+0eKHRU;*5Ux~3?in z3L}&EX!(X2t|#5Hk^yu%Y(8kN-FjA}Z;qFuh8y<@KTb=hfjr<5#;5HggneCqs#qx*(+foX?svfSQN?t{>SmjJ zKu^D0zTdsg(YeR@`M}ef8#47nc5ft%iqeItcc*7+!fr$jhS8M zI;irKJw)yq#LLQ%4~^D8)y?|$F284BSZ|%3nGrA9BrEtew?#m`YS*^5XgPq1F2*%7 z-lXwK+ATMat5{%Ttvsdn0C6`2vL%IV2S9qCrWVp;yHo?Ytg$}+pJ!C#gkK{PU7Q7l z9Mv=z7~6^Jk~_`)g=IZxl@poE`ug^xUYn0fXRA8{Mq~J$`L(0b4DjB?zk}od(z|x% z_d>%{Aep-@8!RJD%DwyCN4iTbJhOE@CFzcKUc~BKN5^Mz-MQ6VVju?73T<~y>n>gm zzpRWLw=AGo+7eDqQ0+b)+=w$UCIgN)N- zrlMkID2%{HGSHl4dxbzVwHh7~gLj@@`BcFQ^EI`u9~=F{-z$_Ken#NCh%G-4j|`ov z5b^)9MkI8ZIE0YTXJ;v}#}u#hU(!W6hop-I(&ab4@TfQDXz=B(R!=R5K&5q5qY9Wry(d zKIaoF_B<&i>p32qtJ_c#U||oSm|8+Ji2++MRGXs$Z=?j(SMp)1&r4wJ&F$d(N0P<%=cz z^H=Rh8J9Pvl7B_|8unQ6CW9&e-Xo&z<^0}C$Ymnu?kA4JF+uN#R0(8cMTiDHHlzLy1~V z^X&V*Eg3fn&(?|*(rm=R-r;S0b-VA%>1qADb+7u_&0i*X_wd7BFs1Fi_|+O|bW2p_ zWL_mSyo^Z8j~-8$y(~P>8LGo)&9+8G%~;{}@+Rs^DT@9uqtlG{lfema*3{%A^{F%mbJCTyAge ziMHt{Rvny9O+8L}^V?aSW6rU7Z#}R9O6Q~xioIt zv$XdAx(vb*K-)O2Swo+evpebyK9>{i7nGSF3akTUx}|&^>9M)C^MFTumR-h@274N$ zFOuaOd64Eg6?AsIE*eQuG~QCaw^6&CTA`%7@Rq2tF`53xacN9yk@wV?yfO2k!>&WZ zm74SrnLB#Ajp=fmLCqn$I>o{-*t9-(AmIqmZy!dX1dw-yoA_-pjHbZ{Q`5?LmudwoGZ>5 z4^^It%JRRU^sc5>MBC2xhVFf+__lLVq1f|ysJ*U$_lPfyA? z-`d{ZUp7x5sP66`ugh?L(e@K^7DqpP+vk}Dro7#nd(YDS9v$7>Bs=!u1n(rMuZJot zOO(})J+Q<&PY$k_GReJj9=wtWymE`)w=b!SFIZ0ct_kA3ecw25h%g^AgzuR*Wq*{{ zBcntn>Nw+aE8nZ<^!Vh%;-WQL$VALPVeOxWh(hnDbq~fBDJ=oG)tlvpe zK49zkVFMqg?jKczOb?(2!X*6zxgsMt`J!-)XTjm}kF+h@g52P1Y zBvvj_10EU&zj!a;^gwP|;V96E z;px=M{GX@IQK5>2_K=I+4>$(3C|}#ioo#atcY*)z;Mm^-=zleugAk6r3x;0epNffQ zx^5M~g_ez7#e|+w%5oK@>d>Nnd#}2j;@%ylTUbraozSa&gDm@w~MMZcb-Q6h8K|}pN z*uAK*bHK!p>DW-heprnMLiJXB(Yu zC$#_yAmVdq%Yj93T4U+u#$LT5nG_NJYj|{FXMX2~eOuJ0;MQ6DO`|6f;(;* z8#`@DH&Quw&hDFdnw{~EmBb}ot_#t~&JmvXa6qjs%87^QP{|CGh-r(;i2m9kuC)b|_tXZ7LxAx=&k zSdL%NMc<^yBTq6KfHa(hmv&|4cE#XhyNA*MW5%MiB?ucF`+D@@vEQ-8-l*>QMKlIpZxJ-!xc4-PgZ!@P1*9(3?!Y?6l z@-P@=)vhYjYrX|iJx$IOu$ywdgH77mcRKD}ba~5L=psj4c-`FffWv4=l>3p!PH(l& za~L?47i47dgnof(JlaKCDc3fo1q z&n_!TiJ)N|KSoOQ=7$Flm~-bQCieF?_8laUzLjON1~S&P&--?LNMmnD<|}%a3UW6z ze5vH65(=MkwZ2v^Ddd~9c&H(6#{V~Us+Q|KZ^1JEr%beKc(ioY4WahqD*N+)U@-6C z(f4}Imkyg70c~&Zu8)pw@+75rEwO#CWo2zNAcMLooe(K~;`a7I0@!tLO-h;t`q($` zwTtbYcz8$fm-z|5F!@il2h+i@`2u=1ecc1n<6(}jnXgAe%?BQmE9_C>cMn( zy#HSS3l{Y09D)Lb2AB*IkQ0E05s68JMb&|o=T@<`{&s_=zbHCk%icfhIKJPO3Rxeu zTRdvhHLs***fw;0VLmu%9?hy8w&c#=ymK%f7pqOPWn!DI>g4{(xi~2@dh*#xo~Prz z(Y9LdA093@^7*5)@rz?+4T&tRmdn!xoUhGjl^nd z2yN0h-qe*77>&mVH*XF04sP5$x^Z+n8|+2JXz%cFI2xyM7DYC)V#xD^boUclP7DZR zZb|?N%z`Q|PhQj>6jmZ45<&s|LZ0&Hv}XSt`Om-q&wu^5pa1;b&tJQHFxj8{@&1gN zp`zpS?P68!9p1Ws&Xsk8EaQ6PFeP!@Z6#t%6dy0s-+uli#_Fv*c}xviFle*k!M5HC zWc6zK=w$xzcs5({VpR#n#f@9VaFk|c6ereNWw11cfQ*7t9R$b1%wU)u1F*1Y8DT_R z#6b=QJo^=>#gboYCuKzQlP~^5?enR3aejeOM+FcBfe=_F!vGK@-n!NN3_kp1_PY;G zPZy3%Qm^Kc2;g|#7&3N)@uQjh_|e()Z1K{qygvI=vzd*`crqzhEBfs8$tg6iy?sPc z{PN3p?!0h#viPLTaIsjr_@>FyfrF!)N1yE*H|;^P|@<=fBoxU{Q9@m*1htRBc$YiKdZLY;zn98*A-Hx$yjYBk#2_)HI7BA3I+gSk;XZz`&tYjLPkJHz_I8yjL*wZTDbxWWwXXM z(v=?)JNWd` z;%v$D`6@Qi(cuucvpk{oVlHkwIk@@9kKSLeSIOVK8YOmrl>Ecr|LxiAV!o#JdiiKp zy>K*QYVN-LqKnIqKKS$LlP8PCysFmKraEU%vkcKFx1ugHyCem`L6O$%E-seV#7!f$ z(08%sn848RU0 z?E34FJ)yNGvIdDjfQSM}tc8Z}0EGJwB4|mV4T}h*Ms2{Lm~YgGzaZ0i^ziX7|NY&w zC$pda^{a2cac{A7r_(jKRR)s8hLVv)!})w^O*5S@t*Z^2Mj{82m^vP*; zf$zM2JEs&NT3@VeoK$r^ov#>eoD@l!uVj_wWnPX6#RI8ijNS%8L9l)th(S;npd#)< zh*8>nwREM<7C=Fvjay(nt z4qv)=_xN;na&p3K*7f$I2U9q%8#7qfC}83&DJT{l~TZ^4$+EI66M7K7O=5I^4f;`(XUSn=ifo_UwE*pPkQV=bP1{s;X+e z*{m+A&8n$cS6M{}FpaZGR*sXr93R|#p%^FmV6=Zw3`c2RWLchOd6L9Y6d9|s+e+K$ z$03MN*ONU55->O*1$Bb5wg9M9QWP0Osw0nD#USWAQ6B;R1|s;5lL=ra5rHv?1_p6Hi>b>`dvkPf zb2u4iX+{8Pk`_q{q=laW=mcOSFiW=V^gaz>AWbyDk57bx1dXsqg*0}@gX^X!!! z%8LfTqT~;NpbC3h28sn_1_TjlkO&wW+r0G38|UW-=cmU-ULB0bQr9blwMh}2g{^Gn zOtF~AAf7ya@?j)LhkLX2>cjgd%Z)1sV`iCMY=86n2i0no7x{Wiwm7`=@~vA(H}2iJ zy?66goDOWHD)knLbixd<)!@?xr3%aGq&z8OIj|rgD?OYa9rSZ7E%l-QyKm}u+$`c7 zOrrOj0KI;UZ{ndfNMwx8exnN0``Nj!%ZC~m)w8SN>vaPXST+2wJ{kACzB$Q@H{N`! z91j2cKjiGed-Ih$TdbY%WK;mJi!!@;bmP7EKRuZ)BsTATay%QS2jlEum{r^4qS|bi zXA#l3%;#H3(=1K%{k_AxckdqEx^sB@?*5JayeQ&0F=V4CvWAT4E;M;84Ar=lMnS}@ zAO-INEJ7Fr6*V8A;IOrLYuihHlsN#NL7h>foapZY5dx(N(1&8A1^-p_5da}3QyXJc zpp6Kvv5`&UI2jBFo8@wOaj~t|uHMw!YFkUqjesKqXJ=E!c-yc+J09j)QI3bBy}e1E zr*kf|^5}4QaP!S_Fc=L+gCb3nI6-ScHIn^&l)_!2j?W)W3PWcMqS*o>k#3YD7~=tR zWcF<2y8}4r@22_!!Z7CIN3qCHWNGnBXb6dvql-ERq1A^8-W@1B22f!tB44WL$_@#A zJ2w1GYeoS^*f6k(lkwf^(G=r@Jb8RJpFKRD-I^pv_wLLtwx2#Y7baI%AAkJ$lOiw6 z?Dma4rBE0gzMkfz7Y7rv`FL+{Z@jm^zdss}i*k@;X=JSiH6cJW1~DQ55N64$VO05ltK!?pbE^ib)K&|m8nM$h{`5J zY?zZQFGgc&ZXDLzx~?|sYF%ws+tqrxTvnUqcD>rHH=FfpwOI>G6d6Q7uzxtO6p`#7>GT8R5*J&(C6<1fMRYmQVxw@hc@CH(q;Q%Vp2n9|YFGqa5A=BO;)}a9{xO z+csoxx+2%k&|PfZ{YQ^Z9zU3$ot_;(eDLt$^n5DphIw2h(PBQI&M(##FSoUg;yf=0 zgTZjJm*?fMDD&YU&jxu}rdb-ru`$*dL{a?%P_6=TAX*%2lg{4{0<|blT6h&AB6uf+Ue?_2Q+fnie_XYMlsI1lum>+7s7~vt_TLUI2;Ht|hUqU6VRpjI z4xDS8bB)u&6v-F^1XciujE$1WT4RlgVoPYzv%iP{3ju;9Mg+&m?BOkGE7Pv1^;RV8 zrA9&zf+5@o&2H7x5)fy48IQA(rtJp2PKX=mU}ML+;+2nnq<)>v%mGsB7TTDqvo zi_bA6WG;k)VTtwG3##9uH3PtWT|JpC>Ut}#sq1=MH;rTG95^Sg(NPEGpVt+zD6-Z@ zQDnpM)!`YPk75A!keRYbvbLg$0SLhos$R1aNGe9;MJ+sYZ+Ma_*rnB<1oOo%@6#vB zpk-XJc<5c(NrwtpQ%r0KI**yip$h2&jml*K$B`ezx4V9Ers59Rd+4Q_w|by*!D76K#BCA<)!xtaog;~AO`GrMYXJD z*rgQGu{Oml!vb}ihxk03boC6$TC}7M#Bf=`*Aw^z9;sK_ppX}j|BLwKr)3)YL|LQ( zK$~PHMwF)EhJC{wMYR5PDi8wRry;Uu$#S~vsAN}yDjyG?M$d}}=%zKGWgr8D1dObD zN#a*fpryXO_Y=sz+ltIF~O%$#25v3MH00LICP?JTYuGtIr zf#-l#XD2>~0QUW%P~o<*$=jm`$^jV}$$!|ciuOCB%9`BXZt=>0DgkH=7(<4Pr%qNZ z!vl3%1^Q7w^seTL9?5rQ&De1z5)dJ<5flT;K0)YfUH~zOt`QaRLSpS|B7#`sz=#tC z%ZzV$`cY2xOhSf*S-_H(97<#zV4qG)piLe69gGmRkUE6l$C;jgMqlZ9^YLNR1A1aw zUl-1a#>0>%Yuy=$-~a`{0E6fT3#()7Jh*qzZGPC2r74-UT1L1!l|uEgS-dkKb&(88 zcq>5AbGM!}Q;Ss+1OP@33E9rHyGV;f_!A~tfB9qRS4jc8ZT@z2GqglRxn8|*CNkt% z#Hpq2B+&5z6(gZw63`oof$K!j{?b*TmiI|So0>FXum)Ktr7+NsisnXQ1dRdXI}$n( zga(mO3<&Cp7Z#Na7O!j20>b3wF#t(@83tL_5CVO4)tG>7rK3ONi@)HzA((*2Hl*(_ zLzdmbd>SeRd{r27J@iAT9hxU$V1rNy$PzPP!`+ip|LL9Du3sSZiMw~&LI6NQmY8&| z2-@*eAQat$@q9np+QA+U(WbN@q+JMY<$Fh>V!5<4jxwmOrULQjalSHsRGFCPriS|(n(~5O1)LlZv8ZdCX2^QA!H%Y z&JF-{BXYqvDFWx$O2p$NJK!`x&sn#hx1ht)!0qADUW16f!gk?-Fl3_Yf3wrpFe$3?30Rx%G`6{VrBSvO~W@-rSB10t;)+xbu~EvD70-`g3Hk zMZuQkV$;-43o5VQgGX?VZJT|mN+{UN9-c?(hWTuU#UwO|DJqS2oX2$)s- z3bF6DrLBkjW=W@YA?>3M#rqCnHHcA~so;Ng3BZUTh!f;qlxSuCG>ot()%H>=4U3O{ znv07x4BDFWQ&8Ab{0K`(;1h*bGq1Jz7G_t!AT3M*yKAI~T{9^lG=!cGE&N>zKvXt4 zh28=J-T9F3*nGdNZ`Mb*uDPmNJMpT#hkt1mQpJCwpBK?0-7A zKZHvQHJax7awOP8hri)^bEe_Kcf+ThZL9rghLi1j!7`b>gNw^Q0} z+U1>sA1nd{LJ%@7{MqfV>)(x^$MKc)t(*+a-A zDR_@ysQNwP*kkYDopOhqhks6jz+ea2LzuqwaWk;E$Wz?Gjz#;9A6$JkJx{yyE;J5X zu=jeT^RnTJ75u^8h4n&O`=YR4EbnGzmu_l{ zCsF_*d%I)p&br?$qaT7Pe<|M#UFhsNA-U=ad?1#-ok&2?yymEMUjXQPJnYz6I`WDu z?>aMmx~m8#1t4&}TfWw0eTVLnla_0e=l-_@7!Cz49nGNY7?SuFJqh&y`2I@!itw_h zm7UYwwzfk1um5U$V9Yg-=F&|JC#TJlLz0fz&DLv+ugjhOUs*GB(>~a5m|b>@(szKJ zTi)@+y*SyX7yx+rcV6|!{Z7es!2I(0WCpYHzvV&7DE zjJEI2chj3o?+|ukNsGB-NclQsS$f&VB{Jk)0+;r)!J6R*_V#tG`ODb4$Q7L6%Ewm> z`x*!npTDIf&pwKmlLvX~w@Ux$$rT5<WM literal 0 HcmV?d00001 diff --git a/src/main/webapp/images/springsource-logo.png b/src/main/webapp/images/springsource-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e170f8abf778b24ed1de11dad6f1444e849269ba GIT binary patch literal 4974 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 WST*12Q+YoC0000 + * Base class for {@link Clinic} integration tests. + *

    + *

    + * "AbstractClinicTests-context.xml" declares a common + * {@link javax.sql.DataSource DataSource}. Subclasses should specify + * additional context locations which declare a + * {@link org.springframework.transaction.PlatformTransactionManager PlatformTransactionManager} + * and a concrete implementation of {@link Clinic}. + *

    + *

    + * This class extends {@link AbstractTransactionalJUnit4SpringContextTests}, + * one of the valuable testing support classes provided by the + * Spring TestContext Framework found in the + * org.springframework.test.context package. The + * annotation-driven configuration used here represents best practice for + * integration tests with Spring. Note, however, that + * AbstractTransactionalJUnit4SpringContextTests serves only as a convenience + * for extension. For example, if you do not wish for your test classes to be + * tied to a Spring-specific class hierarchy, you may configure your tests with + * annotations such as {@link ContextConfiguration @ContextConfiguration}, + * {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}, + * {@link org.springframework.transaction.annotation.Transactional @Transactional}, + * etc. + *

    + *

    + * AbstractClinicTests and its subclasses benefit from the following services + * provided by the Spring TestContext Framework: + *

    + *
      + *
    • Spring IoC container caching which spares us + * unnecessary set up time between test execution.
    • + *
    • Dependency Injection of test fixture instances, + * meaning that we don't need to perform application context lookups. See the + * use of {@link Autowired @Autowired} on the clinic instance + * variable, which uses autowiring by type. As an alternative, we + * could annotate clinic with + * {@link javax.annotation.Resource @Resource} to achieve dependency injection + * by name. + * (see: {@link ContextConfiguration @ContextConfiguration}, + * {@link org.springframework.test.context.support.DependencyInjectionTestExecutionListener DependencyInjectionTestExecutionListener})
    • + *
    • Transaction management, meaning each test method is + * executed in its own transaction, which is automatically rolled back by + * default. Thus, even if tests insert or otherwise change database state, there + * is no need for a teardown or cleanup script. + * (see: {@link org.springframework.test.context.transaction.TransactionConfiguration @TransactionConfiguration}, + * {@link org.springframework.transaction.annotation.Transactional @Transactional}, + * {@link org.springframework.test.context.transaction.TransactionalTestExecutionListener TransactionalTestExecutionListener})
    • + *
    • Useful inherited protected fields, such as a + * {@link org.springframework.jdbc.core.simple.SimpleJdbcTemplate SimpleJdbcTemplate} + * that can be used to verify database state after test operations or to verify + * the results of queries performed by application code. An + * {@link org.springframework.context.ApplicationContext ApplicationContext} is + * also inherited and can be used for explicit bean lookup if necessary. + * (see: {@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests AbstractJUnit4SpringContextTests}, + * {@link AbstractTransactionalJUnit4SpringContextTests})
    • + *
    + *

    + * The Spring TestContext Framework and related unit and integration testing + * support classes are shipped in spring-test.jar. + *

    + * + * @author Ken Krebs + * @author Rod Johnson + * @author Juergen Hoeller + * @author Sam Brannen + */ +@ContextConfiguration +public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4SpringContextTests { + + @Autowired + protected Clinic clinic; + + + @Test + public void getVets() { + Collection vets = this.clinic.getVets(); + // Use the inherited countRowsInTable() convenience method (from + // AbstractTransactionalJUnit4SpringContextTests) to verify the results. + assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("VETS"), vets.size()); + Vet v1 = EntityUtils.getById(vets, Vet.class, 2); + assertEquals("Leary", v1.getLastName()); + assertEquals(1, v1.getNrOfSpecialties()); + assertEquals("radiology", (v1.getSpecialties().get(0)).getName()); + Vet v2 = EntityUtils.getById(vets, Vet.class, 3); + assertEquals("Douglas", v2.getLastName()); + assertEquals(2, v2.getNrOfSpecialties()); + assertEquals("dentistry", (v2.getSpecialties().get(0)).getName()); + assertEquals("surgery", (v2.getSpecialties().get(1)).getName()); + } + + @Test + public void getPetTypes() { + Collection petTypes = this.clinic.getPetTypes(); + assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("TYPES"), + petTypes.size()); + PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1); + assertEquals("cat", t1.getName()); + PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4); + assertEquals("snake", t4.getName()); + } + + @Test + public void findOwners() { + Collection owners = this.clinic.findOwners("Davis"); + assertEquals(2, owners.size()); + owners = this.clinic.findOwners("Daviss"); + assertEquals(0, owners.size()); + } + + @Test + public void loadOwner() { + Owner o1 = this.clinic.loadOwner(1); + assertTrue(o1.getLastName().startsWith("Franklin")); + Owner o10 = this.clinic.loadOwner(10); + assertEquals("Carlos", o10.getFirstName()); + + // XXX: Add programmatic support for ending transactions with the + // TestContext Framework. + + // Check lazy loading, by ending the transaction: + // endTransaction(); + + // Now Owners are "disconnected" from the data store. + // We might need to touch this collection if we switched to lazy loading + // in mapping files, but this test would pick this up. + o1.getPets(); + } + + @Test + public void insertOwner() { + Collection owners = this.clinic.findOwners("Schultz"); + int found = owners.size(); + Owner owner = new Owner(); + owner.setLastName("Schultz"); + this.clinic.storeOwner(owner); + // assertTrue(!owner.isNew()); -- NOT TRUE FOR TOPLINK (before commit) + owners = this.clinic.findOwners("Schultz"); + assertEquals("Verifying number of owners after inserting a new one.", found + 1, owners.size()); + } + + @Test + public void updateOwner() throws Exception { + Owner o1 = this.clinic.loadOwner(1); + String old = o1.getLastName(); + o1.setLastName(old + "X"); + this.clinic.storeOwner(o1); + o1 = this.clinic.loadOwner(1); + assertEquals(old + "X", o1.getLastName()); + } + + @Test + public void loadPet() { + Collection types = this.clinic.getPetTypes(); + Pet p7 = this.clinic.loadPet(7); + assertTrue(p7.getName().startsWith("Samantha")); + assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId()); + assertEquals("Jean", p7.getOwner().getFirstName()); + Pet p6 = this.clinic.loadPet(6); + assertEquals("George", p6.getName()); + assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId()); + assertEquals("Peter", p6.getOwner().getFirstName()); + } + + @Test + public void insertPet() { + Owner o6 = this.clinic.loadOwner(6); + int found = o6.getPets().size(); + Pet pet = new Pet(); + pet.setName("bowser"); + Collection types = this.clinic.getPetTypes(); + pet.setType(EntityUtils.getById(types, PetType.class, 2)); + pet.setBirthDate(new Date()); + o6.addPet(pet); + assertEquals(found + 1, o6.getPets().size()); + // both storePet and storeOwner are necessary to cover all ORM tools + this.clinic.storePet(pet); + this.clinic.storeOwner(o6); + // assertTrue(!pet.isNew()); -- NOT TRUE FOR TOPLINK (before commit) + o6 = this.clinic.loadOwner(6); + assertEquals(found + 1, o6.getPets().size()); + } + + @Test + public void updatePet() throws Exception { + Pet p7 = this.clinic.loadPet(7); + String old = p7.getName(); + p7.setName(old + "X"); + this.clinic.storePet(p7); + p7 = this.clinic.loadPet(7); + assertEquals(old + "X", p7.getName()); + } + + @Test + public void insertVisit() { + Pet p7 = this.clinic.loadPet(7); + int found = p7.getVisits().size(); + Visit visit = new Visit(); + p7.addVisit(visit); + visit.setDescription("test"); + // both storeVisit and storePet are necessary to cover all ORM tools + this.clinic.storeVisit(visit); + this.clinic.storePet(p7); + // assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit) + p7 = this.clinic.loadPet(7); + assertEquals(found + 1, p7.getVisits().size()); + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/OwnerTests.java b/src/test/java/org/springframework/samples/petclinic/OwnerTests.java new file mode 100644 index 000000000..84b5f62c6 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/OwnerTests.java @@ -0,0 +1,27 @@ +package org.springframework.samples.petclinic; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +/** + * JUnit test for the {@link Owner} class. + * + * @author Ken Krebs + */ +public class OwnerTests { + + @Test + public void testHasPet() { + Owner owner = new Owner(); + Pet fido = new Pet(); + fido.setName("Fido"); + assertNull(owner.getPet("Fido")); + assertNull(owner.getPet("fido")); + owner.addPet(fido); + assertEquals(fido, owner.getPet("Fido")); + assertEquals(fido, owner.getPet("fido")); + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java b/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java new file mode 100644 index 000000000..d56199399 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java @@ -0,0 +1,29 @@ +package org.springframework.samples.petclinic; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.springframework.samples.petclinic.hibernate.HibernateClinicTests; +import org.springframework.samples.petclinic.jdbc.SimpleJdbcClinicTests; +import org.springframework.samples.petclinic.jpa.EntityManagerClinicTests; +import org.springframework.samples.petclinic.jpa.HibernateEntityManagerClinicTests; +import org.springframework.samples.petclinic.jpa.OpenJpaEntityManagerClinicTests; +import org.springframework.samples.petclinic.web.VisitsAtomViewTest; + +/** + * JUnit 4 based test suite for all PetClinic tests. + * + * @author Sam Brannen + */ +@RunWith(Suite.class) +@SuiteClasses({ + OwnerTests.class, + SimpleJdbcClinicTests.class, + HibernateClinicTests.class, + EntityManagerClinicTests.class, + HibernateEntityManagerClinicTests.class, + OpenJpaEntityManagerClinicTests.class, + VisitsAtomViewTest.class +}) +public class PetClinicTestSuite { +} diff --git a/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java new file mode 100644 index 000000000..3c275c820 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java @@ -0,0 +1,20 @@ +package org.springframework.samples.petclinic.hibernate; + +import org.springframework.samples.petclinic.AbstractClinicTests; +import org.springframework.test.context.ContextConfiguration; + +/** + *

    + * Integration tests for the {@link HibernateClinic} implementation. + *

    + *

    + * "HibernateClinicTests-context.xml" determines the actual beans to test. + *

    + * + * @author Juergen Hoeller + * @author Sam Brannen + */ +@ContextConfiguration +public class HibernateClinicTests extends AbstractClinicTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java new file mode 100644 index 000000000..709100d1a --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java @@ -0,0 +1,19 @@ +package org.springframework.samples.petclinic.jdbc; + +import org.springframework.samples.petclinic.AbstractClinicTests; +import org.springframework.test.context.ContextConfiguration; + +/** + *

    + * Integration tests for the {@link SimpleJdbcClinic} implementation. + *

    + *

    + * "SimpleJdbcClinicTests-context.xml" determines the actual beans to test. + *

    + * + * @author Thomas Risberg + */ +@ContextConfiguration +public class SimpleJdbcClinicTests extends AbstractClinicTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java new file mode 100644 index 000000000..251af819d --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java @@ -0,0 +1,199 @@ + +package org.springframework.samples.petclinic.jpa; + +import java.util.Collection; +import java.util.Date; + +import javax.persistence.EntityManager; + +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.springframework.samples.petclinic.Clinic; +import org.springframework.samples.petclinic.Owner; +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.Vet; +import org.springframework.samples.petclinic.Visit; +import org.springframework.samples.petclinic.util.EntityUtils; +import org.springframework.test.annotation.ExpectedException; +import org.springframework.test.jpa.AbstractJpaTests; + +/** + *

    + * This class extends {@link AbstractJpaTests}, one of the valuable test + * superclasses provided in the org.springframework.test package. + * This represents best practice for integration tests with Spring for JPA based + * tests which require shadow class loading. For all other types of + * integration testing, the Spring TestContext Framework is + * preferred. + *

    + *

    + * AbstractJpaTests and its superclasses provide the following services: + *

      + *
    • Injects test dependencies, meaning that we don't need to perform + * application context lookups. See the setClinic() method. Injection uses + * autowiring by type.
    • + *
    • Executes each test method in its own transaction, which is automatically + * rolled back by default. This means that even if tests insert or otherwise + * change database state, there is no need for a teardown or cleanup script.
    • + *
    • Provides useful inherited protected fields, such as a + * {@link SimpleJdbcTemplate} that can be used to verify database state after + * test operations, or verify the results of queries performed by application + * code. Alternatively, you can use protected convenience methods such as + * {@link #countRowsInTable(String)}, {@link #deleteFromTables(String[])}, + * etc. An ApplicationContext is also inherited, and can be used for explicit + * lookup if necessary.
    • + *
    + *

    + * {@link AbstractJpaTests} and related classes are shipped in + * spring-test.jar. + *

    + * + * @author Rod Johnson + * @author Sam Brannen + * @see AbstractJpaTests + */ +public abstract class AbstractJpaClinicTests extends AbstractJpaTests { + + protected Clinic clinic; + + + /** + * This method is provided to set the Clinic instance being tested by the + * Dependency Injection injection behaviour of the superclass from the + * org.springframework.test package. + * + * @param clinic clinic to test + */ + public void setClinic(Clinic clinic) { + this.clinic = clinic; + } + + @ExpectedException(IllegalArgumentException.class) + public void testBogusJpql() { + this.sharedEntityManager.createQuery("SELECT RUBBISH FROM RUBBISH HEAP").executeUpdate(); + } + + public void testApplicationManaged() { + EntityManager appManaged = this.entityManagerFactory.createEntityManager(); + appManaged.joinTransaction(); + } + + public void testGetVets() { + Collection vets = this.clinic.getVets(); + // Use the inherited countRowsInTable() convenience method (from + // AbstractTransactionalDataSourceSpringContextTests) to verify the + // results. + assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("VETS"), vets.size()); + Vet v1 = EntityUtils.getById(vets, Vet.class, 2); + assertEquals("Leary", v1.getLastName()); + assertEquals(1, v1.getNrOfSpecialties()); + assertEquals("radiology", (v1.getSpecialties().get(0)).getName()); + Vet v2 = EntityUtils.getById(vets, Vet.class, 3); + assertEquals("Douglas", v2.getLastName()); + assertEquals(2, v2.getNrOfSpecialties()); + assertEquals("dentistry", (v2.getSpecialties().get(0)).getName()); + assertEquals("surgery", (v2.getSpecialties().get(1)).getName()); + } + + public void testGetPetTypes() { + Collection petTypes = this.clinic.getPetTypes(); + assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("TYPES"), + petTypes.size()); + PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1); + assertEquals("cat", t1.getName()); + PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4); + assertEquals("snake", t4.getName()); + } + + public void testFindOwners() { + Collection owners = this.clinic.findOwners("Davis"); + assertEquals(2, owners.size()); + owners = this.clinic.findOwners("Daviss"); + assertEquals(0, owners.size()); + } + + public void testLoadOwner() { + Owner o1 = this.clinic.loadOwner(1); + assertTrue(o1.getLastName().startsWith("Franklin")); + Owner o10 = this.clinic.loadOwner(10); + assertEquals("Carlos", o10.getFirstName()); + + // Check lazy loading, by ending the transaction + endTransaction(); + + // Now Owners are "disconnected" from the data store. + // We might need to touch this collection if we switched to lazy loading + // in mapping files, but this test would pick this up. + o1.getPets(); + } + + public void testInsertOwner() { + Collection owners = this.clinic.findOwners("Schultz"); + int found = owners.size(); + Owner owner = new Owner(); + owner.setLastName("Schultz"); + this.clinic.storeOwner(owner); + // assertTrue(!owner.isNew()); -- NOT TRUE FOR TOPLINK (before commit) + owners = this.clinic.findOwners("Schultz"); + assertEquals(found + 1, owners.size()); + } + + public void testUpdateOwner() throws Exception { + Owner o1 = this.clinic.loadOwner(1); + String old = o1.getLastName(); + o1.setLastName(old + "X"); + this.clinic.storeOwner(o1); + o1 = this.clinic.loadOwner(1); + assertEquals(old + "X", o1.getLastName()); + } + + public void testLoadPet() { + Collection types = this.clinic.getPetTypes(); + Pet p7 = this.clinic.loadPet(7); + assertTrue(p7.getName().startsWith("Samantha")); + assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId()); + assertEquals("Jean", p7.getOwner().getFirstName()); + Pet p6 = this.clinic.loadPet(6); + assertEquals("George", p6.getName()); + assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId()); + assertEquals("Peter", p6.getOwner().getFirstName()); + } + + public void testInsertPet() { + Owner o6 = this.clinic.loadOwner(6); + int found = o6.getPets().size(); + Pet pet = new Pet(); + pet.setName("bowser"); + Collection types = this.clinic.getPetTypes(); + pet.setType(EntityUtils.getById(types, PetType.class, 2)); + pet.setBirthDate(new Date()); + o6.addPet(pet); + assertEquals(found + 1, o6.getPets().size()); + this.clinic.storeOwner(o6); + // assertTrue(!pet.isNew()); -- NOT TRUE FOR TOPLINK (before commit) + o6 = this.clinic.loadOwner(6); + assertEquals(found + 1, o6.getPets().size()); + } + + public void testUpdatePet() throws Exception { + Pet p7 = this.clinic.loadPet(7); + String old = p7.getName(); + p7.setName(old + "X"); + this.clinic.storePet(p7); + p7 = this.clinic.loadPet(7); + assertEquals(old + "X", p7.getName()); + } + + public void testInsertVisit() { + Pet p7 = this.clinic.loadPet(7); + int found = p7.getVisits().size(); + Visit visit = new Visit(); + p7.addVisit(visit); + visit.setDescription("test"); + this.clinic.storePet(p7); + // assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit) + p7 = this.clinic.loadPet(7); + assertEquals(found + 1, p7.getVisits().size()); + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java new file mode 100644 index 000000000..67c472fde --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java @@ -0,0 +1,51 @@ +package org.springframework.samples.petclinic.jpa; + +import java.util.List; + +import org.springframework.samples.petclinic.aspects.UsageLogAspect; + +/** + *

    + * Tests for the DAO variant based on the shared EntityManager approach. Uses + * TopLink Essentials (the reference implementation) for testing. + *

    + *

    + * Specifically tests usage of an orm.xml file, loaded by the + * persistence provider through the Spring-provided persistence unit root URL. + *

    + * + * @author Rod Johnson + * @author Juergen Hoeller + */ +public class EntityManagerClinicTests extends AbstractJpaClinicTests { + + private UsageLogAspect usageLogAspect; + + public void setUsageLogAspect(UsageLogAspect usageLogAspect) { + this.usageLogAspect = usageLogAspect; + } + + @Override + protected String[] getConfigPaths() { + return new String[] { + "applicationContext-jpaCommon.xml", + "applicationContext-toplinkAdapter.xml", + "applicationContext-entityManager.xml" + }; + } + + public void testUsageLogAspectIsInvoked() { + String name1 = "Schuurman"; + String name2 = "Greenwood"; + String name3 = "Leau"; + + assertTrue(this.clinic.findOwners(name1).isEmpty()); + assertTrue(this.clinic.findOwners(name2).isEmpty()); + + List namesRequested = this.usageLogAspect.getNamesRequested(); + assertTrue(namesRequested.contains(name1)); + assertTrue(namesRequested.contains(name2)); + assertFalse(namesRequested.contains(name3)); + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java new file mode 100644 index 000000000..d95b452e1 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java @@ -0,0 +1,26 @@ +package org.springframework.samples.petclinic.jpa; + +/** + *

    + * Tests for the DAO variant based on the shared EntityManager approach, using + * Hibernate EntityManager for testing instead of the reference implementation. + *

    + *

    + * Specifically tests usage of an orm.xml file, loaded by the + * persistence provider through the Spring-provided persistence unit root URL. + *

    + * + * @author Juergen Hoeller + */ +public class HibernateEntityManagerClinicTests extends EntityManagerClinicTests { + + @Override + protected String[] getConfigPaths() { + return new String[] { + "applicationContext-jpaCommon.xml", + "applicationContext-hibernateAdapter.xml", + "applicationContext-entityManager.xml" + }; + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java new file mode 100644 index 000000000..98e38ed61 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java @@ -0,0 +1,27 @@ + +package org.springframework.samples.petclinic.jpa; + +/** + *

    + * Tests for the DAO variant based on the shared EntityManager approach, using + * Apache OpenJPA for testing instead of the reference implementation. + *

    + *

    + * Specifically tests usage of an orm.xml file, loaded by the + * persistence provider through the Spring-provided persistence unit root URL. + *

    + * + * @author Juergen Hoeller + */ +public class OpenJpaEntityManagerClinicTests extends EntityManagerClinicTests { + + @Override + protected String[] getConfigPaths() { + return new String[] { + "applicationContext-jpaCommon.xml", + "applicationContext-openJpaAdapter.xml", + "applicationContext-entityManager.xml" + }; + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java b/src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java new file mode 100644 index 000000000..1e82e1d5b --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.web; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.syndication.feed.atom.Entry; +import com.sun.syndication.feed.atom.Feed; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Before; +import org.junit.Test; + +import org.springframework.samples.petclinic.Pet; +import org.springframework.samples.petclinic.PetType; +import org.springframework.samples.petclinic.Visit; + +/** + * @author Arjen Poutsma + */ +public class VisitsAtomViewTest { + + private VisitsAtomView visitView; + + private Map model; + + private Feed feed; + + @Before + public void setUp() { + visitView = new VisitsAtomView(); + PetType dog = new PetType(); + dog.setName("dog"); + Pet bello = new Pet(); + bello.setName("Bello"); + bello.setType(dog); + Visit belloVisit = new Visit(); + belloVisit.setPet(bello); + belloVisit.setDate(new Date(2009, 0, 1)); + belloVisit.setDescription("Bello visit"); + Pet wodan = new Pet(); + wodan.setName("Wodan"); + wodan.setType(dog); + Visit wodanVisit = new Visit(); + wodanVisit.setPet(wodan); + wodanVisit.setDate(new Date(2009, 0, 2)); + wodanVisit.setDescription("Wodan visit"); + List visits = new ArrayList(); + visits.add(belloVisit); + visits.add(wodanVisit); + + model = new HashMap(); + model.put("visits", visits); + feed = new Feed(); + + } + + @Test + public void buildFeedMetadata() { + visitView.buildFeedMetadata(model, feed, null); + + assertNotNull("No id set", feed.getId()); + assertNotNull("No title set", feed.getTitle()); + assertEquals("Invalid update set", new Date(2009, 0, 2), feed.getUpdated()); + } + + @Test + public void buildFeedEntries() throws Exception { + List entries = visitView.buildFeedEntries(model, null, null); + assertEquals("Invalid amount of entries", 2, entries.size()); + } +} diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml new file mode 100644 index 000000000..767b96d62 --- /dev/null +++ b/src/test/resources/log4j.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml new file mode 100644 index 000000000..3f79cbc09 --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml new file mode 100644 index 000000000..7320035ce --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + ${hibernate.dialect} + ${hibernate.show_sql} + + + + + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml new file mode 100644 index 000000000..81a536988 --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml new file mode 100644 index 000000000..a9d257385 --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml new file mode 100644 index 000000000..447d1bce0 --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml new file mode 100644 index 000000000..b873dfc47 --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml new file mode 100644 index 000000000..8f6f7c442 --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml new file mode 100644 index 000000000..ac031de8e --- /dev/null +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml @@ -0,0 +1,9 @@ + + + + + + From c0b90bf9ef66bb2fdd051a3f0d8c6f6cee7e6ac3 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 25 Nov 2009 19:27:08 +0000 Subject: [PATCH 020/887] SPR-6447 + move jdbc scripts from META-INF into /resources --- pom.xml | 4 +++- .../{webapp/META-INF => resources}/hsqldb/dropTables.txt | 0 src/main/{webapp/META-INF => resources}/hsqldb/initDB.txt | 0 .../{webapp/META-INF => resources}/hsqldb/populateDB.txt | 0 src/main/resources/jdbc.properties | 6 +++--- 5 files changed, 6 insertions(+), 4 deletions(-) rename src/main/{webapp/META-INF => resources}/hsqldb/dropTables.txt (100%) rename src/main/{webapp/META-INF => resources}/hsqldb/initDB.txt (100%) rename src/main/{webapp/META-INF => resources}/hsqldb/populateDB.txt (100%) diff --git a/pom.xml b/pom.xml index d9b79897e..09e4330cf 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.springframework.samples - org.springframework.samples.petclinic + petclinic-classic petclinic-classic war 1.0.0-SNAPSHOT @@ -43,6 +43,7 @@ javax.servlet com.springsource.javax.servlet.jsp.jstl 1.2.0 + provided javax.xml.bind @@ -68,6 +69,7 @@ org.apache.taglibs com.springsource.org.apache.taglibs.standard 1.1.2 + provided org.aspectj diff --git a/src/main/webapp/META-INF/hsqldb/dropTables.txt b/src/main/resources/hsqldb/dropTables.txt similarity index 100% rename from src/main/webapp/META-INF/hsqldb/dropTables.txt rename to src/main/resources/hsqldb/dropTables.txt diff --git a/src/main/webapp/META-INF/hsqldb/initDB.txt b/src/main/resources/hsqldb/initDB.txt similarity index 100% rename from src/main/webapp/META-INF/hsqldb/initDB.txt rename to src/main/resources/hsqldb/initDB.txt diff --git a/src/main/webapp/META-INF/hsqldb/populateDB.txt b/src/main/resources/hsqldb/populateDB.txt similarity index 100% rename from src/main/webapp/META-INF/hsqldb/populateDB.txt rename to src/main/resources/hsqldb/populateDB.txt diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties index e039cdf1b..47537f9cd 100644 --- a/src/main/resources/jdbc.properties +++ b/src/main/resources/jdbc.properties @@ -23,9 +23,9 @@ jdbc.password= # Properties that control the population of schema and data for a new data source jdbc.populate=true -jdbc.schemaLocation=classpath:/META-INF/hsqldb/initDB.txt -jdbc.dataLocation=classpath:/META-INF/hsqldb/populateDB.txt -jdbc.dropLocation=classpath:/META-INF/hsqldb/dropTables.txt +jdbc.schemaLocation=classpath:hsqldb/initDB.txt +jdbc.dataLocation=classpath:hsqldb/populateDB.txt +jdbc.dropLocation=classpath:hsqldb/dropTables.txt # Property that determines which Hibernate dialect to use # (only applied with "applicationContext-hibernate.xml") From d109fdd2f5d6d8746e1a39a896e22ebad06eac85 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 25 Nov 2009 19:37:20 +0000 Subject: [PATCH 021/887] SPR-6447 SPR-6449 + fix the packaging of some libraries to prevent weird class loading problems from occuring --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index 09e4330cf..10e9ca9af 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,14 @@ com.springsource.com.sun.syndication 1.0.0 + javax.persistence com.springsource.javax.persistence @@ -49,6 +57,7 @@ javax.xml.bind com.springsource.javax.xml.bind 2.1.7 + provided org.apache.commons @@ -65,12 +74,14 @@ com.springsource.org.apache.openjpa 1.1.0 + org.aspectj com.springsource.org.aspectj.weaver From 50b87ef75fb8dffb202ff7370434d49dbc3cf129 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 16:46:54 +0000 Subject: [PATCH 022/887] SPR-6447 + moved db files around + moved JPA/AOP META-INF/ files into the webapp classpath --- .../resources/{ => db}/hsqldb/dropTables.txt | 0 src/main/resources/{ => db}/hsqldb/initDB.txt | 0 .../resources/{ => db}/hsqldb/populateDB.txt | 0 src/main/resources/db/mysql/createDB.txt | 3 + src/main/resources/db/mysql/dropDB.txt | 1 + src/main/resources/db/mysql/initDB.txt | 58 +++++++++++++++++ .../db/mysql/petclinic_tomcat_mysql.xml | 64 +++++++++++++++++++ src/main/resources/jdbc.properties | 12 ++-- 8 files changed, 132 insertions(+), 6 deletions(-) rename src/main/resources/{ => db}/hsqldb/dropTables.txt (100%) rename src/main/resources/{ => db}/hsqldb/initDB.txt (100%) rename src/main/resources/{ => db}/hsqldb/populateDB.txt (100%) create mode 100644 src/main/resources/db/mysql/createDB.txt create mode 100644 src/main/resources/db/mysql/dropDB.txt create mode 100644 src/main/resources/db/mysql/initDB.txt create mode 100644 src/main/resources/db/mysql/petclinic_tomcat_mysql.xml diff --git a/src/main/resources/hsqldb/dropTables.txt b/src/main/resources/db/hsqldb/dropTables.txt similarity index 100% rename from src/main/resources/hsqldb/dropTables.txt rename to src/main/resources/db/hsqldb/dropTables.txt diff --git a/src/main/resources/hsqldb/initDB.txt b/src/main/resources/db/hsqldb/initDB.txt similarity index 100% rename from src/main/resources/hsqldb/initDB.txt rename to src/main/resources/db/hsqldb/initDB.txt diff --git a/src/main/resources/hsqldb/populateDB.txt b/src/main/resources/db/hsqldb/populateDB.txt similarity index 100% rename from src/main/resources/hsqldb/populateDB.txt rename to src/main/resources/db/hsqldb/populateDB.txt diff --git a/src/main/resources/db/mysql/createDB.txt b/src/main/resources/db/mysql/createDB.txt new file mode 100644 index 000000000..5b4b3859e --- /dev/null +++ b/src/main/resources/db/mysql/createDB.txt @@ -0,0 +1,3 @@ +CREATE DATABASE petclinic; + +GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; \ No newline at end of file diff --git a/src/main/resources/db/mysql/dropDB.txt b/src/main/resources/db/mysql/dropDB.txt new file mode 100644 index 000000000..e1209da0e --- /dev/null +++ b/src/main/resources/db/mysql/dropDB.txt @@ -0,0 +1 @@ +DROP DATABASE petclinic; diff --git a/src/main/resources/db/mysql/initDB.txt b/src/main/resources/db/mysql/initDB.txt new file mode 100644 index 000000000..0007ee3a3 --- /dev/null +++ b/src/main/resources/db/mysql/initDB.txt @@ -0,0 +1,58 @@ +USE petclinic; + +CREATE TABLE vets ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30), + INDEX(last_name) +) engine=InnoDB; + +CREATE TABLE specialties ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(80), + INDEX(name) +) engine=InnoDB; + +CREATE TABLE vet_specialties ( + vet_id INT(4) UNSIGNED NOT NULL, + specialty_id INT(4) UNSIGNED NOT NULL +) engine=InnoDB; +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets(id); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties(id); + +CREATE TABLE types ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(80), + INDEX(name) +) engine=InnoDB; + +CREATE TABLE owners ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30), + address VARCHAR(255), + city VARCHAR(80), + telephone VARCHAR(20), + INDEX(last_name) +) engine=InnoDB; + +CREATE TABLE pets ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(30), + birth_date DATE, + type_id INT(4) UNSIGNED NOT NULL, + owner_id INT(4) UNSIGNED NOT NULL, + INDEX(name) +) engine=InnoDB; +ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners(id); +ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types(id); +CREATE INDEX pets_name ON pets(name); + +CREATE TABLE visits ( + id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + pet_id INT(4) UNSIGNED NOT NULL, + visit_date DATE, + description VARCHAR(255), + INDEX(pet_id) +) engine=InnoDB; +ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets(id); diff --git a/src/main/resources/db/mysql/petclinic_tomcat_mysql.xml b/src/main/resources/db/mysql/petclinic_tomcat_mysql.xml new file mode 100644 index 000000000..d1c5a3b04 --- /dev/null +++ b/src/main/resources/db/mysql/petclinic_tomcat_mysql.xml @@ -0,0 +1,64 @@ + + + + + + + + + + factory + org.apache.commons.dbcp.BasicDataSourceFactory + + + + driverClassName + org.gjt.mm.mysql.Driver + + + + url + jdbc:mysql://localhost:3306/petclinic?autoReconnect=true + + + username + pc + + + password + pc + + + + maxActive + 50 + + + maxIdle + 10 + + + maxWait + 10000 + + + removeAbandoned + true + + + removeAbandonedTimeout + 60 + + + logAbandoned + true + + + + + diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties index 47537f9cd..02bda078b 100644 --- a/src/main/resources/jdbc.properties +++ b/src/main/resources/jdbc.properties @@ -23,9 +23,9 @@ jdbc.password= # Properties that control the population of schema and data for a new data source jdbc.populate=true -jdbc.schemaLocation=classpath:hsqldb/initDB.txt -jdbc.dataLocation=classpath:hsqldb/populateDB.txt -jdbc.dropLocation=classpath:hsqldb/dropTables.txt +jdbc.schemaLocation=classpath:db/hsqldb/initDB.txt +jdbc.dataLocation=classpath:db/hsqldb/populateDB.txt +jdbc.dropLocation=classpath:db/hsqldb/dropTables.txt # Property that determines which Hibernate dialect to use # (only applied with "applicationContext-hibernate.xml") @@ -48,9 +48,9 @@ jpa.database=HSQL # Properties that control the population of schema and data for a new data source #jdbc.populate=false -#jdbc.schemaLocation= -#jdbc.dataLocation= -#jdbc.dropLocation= +#jdbc.schemaLocation=classpath:db/mysql/initDB.txt +#jdbc.dataLocation=classpath:db/mysql/populateDB.txt +#jdbc.dropLocation=classpath:db/mysql/dropTables.txt # Property that determines which Hibernate dialect to use # (only applied with "applicationContext-hibernate.xml") From 8291c801229786cc6cd50f585e81021cd0ec1a72 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 16:47:32 +0000 Subject: [PATCH 023/887] SPR-6447 + added on the fly db configuration to all contexts + removed schema numbers to always pick the latest version --- .../WEB-INF/applicationContext-hibernate.xml | 18 ++++++++---- .../WEB-INF/applicationContext-jdbc.xml | 16 +++++++---- .../webapp/WEB-INF/applicationContext-jpa.xml | 28 +++++++++++++------ src/main/webapp/WEB-INF/petclinic-servlet.xml | 4 +-- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml index bfc166db6..39a939aad 100644 --- a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml +++ b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml @@ -6,10 +6,10 @@ xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd - http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd - http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> @@ -22,10 +22,18 @@ for the required JAR files. Alternatively you can use another connection pool such as C3P0, similarly configured using Spring. --> + + + + + @@ -32,6 +32,12 @@ p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}" p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"/> + + @@ -27,14 +27,24 @@ + + + + + + + + + + factory + org.apache.commons.dbcp.BasicDataSourceFactory + + + + driverClassName + org.hsqldb.jdbcDriver + + + url + jdbc:hsqldb:hsql://localhost:9001 + + + username + sa + + + + maxActive + 50 + + + maxIdle + 10 + + + maxWait + 10000 + + + removeAbandoned + true + + + removeAbandonedTimeout + 60 + + + logAbandoned + true + + + From 9617efef3225b818b96cfb1d1d63ae2f69f9df4a Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 18:30:49 +0000 Subject: [PATCH 027/887] SPR-6447 + improve DataSource setup --- db/build.xml | 85 ------------------- db/dropTables.txt | 7 -- db/emptyDB.txt | 7 -- db/mysql/createDB.txt | 3 - db/mysql/dropDB.txt | 1 - db/mysql/initDB.txt | 58 ------------- db/mysql/petclinic_db_setup_mysql.txt | 22 ----- db/mysql/petclinic_tomcat_mysql.xml | 64 --------------- db/petclinic_tomcat_all.xml | 112 -------------------------- db/populateDB.txt | 53 ------------ pom.xml | 20 +++-- src/main/resources/db/db_readme.txt | 15 ++++ 12 files changed, 30 insertions(+), 417 deletions(-) delete mode 100644 db/build.xml delete mode 100644 db/dropTables.txt delete mode 100644 db/emptyDB.txt delete mode 100644 db/mysql/createDB.txt delete mode 100644 db/mysql/dropDB.txt delete mode 100644 db/mysql/initDB.txt delete mode 100644 db/mysql/petclinic_db_setup_mysql.txt delete mode 100644 db/mysql/petclinic_tomcat_mysql.xml delete mode 100644 db/petclinic_tomcat_all.xml delete mode 100644 db/populateDB.txt create mode 100644 src/main/resources/db/db_readme.txt diff --git a/db/build.xml b/db/build.xml deleted file mode 100644 index b6d09936b..000000000 --- a/db/build.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/db/dropTables.txt b/db/dropTables.txt deleted file mode 100644 index 90ae6329f..000000000 --- a/db/dropTables.txt +++ /dev/null @@ -1,7 +0,0 @@ -DROP TABLE visits; -DROP TABLE pets; -DROP TABLE owners; -DROP TABLE types; -DROP TABLE vet_specialties; -DROP TABLE specialties; -DROP TABLE vets; diff --git a/db/emptyDB.txt b/db/emptyDB.txt deleted file mode 100644 index d5dd8728c..000000000 --- a/db/emptyDB.txt +++ /dev/null @@ -1,7 +0,0 @@ -DELETE FROM vets; -DELETE FROM specialties; -DELETE FROM vet_specialties; -DELETE FROM types; -DELETE FROM owners; -DELETE FROM pets; -DELETE FROM visits; diff --git a/db/mysql/createDB.txt b/db/mysql/createDB.txt deleted file mode 100644 index 5b4b3859e..000000000 --- a/db/mysql/createDB.txt +++ /dev/null @@ -1,3 +0,0 @@ -CREATE DATABASE petclinic; - -GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; \ No newline at end of file diff --git a/db/mysql/dropDB.txt b/db/mysql/dropDB.txt deleted file mode 100644 index e1209da0e..000000000 --- a/db/mysql/dropDB.txt +++ /dev/null @@ -1 +0,0 @@ -DROP DATABASE petclinic; diff --git a/db/mysql/initDB.txt b/db/mysql/initDB.txt deleted file mode 100644 index 0007ee3a3..000000000 --- a/db/mysql/initDB.txt +++ /dev/null @@ -1,58 +0,0 @@ -USE petclinic; - -CREATE TABLE vets ( - id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - first_name VARCHAR(30), - last_name VARCHAR(30), - INDEX(last_name) -) engine=InnoDB; - -CREATE TABLE specialties ( - id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(80), - INDEX(name) -) engine=InnoDB; - -CREATE TABLE vet_specialties ( - vet_id INT(4) UNSIGNED NOT NULL, - specialty_id INT(4) UNSIGNED NOT NULL -) engine=InnoDB; -ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets(id); -ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties(id); - -CREATE TABLE types ( - id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(80), - INDEX(name) -) engine=InnoDB; - -CREATE TABLE owners ( - id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - first_name VARCHAR(30), - last_name VARCHAR(30), - address VARCHAR(255), - city VARCHAR(80), - telephone VARCHAR(20), - INDEX(last_name) -) engine=InnoDB; - -CREATE TABLE pets ( - id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(30), - birth_date DATE, - type_id INT(4) UNSIGNED NOT NULL, - owner_id INT(4) UNSIGNED NOT NULL, - INDEX(name) -) engine=InnoDB; -ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners(id); -ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types(id); -CREATE INDEX pets_name ON pets(name); - -CREATE TABLE visits ( - id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - pet_id INT(4) UNSIGNED NOT NULL, - visit_date DATE, - description VARCHAR(255), - INDEX(pet_id) -) engine=InnoDB; -ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets(id); diff --git a/db/mysql/petclinic_db_setup_mysql.txt b/db/mysql/petclinic_db_setup_mysql.txt deleted file mode 100644 index 66727e190..000000000 --- a/db/mysql/petclinic_db_setup_mysql.txt +++ /dev/null @@ -1,22 +0,0 @@ -================================================================================ -=== Spring PetClinic sample application - MySQL Configuration === -================================================================================ - -@author Sam Brannen - --------------------------------------------------------------------------------- - -1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), - which can be found here: http://dev.mysql.com/downloads/ - -2) Download Connector/J, the MySQL JDBC driver (e.g., Connector/J 5.1.x), which - can be found here: http://dev.mysql.com/downloads/connector/j/ - Copy the Connector/J JAR file (e.g., mysql-connector-java-5.1.5-bin.jar) into - the db/mysql directory. - -3) Create the PetClinic database and user by executing the "db/mysql/createDB.txt" - script. - -4) Open "src/main/resources/jdbc.properties"; comment out all properties in the - "HSQL Settings" section; uncomment all properties in the "MySQL Settings" - section. \ No newline at end of file diff --git a/db/mysql/petclinic_tomcat_mysql.xml b/db/mysql/petclinic_tomcat_mysql.xml deleted file mode 100644 index d1c5a3b04..000000000 --- a/db/mysql/petclinic_tomcat_mysql.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - factory - org.apache.commons.dbcp.BasicDataSourceFactory - - - - driverClassName - org.gjt.mm.mysql.Driver - - - - url - jdbc:mysql://localhost:3306/petclinic?autoReconnect=true - - - username - pc - - - password - pc - - - - maxActive - 50 - - - maxIdle - 10 - - - maxWait - 10000 - - - removeAbandoned - true - - - removeAbandonedTimeout - 60 - - - logAbandoned - true - - - - - diff --git a/db/petclinic_tomcat_all.xml b/db/petclinic_tomcat_all.xml deleted file mode 100644 index ed45c5cd3..000000000 --- a/db/petclinic_tomcat_all.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - factory - org.apache.commons.dbcp.BasicDataSourceFactory - - - - driverClassName - org.hsqldb.jdbcDriver - - - url - jdbc:hsqldb:hsql://localhost:9001 - - - username - sa - - - - maxActive - 50 - - - maxIdle - 10 - - - maxWait - 10000 - - - removeAbandoned - true - - - removeAbandonedTimeout - 60 - - - logAbandoned - true - - - - - - - - factory - org.apache.commons.dbcp.BasicDataSourceFactory - - - - driverClassName - org.gjt.mm.mysql.Driver - - - - url - jdbc:mysql://localhost:3306/petclinic?autoReconnect=true - - - username - pc - - - password - pc - - - - maxActive - 50 - - - maxIdle - 10 - - - maxWait - 10000 - - - removeAbandoned - true - - - removeAbandonedTimeout - 60 - - - logAbandoned - true - - - - - diff --git a/db/populateDB.txt b/db/populateDB.txt deleted file mode 100644 index 1bf0c4a6e..000000000 --- a/db/populateDB.txt +++ /dev/null @@ -1,53 +0,0 @@ -INSERT INTO vets VALUES (1, 'James', 'Carter'); -INSERT INTO vets VALUES (2, 'Helen', 'Leary'); -INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); -INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); -INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); -INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); - -INSERT INTO specialties VALUES (1, 'radiology'); -INSERT INTO specialties VALUES (2, 'surgery'); -INSERT INTO specialties VALUES (3, 'dentistry'); - -INSERT INTO vet_specialties VALUES (2, 1); -INSERT INTO vet_specialties VALUES (3, 2); -INSERT INTO vet_specialties VALUES (3, 3); -INSERT INTO vet_specialties VALUES (4, 2); -INSERT INTO vet_specialties VALUES (5, 1); - -INSERT INTO types VALUES (1, 'cat'); -INSERT INTO types VALUES (2, 'dog'); -INSERT INTO types VALUES (3, 'lizard'); -INSERT INTO types VALUES (4, 'snake'); -INSERT INTO types VALUES (5, 'bird'); -INSERT INTO types VALUES (6, 'hamster'); - -INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); -INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); -INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); -INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); -INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); -INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); -INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); -INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); -INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); -INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); - -INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1); -INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2); -INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3); -INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3); -INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4); -INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5); -INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6); -INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6); -INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7); -INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8); -INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9); -INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10); -INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10); - -INSERT INTO visits VALUES (1, 7, '1996-03-04', 'rabies shot'); -INSERT INTO visits VALUES (2, 8, '1996-03-04', 'rabies shot'); -INSERT INTO visits VALUES (3, 8, '1996-06-04', 'neutered'); -INSERT INTO visits VALUES (4, 7, '1996-09-04', 'spayed'); diff --git a/pom.xml b/pom.xml index 10e9ca9af..6174812c4 100644 --- a/pom.xml +++ b/pom.xml @@ -3,8 +3,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.springframework.samples - petclinic-classic - petclinic-classic + petclinic + petclinic war 1.0.0-SNAPSHOT @@ -102,6 +102,14 @@ com.springsource.org.hsqldb 1.8.0.9 + + org.jdom com.springsource.org.jdom @@ -112,6 +120,11 @@ org.springframework.asm ${spring.version} + + org.springframework + org.springframework.aspects + ${spring.version} + org.springframework org.springframework.orm @@ -156,19 +169,16 @@ org.slf4j com.springsource.slf4j.org.apache.commons.logging ${slf4j.version} - provided org.slf4j com.springsource.slf4j.api ${slf4j.version} - provided org.slf4j com.springsource.slf4j.log4j ${slf4j.version} - provided log4j diff --git a/src/main/resources/db/db_readme.txt b/src/main/resources/db/db_readme.txt new file mode 100644 index 000000000..80deff0ea --- /dev/null +++ b/src/main/resources/db/db_readme.txt @@ -0,0 +1,15 @@ +================================================================================ +=== Spring PetClinic sample application - Database Configuration === +================================================================================ + +@author Costin Leau + +-------------------------------------------------------------------------------- + +In its default configuration, Petclinic uses an in-memory database (HSQLDB) which +gets populated at startup with data. Since there is no persistent support, once +the application is destroyed, so is the database. +If a persistent database configuration is chosen, make sure to change the datasource +inside the relevant application-*.xml so that the schema and the data do not get +inserted each time the application is started. Additionally, update the jdbc.properties +file to reflect your change. \ No newline at end of file From a36bc3c2925bb355f7496b2dc87048200a5fad1a Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 19:34:40 +0000 Subject: [PATCH 028/887] SPR-6447 SPR-6448 + add JSTL libraries to the war for portability --- pom.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pom.xml b/pom.xml index 6174812c4..95accfb66 100644 --- a/pom.xml +++ b/pom.xml @@ -22,14 +22,6 @@ com.springsource.com.sun.syndication 1.0.0 - javax.persistence com.springsource.javax.persistence @@ -74,14 +66,12 @@ com.springsource.org.apache.openjpa 1.1.0 - org.aspectj com.springsource.org.aspectj.weaver From 5db88f472c254ccfc8ec34fb2b1144ecbc984480 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 20:03:27 +0000 Subject: [PATCH 029/887] SPR-6447 SPR-6448 + add JSTL libraries to the war for portability --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 95accfb66..184fb3253 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,6 @@ javax.servlet com.springsource.javax.servlet.jsp.jstl 1.2.0 - provided javax.xml.bind @@ -70,7 +69,6 @@ org.apache.taglibs com.springsource.org.apache.taglibs.standard 1.1.2 - provided org.aspectj From a8cc00689b5610be30f0e33f653510459adc8e89 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 20:04:27 +0000 Subject: [PATCH 030/887] SPR-6447 + extracted datasource definition into a separate file to eliminate redundancy + introduce jdbc: namespace --- .../config/DbcpDataSourceFactory.java | 261 ------------------ src/main/resources/jdbc.properties | 10 +- .../WEB-INF/applicationContext-dataSource.xml | 37 +++ .../WEB-INF/applicationContext-hibernate.xml | 29 +- .../WEB-INF/applicationContext-jdbc.xml | 37 +-- .../webapp/WEB-INF/applicationContext-jpa.xml | 37 +-- 6 files changed, 55 insertions(+), 356 deletions(-) delete mode 100644 src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java create mode 100644 src/main/webapp/WEB-INF/applicationContext-dataSource.xml diff --git a/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java b/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java deleted file mode 100644 index 0454161e6..000000000 --- a/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.config; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringWriter; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import javax.sql.DataSource; - -import org.apache.commons.dbcp.BasicDataSource; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.core.io.Resource; - -/** - * A factory that creates a data source fit for use in a system environment. Creates a DBCP simple data source - * from the provided connection properties. - * - * This factory returns a fully-initialized DataSource implementation. When the DataSource is returned, callers are - * guaranteed that the database schema and data will have been loaded by that time. - * - * Is a FactoryBean, for exposing the fully-initialized DataSource as a Spring bean. See {@link #getObject()}. - * - * @author Chris Beams - * @author Scott Andrews - */ -public class DbcpDataSourceFactory implements FactoryBean, DisposableBean { - - // configurable properties - - private String driverClassName; - - private String url; - - private String username; - - private String password; - - private boolean populate; - - private Resource schemaLocation; - - private Resource dataLocation; - - private Resource dropLocation; - - /** - * The object created by this factory. - */ - private BasicDataSource dataSource; - - public void setDriverClassName(String driverClassName) { - this.driverClassName = driverClassName; - } - - /** - * The data source connection URL - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * The data source username - */ - public void setUsername(String username) { - this.username = username; - } - - /** - *The data source password - */ - public void setPassword(String password) { - this.password = password; - } - - /** - * Indicates that the data base should be populated from the schema and data locations - */ - public void setPopulate(boolean populate) { - this.populate = populate; - } - - /** - * Sets the location of the file containing the schema DDL to export to the database. - * @param schemaLocation the location of the database schema DDL - */ - public void setSchemaLocation(Resource schemaLocation) { - this.schemaLocation = schemaLocation; - } - - /** - * Sets the location of the file containing the data to load into the database. - * @param testDataLocation the location of the data file - */ - public void setDataLocation(Resource testDataLocation) { - this.dataLocation = testDataLocation; - } - - /** - * Sets the location of the file containing the drop scripts for the database. - * @param testDataLocation the location of the data file - */ - public void setDropLocation(Resource testDropLocation) { - this.dropLocation = testDropLocation; - } - - // implementing FactoryBean - - // this method is called by Spring to expose the DataSource as a bean - public DataSource getObject() throws Exception { - if (dataSource == null) { - initDataSource(); - } - return dataSource; - } - - public Class getObjectType() { - return DataSource.class; - } - - public boolean isSingleton() { - return true; - } - - // implementing DisposableBean - - public void destroy() throws Exception { - dataSource.close(); - } - - // internal helper methods - - // encapsulates the steps involved in initializing the data source: creating it, and populating it - private void initDataSource() { - // create the database source first - this.dataSource = createDataSource(); - - if (this.populate) { - // now populate the database by loading the schema and data - populateDataSource(); - } - } - - private BasicDataSource createDataSource() { - BasicDataSource dataSource = new BasicDataSource(); - dataSource.setDriverClassName(this.driverClassName); - dataSource.setUrl(this.url); - dataSource.setUsername(this.username); - dataSource.setPassword(this.password); - return dataSource; - } - - private void populateDataSource() { - DatabasePopulator populator = new DatabasePopulator(dataSource); - if (dropLocation != null) { - try { - populator.populate(this.dropLocation); - } - catch (Exception e) { - // ignore - } - } - populator.populate(this.schemaLocation); - populator.populate(this.dataLocation); - } - - /** - * Populates a in memory data source with data. - */ - private class DatabasePopulator { - - private DataSource dataSource; - - /** - * Creates a new database populator. - * @param dataSource the data source that will be populated. - */ - public DatabasePopulator(DataSource dataSource) { - this.dataSource = dataSource; - } - - /** - * Populate the database executing the statements in the provided resource against the database - * @param sqlFile spring resource containing SQL to run against the db - */ - public void populate(Resource sqlFile) { - Connection connection = null; - try { - connection = dataSource.getConnection(); - try { - String sql = parseSqlIn(sqlFile); - executeSql(sql, connection); - } catch (IOException e) { - throw new RuntimeException("I/O exception occurred accessing the database schema file", e); - } catch (SQLException e) { - throw new RuntimeException("SQL exception occurred exporting database schema", e); - } - } catch (SQLException e) { - throw new RuntimeException("SQL exception occurred acquiring connection", e); - } finally { - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - } - } - } - } - - // utility method to read a .sql txt input stream - private String parseSqlIn(Resource resource) throws IOException { - InputStream is = null; - try { - is = resource.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - - StringWriter sw = new StringWriter(); - BufferedWriter writer = new BufferedWriter(sw); - - for (int c=reader.read(); c != -1; c=reader.read()) { - writer.write(c); - } - writer.flush(); - return sw.toString(); - - } finally { - if (is != null) { - is.close(); - } - } - } - - // utility method to run the parsed sql - private void executeSql(String sql, Connection connection) throws SQLException { - Statement statement = connection.createStatement(); - statement.execute(sql); - } - } - -} diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties index 02bda078b..802ff6321 100644 --- a/src/main/resources/jdbc.properties +++ b/src/main/resources/jdbc.properties @@ -22,10 +22,8 @@ jdbc.username=sa jdbc.password= # Properties that control the population of schema and data for a new data source -jdbc.populate=true -jdbc.schemaLocation=classpath:db/hsqldb/initDB.txt +jdbc.initLocation=classpath:db/hsqldb/initDB.txt jdbc.dataLocation=classpath:db/hsqldb/populateDB.txt -jdbc.dropLocation=classpath:db/hsqldb/dropTables.txt # Property that determines which Hibernate dialect to use # (only applied with "applicationContext-hibernate.xml") @@ -43,14 +41,12 @@ jpa.database=HSQL #jdbc.driverClassName=com.mysql.jdbc.Driver #jdbc.url=jdbc:mysql://localhost:3306/petclinic -#jdbc.username=pc -#jdbc.password=pc +#jdbc.username=root +#jdbc.password= # Properties that control the population of schema and data for a new data source -#jdbc.populate=false #jdbc.schemaLocation=classpath:db/mysql/initDB.txt #jdbc.dataLocation=classpath:db/mysql/populateDB.txt -#jdbc.dropLocation=classpath:db/mysql/dropTables.txt # Property that determines which Hibernate dialect to use # (only applied with "applicationContext-hibernate.xml") diff --git a/src/main/webapp/WEB-INF/applicationContext-dataSource.xml b/src/main/webapp/WEB-INF/applicationContext-dataSource.xml new file mode 100644 index 000000000..cf655c5f7 --- /dev/null +++ b/src/main/webapp/WEB-INF/applicationContext-dataSource.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml index 39a939aad..8f414a7df 100644 --- a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml +++ b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml @@ -4,41 +4,18 @@ --> - + - - - - - - - - - @@ -94,4 +71,4 @@ - + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/applicationContext-jdbc.xml b/src/main/webapp/WEB-INF/applicationContext-jdbc.xml index e2b9bb4f7..6819d6db4 100644 --- a/src/main/webapp/WEB-INF/applicationContext-jdbc.xml +++ b/src/main/webapp/WEB-INF/applicationContext-jdbc.xml @@ -3,45 +3,18 @@ Application context definition for PetClinic on JDBC. --> - - - - - - - - - - - + + - + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/applicationContext-jpa.xml b/src/main/webapp/WEB-INF/applicationContext-jpa.xml index 5b2be5ecd..03ff7645e 100644 --- a/src/main/webapp/WEB-INF/applicationContext-jpa.xml +++ b/src/main/webapp/WEB-INF/applicationContext-jpa.xml @@ -4,17 +4,18 @@ --> + + + - + - - - - - - - - - + @@ -108,4 +85,4 @@ --> - + \ No newline at end of file From d6b57ac053c4b633ee19e1225a396a9e3e0c6c4e Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 20:50:10 +0000 Subject: [PATCH 031/887] SPR-6447 + improve mysql script to prevent data from being added if it's already present --- src/main/resources/db/db_readme.txt | 10 ++-- src/main/resources/db/mysql/createDB.txt | 3 -- src/main/resources/db/mysql/dropDB.txt | 1 - src/main/resources/db/mysql/initDB.txt | 36 ++++++++------- src/main/resources/db/mysql/populateDB.txt | 53 ++++++++++++++++++++++ src/main/resources/jdbc.properties | 2 +- 6 files changed, 77 insertions(+), 28 deletions(-) delete mode 100644 src/main/resources/db/mysql/createDB.txt delete mode 100644 src/main/resources/db/mysql/dropDB.txt create mode 100644 src/main/resources/db/mysql/populateDB.txt diff --git a/src/main/resources/db/db_readme.txt b/src/main/resources/db/db_readme.txt index 80deff0ea..55fbb6264 100644 --- a/src/main/resources/db/db_readme.txt +++ b/src/main/resources/db/db_readme.txt @@ -7,9 +7,7 @@ -------------------------------------------------------------------------------- In its default configuration, Petclinic uses an in-memory database (HSQLDB) which -gets populated at startup with data. Since there is no persistent support, once -the application is destroyed, so is the database. -If a persistent database configuration is chosen, make sure to change the datasource -inside the relevant application-*.xml so that the schema and the data do not get -inserted each time the application is started. Additionally, update the jdbc.properties -file to reflect your change. \ No newline at end of file +gets populated at startup with data. A similar setup is provided for Mysql in case +a persistent database configuration is needed. +Note that whenever the database type is changed, the jdbc.properties file needs to +be updated. \ No newline at end of file diff --git a/src/main/resources/db/mysql/createDB.txt b/src/main/resources/db/mysql/createDB.txt deleted file mode 100644 index 5b4b3859e..000000000 --- a/src/main/resources/db/mysql/createDB.txt +++ /dev/null @@ -1,3 +0,0 @@ -CREATE DATABASE petclinic; - -GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; \ No newline at end of file diff --git a/src/main/resources/db/mysql/dropDB.txt b/src/main/resources/db/mysql/dropDB.txt deleted file mode 100644 index e1209da0e..000000000 --- a/src/main/resources/db/mysql/dropDB.txt +++ /dev/null @@ -1 +0,0 @@ -DROP DATABASE petclinic; diff --git a/src/main/resources/db/mysql/initDB.txt b/src/main/resources/db/mysql/initDB.txt index 0007ee3a3..b90d1843a 100644 --- a/src/main/resources/db/mysql/initDB.txt +++ b/src/main/resources/db/mysql/initDB.txt @@ -1,32 +1,36 @@ +CREATE DATABASE IF NOT EXISTS petclinic; +GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; + USE petclinic; -CREATE TABLE vets ( +CREATE TABLE IF NOT EXISTS vets ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(30), last_name VARCHAR(30), INDEX(last_name) ) engine=InnoDB; -CREATE TABLE specialties ( +CREATE TABLE IF NOT EXISTS specialties ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(80), INDEX(name) ) engine=InnoDB; -CREATE TABLE vet_specialties ( +CREATE TABLE IF NOT EXISTS vet_specialties ( vet_id INT(4) UNSIGNED NOT NULL, - specialty_id INT(4) UNSIGNED NOT NULL + specialty_id INT(4) UNSIGNED NOT NULL, + FOREIGN KEY (vet_id) REFERENCES vets(id), + FOREIGN KEY (specialty_id) REFERENCES specialties(id), + UNIQUE (vet_id,specialty_id) ) engine=InnoDB; -ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets(id); -ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties(id); -CREATE TABLE types ( +CREATE TABLE IF NOT EXISTS types ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(80), INDEX(name) ) engine=InnoDB; -CREATE TABLE owners ( +CREATE TABLE IF NOT EXISTS owners ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(30), last_name VARCHAR(30), @@ -36,23 +40,21 @@ CREATE TABLE owners ( INDEX(last_name) ) engine=InnoDB; -CREATE TABLE pets ( +CREATE TABLE IF NOT EXISTS pets ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30), birth_date DATE, type_id INT(4) UNSIGNED NOT NULL, owner_id INT(4) UNSIGNED NOT NULL, - INDEX(name) + INDEX(name), + FOREIGN KEY (owner_id) REFERENCES owners(id), + FOREIGN KEY (type_id) REFERENCES types(id) ) engine=InnoDB; -ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners(id); -ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types(id); -CREATE INDEX pets_name ON pets(name); -CREATE TABLE visits ( +CREATE TABLE IF NOT EXISTS visits ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, pet_id INT(4) UNSIGNED NOT NULL, visit_date DATE, description VARCHAR(255), - INDEX(pet_id) -) engine=InnoDB; -ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets(id); + FOREIGN KEY (pet_id) REFERENCES pets(id) +) engine=InnoDB; \ No newline at end of file diff --git a/src/main/resources/db/mysql/populateDB.txt b/src/main/resources/db/mysql/populateDB.txt new file mode 100644 index 000000000..0a1cc9c29 --- /dev/null +++ b/src/main/resources/db/mysql/populateDB.txt @@ -0,0 +1,53 @@ +INSERT IGNORE INTO vets VALUES (1, 'James', 'Carter'); +INSERT IGNORE INTO vets VALUES (2, 'Helen', 'Leary'); +INSERT IGNORE INTO vets VALUES (3, 'Linda', 'Douglas'); +INSERT IGNORE INTO vets VALUES (4, 'Rafael', 'Ortega'); +INSERT IGNORE INTO vets VALUES (5, 'Henry', 'Stevens'); +INSERT IGNORE INTO vets VALUES (6, 'Sharon', 'Jenkins'); + +INSERT IGNORE INTO specialties VALUES (1, 'radiology'); +INSERT IGNORE INTO specialties VALUES (2, 'surgery'); +INSERT IGNORE INTO specialties VALUES (3, 'dentistry'); + +INSERT IGNORE INTO vet_specialties VALUES (2, 1); +INSERT IGNORE INTO vet_specialties VALUES (3, 2); +INSERT IGNORE INTO vet_specialties VALUES (3, 3); +INSERT IGNORE INTO vet_specialties VALUES (4, 2); +INSERT IGNORE INTO vet_specialties VALUES (5, 1); + +INSERT IGNORE INTO types VALUES (1, 'cat'); +INSERT IGNORE INTO types VALUES (2, 'dog'); +INSERT IGNORE INTO types VALUES (3, 'lizard'); +INSERT IGNORE INTO types VALUES (4, 'snake'); +INSERT IGNORE INTO types VALUES (5, 'bird'); +INSERT IGNORE INTO types VALUES (6, 'hamster'); + +INSERT IGNORE INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT IGNORE INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT IGNORE INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT IGNORE INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT IGNORE INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT IGNORE INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT IGNORE INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT IGNORE INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT IGNORE INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT IGNORE INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); + +INSERT IGNORE INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1); +INSERT IGNORE INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2); +INSERT IGNORE INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3); +INSERT IGNORE INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3); +INSERT IGNORE INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4); +INSERT IGNORE INTO pets VALUES (6, 'George', '2000-01-20', 4, 5); +INSERT IGNORE INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6); +INSERT IGNORE INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6); +INSERT IGNORE INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7); +INSERT IGNORE INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8); +INSERT IGNORE INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9); +INSERT IGNORE INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10); +INSERT IGNORE INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10); + +INSERT IGNORE INTO visits VALUES (1, 7, '1996-03-04', 'rabies shot'); +INSERT IGNORE INTO visits VALUES (2, 8, '1996-03-04', 'rabies shot'); +INSERT IGNORE INTO visits VALUES (3, 8, '1996-06-04', 'neutered'); +INSERT IGNORE INTO visits VALUES (4, 7, '1996-09-04', 'spayed'); diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties index 802ff6321..82cd2ead2 100644 --- a/src/main/resources/jdbc.properties +++ b/src/main/resources/jdbc.properties @@ -45,7 +45,7 @@ jpa.database=HSQL #jdbc.password= # Properties that control the population of schema and data for a new data source -#jdbc.schemaLocation=classpath:db/mysql/initDB.txt +#jdbc.initLocation=classpath:db/mysql/initDB.txt #jdbc.dataLocation=classpath:db/mysql/populateDB.txt # Property that determines which Hibernate dialect to use From 6f056b5072f474d334f65fe7886f98710168c907 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 20:51:48 +0000 Subject: [PATCH 032/887] SPR-6447 + removed unused script --- src/main/resources/db/hsqldb/dropTables.txt | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/resources/db/hsqldb/dropTables.txt diff --git a/src/main/resources/db/hsqldb/dropTables.txt b/src/main/resources/db/hsqldb/dropTables.txt deleted file mode 100644 index 90ae6329f..000000000 --- a/src/main/resources/db/hsqldb/dropTables.txt +++ /dev/null @@ -1,7 +0,0 @@ -DROP TABLE visits; -DROP TABLE pets; -DROP TABLE owners; -DROP TABLE types; -DROP TABLE vet_specialties; -DROP TABLE specialties; -DROP TABLE vets; From 93a378adde6b60c445c486e6f1989b7b11dff978 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 26 Nov 2009 20:56:30 +0000 Subject: [PATCH 033/887] SPR-6447 + fixed tab/spaces consistency --- .../WEB-INF/applicationContext-dataSource.xml | 16 ++++++++-------- .../webapp/WEB-INF/applicationContext-jpa.xml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/webapp/WEB-INF/applicationContext-dataSource.xml b/src/main/webapp/WEB-INF/applicationContext-dataSource.xml index cf655c5f7..395885883 100644 --- a/src/main/webapp/WEB-INF/applicationContext-dataSource.xml +++ b/src/main/webapp/WEB-INF/applicationContext-dataSource.xml @@ -11,13 +11,13 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> - - + + - + @@ -29,9 +29,9 @@ - - - - + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/applicationContext-jpa.xml b/src/main/webapp/WEB-INF/applicationContext-jpa.xml index 03ff7645e..080351116 100644 --- a/src/main/webapp/WEB-INF/applicationContext-jpa.xml +++ b/src/main/webapp/WEB-INF/applicationContext-jpa.xml @@ -13,9 +13,9 @@ - - - + + + - + From d8b761570563d3ab783fcaf7f8f3135fbda3bd69 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 27 Nov 2009 16:48:35 +0000 Subject: [PATCH 034/887] SPR-6447 + add missing datasource import to hibernate config --- src/main/webapp/WEB-INF/applicationContext-hibernate.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml index 8f414a7df..4fd19921b 100644 --- a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml +++ b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml @@ -12,6 +12,9 @@ + + + From fe63e9c87f9b1585ed5ef22bafdd1e397f1354dd Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 10 Dec 2009 20:49:35 +0000 Subject: [PATCH 035/887] + add default servlet definition (for containers that do not declare it - such as GlassFish) + increase Spring version to RC3 (it works with trunk just fine) --- pom.xml | 22 ++- src/main/webapp/WEB-INF/web.xml | 341 +++++++++++++++++--------------- 2 files changed, 198 insertions(+), 165 deletions(-) diff --git a/pom.xml b/pom.xml index 184fb3253..0606f04ab 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ war 1.0.0-SNAPSHOT - 3.0.0.RC2 + 3.0.0.RC3 1.5.6 @@ -73,12 +73,24 @@ org.aspectj com.springsource.org.aspectj.weaver - 1.6.3.RELEASE + 1.6.5.RELEASE org.hibernate - com.springsource.org.hibernate - 3.3.1.GA + hibernate + 3.2.7.ga + + + javax.transaction + jta + + + org.hibernate @@ -222,8 +234,10 @@ org.apache.maven.plugins maven-compiler-plugin + true 1.5 1.5 + true diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 06a6a3110..c83f52eb4 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -1,161 +1,180 @@ - - - - Spring PetClinic - - Spring PetClinic sample application - - - - webAppRootKey - petclinic.root - - - - - - - log4jConfigLocation - /WEB-INF/classes/log4j.properties - - - - - contextConfigLocation - - /WEB-INF/applicationContext-jdbc.xml - - - - - - - - - - - - org.springframework.web.context.ContextLoaderListener - - - - - default - /static/* - - - - - petclinic - org.springframework.web.servlet.DispatcherServlet - 2 - - - - - petclinic - / - - - - httpMethodFilter - org.springframework.web.filter.HiddenHttpMethodFilter - - - - httpMethodFilter - petclinic - - - - 10 - - - - java.lang.Exception - - /WEB-INF/jsp/uncaughtException.jsp - - - - - - + + + + Spring PetClinic + + Spring PetClinic sample application + + + + webAppRootKey + petclinic.root + + + + + + + log4jConfigLocation + /WEB-INF/classes/log4j.properties + + + + + contextConfigLocation + /WEB-INF/applicationContext-jdbc.xml + + + + + + + + + + + + org.springframework.web.context.ContextLoaderListener + + + + + + default + /static/* + + + + + petclinic + org.springframework.web.servlet.DispatcherServlet + 2 + + + + + petclinic + / + + + + httpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + + httpMethodFilter + petclinic + + + + 10 + + + + java.lang.Exception + + /WEB-INF/jsp/uncaughtException.jsp + + + + + + From 6116d12475ff697f495d0dea3b502620d5ed97ec Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 10 Dec 2009 21:08:19 +0000 Subject: [PATCH 036/887] SPR-6447 SPR-6449 --- readme.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.txt b/readme.txt index ae1fb2511..6d26c339a 100644 --- a/readme.txt +++ b/readme.txt @@ -73,6 +73,12 @@ to set up corresponding DataSources in your Java EE container. Notes on enabling Log4J: - Log4J is disabled by default due to issues with JBoss. - Uncomment the Log4J listener in "WEB-INF/web.xml" to enable logging. + +Notes on service static resources: + - Most web containers provide a 'default' servlet for serving static + resources; Petclinic relies on it for its images. + - On containers without such a mapping (ex: GlassFish), uncomment the + 'default' declaration in "WEB-INF/web.xml". ========================================================================== === JPA on Tomcat From dd521eb88a32fb613d1a18ae9b9f30cd7b227707 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Mon, 14 Dec 2009 19:06:58 +0000 Subject: [PATCH 037/887] SAMPLESPET-3 + renamed META-INF/persistence.xml to META-INF/jpa-persistence.xml since JBoss will scan it automatically and complain about non-jta-resources declared. --- src/main/webapp/WEB-INF/applicationContext-jpa.xml | 5 ++++- .../META-INF/{persistence.xml => jpa-persistence.xml} | 0 2 files changed, 4 insertions(+), 1 deletion(-) rename src/main/webapp/WEB-INF/classes/META-INF/{persistence.xml => jpa-persistence.xml} (100%) diff --git a/src/main/webapp/WEB-INF/applicationContext-jpa.xml b/src/main/webapp/WEB-INF/applicationContext-jpa.xml index 080351116..01ebfa01c 100644 --- a/src/main/webapp/WEB-INF/applicationContext-jpa.xml +++ b/src/main/webapp/WEB-INF/applicationContext-jpa.xml @@ -42,6 +42,7 @@ p:database="${jpa.database}" p:showSql="${jpa.showSql}"/> --> + @@ -62,8 +63,10 @@ - + contextConfigLocation - /WEB-INF/applicationContext-jdbc.xml + /WEB-INF/spring/applicationContext-jdbc.xml - + com.springsource.org.hibernate + 3.3.2.GA org.hibernate @@ -110,16 +98,6 @@ 5.1.6 --> - - org.jdom - com.springsource.org.jdom - 1.0.0 - - - org.springframework - org.springframework.asm - ${spring.version} - org.springframework org.springframework.aspects @@ -140,31 +118,6 @@ org.springframework.web.servlet ${spring.version} - - - org.junit - com.springsource.org.junit - 4.5.0 - test - - - org.springframework - org.springframework.test - ${spring.version} - test - - - javax.transaction - com.springsource.javax.transaction - 1.1.0 - test - - - org.hibernate - com.springsource.org.hibernate.annotations - 3.4.0.GA - test - org.slf4j com.springsource.slf4j.org.apache.commons.logging @@ -179,17 +132,20 @@ org.slf4j com.springsource.slf4j.log4j ${slf4j.version} - - - log4j - log4j - - - org.apache.log4j - com.springsource.org.apache.log4j - - + + + org.junit + com.springsource.org.junit + 4.5.0 + test + + + org.springframework + org.springframework.test + ${spring.version} + test + @@ -197,36 +153,21 @@ SpringSource Enterprise Bundle Repository - SpringSource Releases http://repository.springsource.com/maven/bundles/release - - com.springsource.repository.bundles.milestone - SpringSource Enterprise Bundle Repository - SpringSource Milestones - http://repository.springsource.com/maven/bundles/milestone - com.springsource.repository.bundles.external SpringSource Enterprise Bundle Repository - External Releases http://repository.springsource.com/maven/bundles/external + + com.springsource.repository.bundles.milestone + SpringSource Enterprise Bundle Repository - SpringSource Milestones + http://repository.springsource.com/maven/bundles/milestone + com.springsource.repository.bundles.snapshot SpringSource Enterprise Bundle Repository - Snapshot Releases http://repository.springsource.com/maven/bundles/snapshot - - spring-release - Spring Portfolio Release Repository - http://maven.springframework.org/release - - - spring-external - Spring Portfolio External Repository - http://maven.springframework.org/external - - - spring-milestone - Spring Portfolio Milestone Repository - http://maven.springframework.org/milestone - From 3dc88e069a6e909529a9a6eb5540c1bb64b149f3 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 16 Dec 2009 16:44:43 +0000 Subject: [PATCH 041/887] polish --- pom.xml | 8 ++++- .../petclinic/AbstractClinicTests-context.xml | 33 ++++++++++++------- .../jpa/applicationContext-jpaCommon.xml | 32 +++++++++++------- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index 5883e8e37..71f127ba1 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ javax.persistence com.springsource.javax.persistence 1.0.0 - + javax.servlet com.springsource.javax.servlet @@ -146,6 +146,12 @@ ${spring.version} test + + javax.transaction + com.springsource.javax.transaction + 1.1.0 + test + diff --git a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml index 3f79cbc09..af4c40bfc 100644 --- a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml +++ b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml @@ -1,22 +1,31 @@ + xmlns:p="http://www.springframework.org/schema/p" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:jdbc="http://www.springframework.org/schema/jdbc" + xmlns:tx="http://www.springframework.org/schema/tx" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> - + - + + + + + + + + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml index b873dfc47..33a2eb1a8 100644 --- a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml @@ -1,21 +1,30 @@ + xmlns:p="http://www.springframework.org/schema/p" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:jdbc="http://www.springframework.org/schema/jdbc" + xmlns:tx="http://www.springframework.org/schema/tx" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> - + + + + + + + + + + Date: Wed, 16 Dec 2009 16:54:41 +0000 Subject: [PATCH 042/887] polish --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 71f127ba1..7559af78e 100644 --- a/pom.xml +++ b/pom.xml @@ -151,6 +151,12 @@ com.springsource.javax.transaction 1.1.0 test + + + org.hibernate + com.springsource.org.hibernate.annotations + 3.4.0.GA + test From ef838ad656dd4c804e85fd630005f41da63c9e71 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 16 Dec 2009 16:59:09 +0000 Subject: [PATCH 043/887] Switched to embedded db --- .../petclinic/AbstractClinicTests-context.xml | 13 +++---------- .../petclinic/jpa/applicationContext-jpaCommon.xml | 11 ++--------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml index af4c40bfc..a0bc4bd00 100644 --- a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml +++ b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml @@ -16,16 +16,9 @@ - - - - - - + - - + + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml index 33a2eb1a8..f5fbe563f 100644 --- a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml @@ -14,17 +14,10 @@ - - - - - - + - + Date: Wed, 16 Dec 2009 17:16:10 +0000 Subject: [PATCH 044/887] removed test suite class --- .../samples/petclinic/PetClinicTestSuite.java | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java diff --git a/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java b/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java deleted file mode 100644 index d56199399..000000000 --- a/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.springframework.samples.petclinic; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; -import org.springframework.samples.petclinic.hibernate.HibernateClinicTests; -import org.springframework.samples.petclinic.jdbc.SimpleJdbcClinicTests; -import org.springframework.samples.petclinic.jpa.EntityManagerClinicTests; -import org.springframework.samples.petclinic.jpa.HibernateEntityManagerClinicTests; -import org.springframework.samples.petclinic.jpa.OpenJpaEntityManagerClinicTests; -import org.springframework.samples.petclinic.web.VisitsAtomViewTest; - -/** - * JUnit 4 based test suite for all PetClinic tests. - * - * @author Sam Brannen - */ -@RunWith(Suite.class) -@SuiteClasses({ - OwnerTests.class, - SimpleJdbcClinicTests.class, - HibernateClinicTests.class, - EntityManagerClinicTests.class, - HibernateEntityManagerClinicTests.class, - OpenJpaEntityManagerClinicTests.class, - VisitsAtomViewTest.class -}) -public class PetClinicTestSuite { -} From 31733db715e82e4eae554bb8fac48f7e6f043dd8 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 16 Dec 2009 17:25:22 +0000 Subject: [PATCH 045/887] fixed test suite failing --- .../samples/petclinic/hibernate/HibernateClinicTests.java | 2 ++ .../samples/petclinic/jdbc/SimpleJdbcClinicTests.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java index 3c275c820..4f50d7231 100644 --- a/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java @@ -1,6 +1,7 @@ package org.springframework.samples.petclinic.hibernate; import org.springframework.samples.petclinic.AbstractClinicTests; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; /** @@ -15,6 +16,7 @@ import org.springframework.test.context.ContextConfiguration; * @author Sam Brannen */ @ContextConfiguration +@DirtiesContext public class HibernateClinicTests extends AbstractClinicTests { } diff --git a/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java index 709100d1a..f44baeb12 100644 --- a/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java @@ -1,6 +1,7 @@ package org.springframework.samples.petclinic.jdbc; import org.springframework.samples.petclinic.AbstractClinicTests; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; /** @@ -14,6 +15,7 @@ import org.springframework.test.context.ContextConfiguration; * @author Thomas Risberg */ @ContextConfiguration +@DirtiesContext public class SimpleJdbcClinicTests extends AbstractClinicTests { } From bd07ffc47e599ee4d664932b58576963b26451c3 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 16 Dec 2009 20:22:37 +0000 Subject: [PATCH 046/887] polish --- pom.xml | 219 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 128 insertions(+), 91 deletions(-) diff --git a/pom.xml b/pom.xml index 7559af78e..b87496f45 100644 --- a/pom.xml +++ b/pom.xml @@ -12,21 +12,126 @@ 1.5.6 + + + + org.springframework + org.springframework.context + ${spring.version} + + + + org.apache.commons.logging + com.springsource.org.apache.commons.logging + + + + + org.springframework + org.springframework.aspects + ${spring.version} + + + org.aspectj + com.springsource.org.aspectj.weaver + 1.6.5.RELEASE + + + org.springframework + org.springframework.orm + ${spring.version} + + + org.springframework + org.springframework.oxm + ${spring.version} + + + org.springframework + org.springframework.web.servlet + ${spring.version} + + + + + org.slf4j + com.springsource.slf4j.org.apache.commons.logging + ${slf4j.version} + runtime + + + org.slf4j + com.springsource.slf4j.api + ${slf4j.version} + + + org.slf4j + com.springsource.slf4j.log4j + ${slf4j.version} + runtime + + + org.apache.log4j + com.springsource.org.apache.log4j + 1.2.15 + runtime + + + + + org.apache.commons + com.springsource.org.apache.commons.dbcp + 1.2.2.osgi + + + org.hsqldb + com.springsource.org.hsqldb + 1.8.0.9 + + + + + + + org.hibernate + com.springsource.org.hibernate + 3.3.2.GA + + + + + javax.persistence + com.springsource.javax.persistence + 1.0.0 + + com.oracle.toplink.essentials com.springsource.oracle.toplink.essentials 2.0.0.b41-beta2 + - com.sun.syndication - com.springsource.com.sun.syndication - 1.0.0 + org.hibernate + com.springsource.org.hibernate.ejb + 3.4.0.GA + runtime + - javax.persistence - com.springsource.javax.persistence - 1.0.0 - + org.apache.openjpa + com.springsource.org.apache.openjpa + 1.1.0 + runtime + + + javax.servlet com.springsource.javax.servlet @@ -44,95 +149,26 @@ com.springsource.javax.servlet.jsp.jstl 1.2.0 + + org.apache.taglibs + com.springsource.org.apache.taglibs.standard + 1.1.2 + + + + + com.sun.syndication + com.springsource.com.sun.syndication + 1.0.0 + + javax.xml.bind com.springsource.javax.xml.bind 2.1.7 provided - - org.apache.commons - com.springsource.org.apache.commons.dbcp - 1.2.2.osgi - - - org.apache.log4j - com.springsource.org.apache.log4j - 1.2.15 - - - org.apache.openjpa - com.springsource.org.apache.openjpa - 1.1.0 - - - org.apache.taglibs - com.springsource.org.apache.taglibs.standard - 1.1.2 - - - org.aspectj - com.springsource.org.aspectj.weaver - 1.6.5.RELEASE - - - org.hibernate - com.springsource.org.hibernate - 3.3.2.GA - - - org.hibernate - com.springsource.org.hibernate.ejb - 3.4.0.GA - - - org.hsqldb - com.springsource.org.hsqldb - 1.8.0.9 - - - - - org.springframework - org.springframework.aspects - ${spring.version} - - - org.springframework - org.springframework.orm - ${spring.version} - - - org.springframework - org.springframework.oxm - ${spring.version} - - - org.springframework - org.springframework.web.servlet - ${spring.version} - - - org.slf4j - com.springsource.slf4j.org.apache.commons.logging - ${slf4j.version} - - - org.slf4j - com.springsource.slf4j.api - ${slf4j.version} - - - org.slf4j - com.springsource.slf4j.log4j - ${slf4j.version} - + org.junit @@ -157,7 +193,8 @@ com.springsource.org.hibernate.annotations 3.4.0.GA test - + + From c0a9be95fb8f237dbd8b34ee0d158fa23a0295b4 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 17 Dec 2009 17:12:21 +0000 Subject: [PATCH 047/887] commons logging exclusion for openjpa --- pom.xml | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index b87496f45..e7da6cc99 100644 --- a/pom.xml +++ b/pom.xml @@ -26,16 +26,6 @@ - - org.springframework - org.springframework.aspects - ${spring.version} - - - org.aspectj - com.springsource.org.aspectj.weaver - 1.6.5.RELEASE - org.springframework org.springframework.orm @@ -52,6 +42,18 @@ ${spring.version} + + + org.springframework + org.springframework.aspects + ${spring.version} + + + org.aspectj + com.springsource.org.aspectj.weaver + 1.6.5.RELEASE + + org.slf4j @@ -129,6 +131,13 @@ com.springsource.org.apache.openjpa 1.1.0 runtime + + + + org.apache.commons.logging + com.springsource.org.apache.commons.logging + + @@ -199,22 +208,22 @@ com.springsource.repository.bundles.release - SpringSource Enterprise Bundle Repository - SpringSource Releases + EBR Spring Releases http://repository.springsource.com/maven/bundles/release com.springsource.repository.bundles.external - SpringSource Enterprise Bundle Repository - External Releases + EBR External Releases http://repository.springsource.com/maven/bundles/external com.springsource.repository.bundles.milestone - SpringSource Enterprise Bundle Repository - SpringSource Milestones + EBR Spring Milestones http://repository.springsource.com/maven/bundles/milestone com.springsource.repository.bundles.snapshot - SpringSource Enterprise Bundle Repository - Snapshot Releases + EBR Spring Snapshots http://repository.springsource.com/maven/bundles/snapshot From 905d9824b012ee6eceb8305cd15d521c3b4d1956 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 17 Dec 2009 17:34:12 +0000 Subject: [PATCH 048/887] + improved war structure --- .settings/org.eclipse.wst.common.component | 20 +++---- pom.xml | 53 +++++++++++-------- .../classes => resources}/META-INF/aop.xml | 0 .../META-INF/jpa-persistence.xml | 0 .../classes => resources}/META-INF/orm.xml | 0 .../webapp/WEB-INF/classes/log4j.properties | 18 ------- .../WEB-INF/classes/messages.properties | 8 --- .../WEB-INF/classes/messages_de.properties | 8 --- .../WEB-INF/classes/messages_en.properties | 1 - src/main/webapp/WEB-INF/web.xml | 6 ++- .../petclinic/jpa/AbstractJpaClinicTests.java | 3 +- 11 files changed, 45 insertions(+), 72 deletions(-) rename src/main/{webapp/WEB-INF/classes => resources}/META-INF/aop.xml (100%) rename src/main/{webapp/WEB-INF/classes => resources}/META-INF/jpa-persistence.xml (100%) rename src/main/{webapp/WEB-INF/classes => resources}/META-INF/orm.xml (100%) delete mode 100644 src/main/webapp/WEB-INF/classes/log4j.properties delete mode 100644 src/main/webapp/WEB-INF/classes/messages.properties delete mode 100644 src/main/webapp/WEB-INF/classes/messages_de.properties delete mode 100644 src/main/webapp/WEB-INF/classes/messages_en.properties diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 89d4f2ab5..429be379d 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,10 +1,10 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/pom.xml b/pom.xml index e7da6cc99..6bce6af6d 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,16 @@ + + org.springframework + org.springframework.aspects + ${spring.version} + + + org.aspectj + com.springsource.org.aspectj.weaver + 1.6.5.RELEASE + org.springframework org.springframework.orm @@ -42,18 +52,6 @@ ${spring.version} - - - org.springframework - org.springframework.aspects - ${spring.version} - - - org.aspectj - com.springsource.org.aspectj.weaver - 1.6.5.RELEASE - - org.slf4j @@ -131,13 +129,6 @@ com.springsource.org.apache.openjpa 1.1.0 runtime - - - - org.apache.commons.logging - com.springsource.org.apache.commons.logging - - @@ -208,22 +199,22 @@ com.springsource.repository.bundles.release - EBR Spring Releases + SpringSource Enterprise Bundle Repository - SpringSource Releases http://repository.springsource.com/maven/bundles/release com.springsource.repository.bundles.external - EBR External Releases + SpringSource Enterprise Bundle Repository - External Releases http://repository.springsource.com/maven/bundles/external com.springsource.repository.bundles.milestone - EBR Spring Milestones + SpringSource Enterprise Bundle Repository - SpringSource Milestones http://repository.springsource.com/maven/bundles/milestone com.springsource.repository.bundles.snapshot - EBR Spring Snapshots + SpringSource Enterprise Bundle Repository - Snapshot Releases http://repository.springsource.com/maven/bundles/snapshot @@ -239,6 +230,22 @@ true + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*Tests.java + + + + + org.apache.maven.plugins + maven-war-plugin + + petclinic + + org.apache.maven.plugins maven-dependency-plugin diff --git a/src/main/webapp/WEB-INF/classes/META-INF/aop.xml b/src/main/resources/META-INF/aop.xml similarity index 100% rename from src/main/webapp/WEB-INF/classes/META-INF/aop.xml rename to src/main/resources/META-INF/aop.xml diff --git a/src/main/webapp/WEB-INF/classes/META-INF/jpa-persistence.xml b/src/main/resources/META-INF/jpa-persistence.xml similarity index 100% rename from src/main/webapp/WEB-INF/classes/META-INF/jpa-persistence.xml rename to src/main/resources/META-INF/jpa-persistence.xml diff --git a/src/main/webapp/WEB-INF/classes/META-INF/orm.xml b/src/main/resources/META-INF/orm.xml similarity index 100% rename from src/main/webapp/WEB-INF/classes/META-INF/orm.xml rename to src/main/resources/META-INF/orm.xml diff --git a/src/main/webapp/WEB-INF/classes/log4j.properties b/src/main/webapp/WEB-INF/classes/log4j.properties deleted file mode 100644 index ebee551aa..000000000 --- a/src/main/webapp/WEB-INF/classes/log4j.properties +++ /dev/null @@ -1,18 +0,0 @@ -# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml! -# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J. -log4j.rootLogger=INFO, stdout, logfile - -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n - -log4j.appender.logfile=org.apache.log4j.RollingFileAppender -log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log -log4j.appender.logfile.MaxFileSize=512KB -# Keep three backup files. -log4j.appender.logfile.MaxBackupIndex=3 -# Pattern to output: date priority [category] - message -log4j.appender.logfile.layout=org.apache.log4j.PatternLayout -log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n - -log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG diff --git a/src/main/webapp/WEB-INF/classes/messages.properties b/src/main/webapp/WEB-INF/classes/messages.properties deleted file mode 100644 index 173417a10..000000000 --- a/src/main/webapp/WEB-INF/classes/messages.properties +++ /dev/null @@ -1,8 +0,0 @@ -welcome=Welcome -required=is required -notFound=has not been found -duplicate=is already in use -nonNumeric=must be all numeric -duplicateFormSubmission=Duplicate form submission is not allowed -typeMismatch.date=invalid date -typeMismatch.birthDate=invalid date diff --git a/src/main/webapp/WEB-INF/classes/messages_de.properties b/src/main/webapp/WEB-INF/classes/messages_de.properties deleted file mode 100644 index 124bee48b..000000000 --- a/src/main/webapp/WEB-INF/classes/messages_de.properties +++ /dev/null @@ -1,8 +0,0 @@ -welcome=Willkommen -required=muss angegeben werden -notFound=wurde nicht gefunden -duplicate=ist bereits vergeben -nonNumeric=darf nur numerisch sein -duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt -typeMismatch.date=ungltiges Datum -typeMismatch.birthDate=ungltiges Datum diff --git a/src/main/webapp/WEB-INF/classes/messages_en.properties b/src/main/webapp/WEB-INF/classes/messages_en.properties deleted file mode 100644 index 05d519bb8..000000000 --- a/src/main/webapp/WEB-INF/classes/messages_en.properties +++ /dev/null @@ -1 +0,0 @@ -# This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file. \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index b4af82221..4d7a09ab9 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -45,8 +45,10 @@ diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java index 251af819d..d8adc9183 100644 --- a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java @@ -195,5 +195,4 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { p7 = this.clinic.loadPet(7); assertEquals(found + 1, p7.getVisits().size()); } - -} +} \ No newline at end of file From 57e17d32b285d63c96747e5fed059ef1ea4cb529 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 17 Dec 2009 18:51:44 +0000 Subject: [PATCH 049/887] finally got rid of commons logging --- .settings/org.eclipse.wst.common.component | 20 +++--- pom.xml | 71 +++++++++++++++------- 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 429be379d..89d4f2ab5 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,10 +1,10 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 6bce6af6d..f4ca9008f 100644 --- a/pom.xml +++ b/pom.xml @@ -19,23 +19,13 @@ org.springframework.context ${spring.version} - + org.apache.commons.logging com.springsource.org.apache.commons.logging - + - - org.springframework - org.springframework.aspects - ${spring.version} - - - org.aspectj - com.springsource.org.aspectj.weaver - 1.6.5.RELEASE - org.springframework org.springframework.orm @@ -52,6 +42,20 @@ ${spring.version} + + + org.aspectj + com.springsource.org.aspectj.weaver + 1.6.5.RELEASE + optional + + + org.springframework + org.springframework.aspects + ${spring.version} + optional + + org.slf4j @@ -102,6 +106,7 @@ org.hibernate com.springsource.org.hibernate 3.3.2.GA + optional @@ -109,26 +114,56 @@ javax.persistence com.springsource.javax.persistence 1.0.0 + optional com.oracle.toplink.essentials com.springsource.oracle.toplink.essentials 2.0.0.b41-beta2 + optional org.hibernate com.springsource.org.hibernate.ejb 3.4.0.GA - runtime + optional + + + + org.apache.commons.logging + com.springsource.org.apache.commons.logging + + + + org.hibernate + com.springsource.org.hibernate.annotations + 3.4.0.GA + optional + + + + org.apache.commons.logging + com.springsource.org.apache.commons.logging + + + + org.apache.openjpa com.springsource.org.apache.openjpa 1.1.0 - runtime + optional + + + + org.apache.commons.logging + com.springsource.org.apache.commons.logging + + @@ -188,13 +223,7 @@ 1.1.0 test - - org.hibernate - com.springsource.org.hibernate.annotations - 3.4.0.GA - test - - + From bcda93f280e9174f4e5c44fc830a864a963633a5 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 21:37:18 +0000 Subject: [PATCH 050/887] Slf4j update --- pom.xml | 2 +- .../samples/petclinic/aspects/AbstractTraceAspect.java | 6 +++--- .../samples/petclinic/jdbc/SimpleJdbcClinic.java | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index f4ca9008f..22a3c6067 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 1.0.0-SNAPSHOT 3.0.0.RELEASE - 1.5.6 + 1.5.10 diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java index 26d32359f..977bb684f 100644 --- a/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java +++ b/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java @@ -1,11 +1,11 @@ package org.springframework.samples.petclinic.aspects; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Aspect to illustrate Spring-driven load-time weaving. @@ -16,7 +16,7 @@ import org.aspectj.lang.annotation.Pointcut; @Aspect public abstract class AbstractTraceAspect { - private static final Log logger = LogFactory.getLog(AbstractTraceAspect.class); + private static final Logger logger = LoggerFactory.getLogger(AbstractTraceAspect.class); @Pointcut public abstract void traced(); diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java index 587acecb9..1d9894d38 100644 --- a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java +++ b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java @@ -8,9 +8,8 @@ import java.util.List; import javax.sql.DataSource; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; @@ -57,7 +56,7 @@ import org.springframework.transaction.annotation.Transactional; @ManagedResource("petclinic:type=Clinic") public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean { - private final Log logger = LogFactory.getLog(getClass()); + private final Logger logger = LoggerFactory.getLogger(getClass()); private SimpleJdbcTemplate simpleJdbcTemplate; From d7f75cfdb9329bfdbaaba92b69cde8d8c1ed880a Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 21:49:29 +0000 Subject: [PATCH 051/887] Fixed pom optional bugs --- pom.xml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 22a3c6067..ddba70977 100644 --- a/pom.xml +++ b/pom.xml @@ -47,27 +47,27 @@ org.aspectj com.springsource.org.aspectj.weaver 1.6.5.RELEASE - optional + true org.springframework org.springframework.aspects ${spring.version} - optional + true + + org.slf4j + com.springsource.slf4j.api + ${slf4j.version} + org.slf4j com.springsource.slf4j.org.apache.commons.logging ${slf4j.version} runtime - - org.slf4j - com.springsource.slf4j.api - ${slf4j.version} - org.slf4j com.springsource.slf4j.log4j @@ -106,7 +106,7 @@ org.hibernate com.springsource.org.hibernate 3.3.2.GA - optional + true @@ -114,21 +114,20 @@ javax.persistence com.springsource.javax.persistence 1.0.0 - optional com.oracle.toplink.essentials com.springsource.oracle.toplink.essentials 2.0.0.b41-beta2 - optional + true org.hibernate com.springsource.org.hibernate.ejb 3.4.0.GA - optional + true @@ -141,7 +140,7 @@ org.hibernate com.springsource.org.hibernate.annotations 3.4.0.GA - optional + true @@ -149,14 +148,14 @@ com.springsource.org.apache.commons.logging - + org.apache.openjpa com.springsource.org.apache.openjpa 1.1.0 - optional + true From 33a5c878e3098f3afde49d3318c389274514b210 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 21:55:55 +0000 Subject: [PATCH 052/887] tweaks --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index ddba70977..c8de38f22 100644 --- a/pom.xml +++ b/pom.xml @@ -86,11 +86,13 @@ org.apache.commons com.springsource.org.apache.commons.dbcp 1.2.2.osgi + runtime org.hsqldb com.springsource.org.hsqldb 1.8.0.9 + runtime From 58fe4779a5adf6d4ee3a9f6f0715b30f581d5dd7 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 22:12:52 +0000 Subject: [PATCH 053/887] correct commons logging exclude --- pom.xml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index c8de38f22..90e37b899 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ - org.apache.commons.logging + org.apache.commons com.springsource.org.apache.commons.logging @@ -134,7 +134,7 @@ - org.apache.commons.logging + org.apache.commons com.springsource.org.apache.commons.logging @@ -147,12 +147,11 @@ - org.apache.commons.logging + org.apache.commons com.springsource.org.apache.commons.logging - - + org.apache.openjpa @@ -162,7 +161,7 @@ - org.apache.commons.logging + org.apache.commons com.springsource.org.apache.commons.logging From 9ef38c5e972ee8bcf0ef3a240be95c88339073de Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 22:14:21 +0000 Subject: [PATCH 054/887] polish --- .springBeans | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.springBeans b/.springBeans index 618a2584b..34b281cf1 100644 --- a/.springBeans +++ b/.springBeans @@ -1,7 +1,7 @@ 1 - + From dee6a358d6da60928dcaedb73661cb8070913d13 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 22:16:35 +0000 Subject: [PATCH 055/887] aspectj is required --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 90e37b899..667f99637 100644 --- a/pom.xml +++ b/pom.xml @@ -47,13 +47,11 @@ org.aspectj com.springsource.org.aspectj.weaver 1.6.5.RELEASE - true org.springframework org.springframework.aspects ${spring.version} - true From 6d0d36f35b70a3df40ad4e87998ae799ab258bae Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 22:21:35 +0000 Subject: [PATCH 056/887] polish --- pom.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 667f99637..290393108 100644 --- a/pom.xml +++ b/pom.xml @@ -48,11 +48,6 @@ com.springsource.org.aspectj.weaver 1.6.5.RELEASE - - org.springframework - org.springframework.aspects - ${spring.version} - @@ -115,7 +110,7 @@ com.springsource.javax.persistence 1.0.0 true - + com.oracle.toplink.essentials From 6f1ca5ddaa95ba23723c85694247489915ace28e Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 22:29:37 +0000 Subject: [PATCH 057/887] format --- pom.xml | 130 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/pom.xml b/pom.xml index 290393108..7962bdda0 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 1.5.10 - + org.springframework @@ -23,8 +23,8 @@ org.apache.commons com.springsource.org.apache.commons.logging - - + + org.springframework @@ -41,32 +41,32 @@ org.springframework.web.servlet ${spring.version} - + org.aspectj com.springsource.org.aspectj.weaver 1.6.5.RELEASE - + - - org.slf4j - com.springsource.slf4j.api - ${slf4j.version} - - - org.slf4j - com.springsource.slf4j.org.apache.commons.logging - ${slf4j.version} - runtime - - - org.slf4j - com.springsource.slf4j.log4j - ${slf4j.version} - runtime - + + org.slf4j + com.springsource.slf4j.api + ${slf4j.version} + + + org.slf4j + com.springsource.slf4j.org.apache.commons.logging + ${slf4j.version} + runtime + + + org.slf4j + com.springsource.slf4j.log4j + ${slf4j.version} + runtime + org.apache.log4j com.springsource.org.apache.log4j @@ -79,8 +79,8 @@ org.apache.commons com.springsource.org.apache.commons.dbcp 1.2.2.osgi - runtime - + runtime + org.hsqldb com.springsource.org.hsqldb @@ -89,13 +89,11 @@ - + com.mysql.jdbc + com.springsource.com.mysql.jdbc + 5.1.6 + --> + org.hibernate @@ -103,20 +101,20 @@ 3.3.2.GA true - + javax.persistence com.springsource.javax.persistence 1.0.0 - true - + true + com.oracle.toplink.essentials com.springsource.oracle.toplink.essentials 2.0.0.b41-beta2 - true + true @@ -129,20 +127,20 @@ org.apache.commons com.springsource.org.apache.commons.logging - - + + - org.hibernate - com.springsource.org.hibernate.annotations - 3.4.0.GA + org.hibernate + com.springsource.org.hibernate.annotations + 3.4.0.GA true org.apache.commons com.springsource.org.apache.commons.logging - + @@ -156,8 +154,8 @@ org.apache.commons com.springsource.org.apache.commons.logging - - + + @@ -182,7 +180,7 @@ org.apache.taglibs com.springsource.org.apache.taglibs.standard 1.1.2 - + @@ -209,13 +207,13 @@ org.springframework org.springframework.test ${spring.version} - test + test - javax.transaction - com.springsource.javax.transaction - 1.1.0 - test + javax.transaction + com.springsource.javax.transaction + 1.1.0 + test @@ -247,28 +245,28 @@ org.apache.maven.plugins maven-compiler-plugin - true + true 1.5 1.5 true - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*Tests.java - - - - - org.apache.maven.plugins - maven-war-plugin - - petclinic - - + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*Tests.java + + + + + org.apache.maven.plugins + maven-war-plugin + + petclinic + + org.apache.maven.plugins maven-dependency-plugin From 6f6d9508470262674c2f6983df54f189ff40bb52 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 19 Dec 2009 22:36:19 +0000 Subject: [PATCH 058/887] jdom needed for rome --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 7962bdda0..ae9af57f6 100644 --- a/pom.xml +++ b/pom.xml @@ -188,6 +188,13 @@ com.springsource.com.sun.syndication 1.0.0 + + org.jdom + com.springsource.org.jdom + 1.1.0 + runtime + + javax.xml.bind From 1f59a262c37d89e1dc55294140c8945e30a312f0 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Mon, 25 Jan 2010 17:11:59 +0000 Subject: [PATCH 059/887] + add comment about Tomcat 6 --- src/main/webapp/META-INF/context.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml index 89e3be4bd..fb6b09c3b 100644 --- a/src/main/webapp/META-INF/context.xml +++ b/src/main/webapp/META-INF/context.xml @@ -1,7 +1,7 @@ - + From 84455ff3a2aad8baae37f4e8ab5db6caecc6cdd0 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 3 Feb 2010 22:15:30 +0000 Subject: [PATCH 060/887] + update commons-pool to 1.5.3 to avoid some memory leaks --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index ae9af57f6..9ba67ac96 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,12 @@ 1.2.2.osgi runtime + + org.apache.commons + com.springsource.org.apache.commons.pool + 1.5.3 + runtime + org.hsqldb com.springsource.org.hsqldb From a7ae7df3a8a85ed841d1c05e437a99e9c4c936a8 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 4 Feb 2010 17:48:51 +0000 Subject: [PATCH 061/887] + upgrade to AJ 1.6.8 + add dedicated section for Tomcat 5.5 and Tomcat 6 LTW setup (so it's clearer) --- pom.xml | 4 ++-- src/main/webapp/META-INF/context.xml | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 9ba67ac96..0e02dcb04 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 1.0.0-SNAPSHOT 3.0.0.RELEASE - 1.5.10 + 1.5.6 @@ -46,7 +46,7 @@ org.aspectj com.springsource.org.aspectj.weaver - 1.6.5.RELEASE + 1.6.8.RELEASE diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml index fb6b09c3b..25356f60d 100644 --- a/src/main/webapp/META-INF/context.xml +++ b/src/main/webapp/META-INF/context.xml @@ -1,8 +1,14 @@ - + + + + + From ffd7a4602cabac9baba45bd822caa25c4fcb2f25 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 4 Feb 2010 19:07:55 +0000 Subject: [PATCH 062/887] + removed optional marker on some dependencies so they get included in the final war --- pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pom.xml b/pom.xml index 0e02dcb04..c2df70380 100644 --- a/pom.xml +++ b/pom.xml @@ -105,7 +105,6 @@ org.hibernate com.springsource.org.hibernate 3.3.2.GA - true @@ -113,21 +112,18 @@ javax.persistence com.springsource.javax.persistence 1.0.0 - true com.oracle.toplink.essentials com.springsource.oracle.toplink.essentials 2.0.0.b41-beta2 - true org.hibernate com.springsource.org.hibernate.ejb 3.4.0.GA - true @@ -140,7 +136,6 @@ org.hibernate com.springsource.org.hibernate.annotations 3.4.0.GA - true @@ -154,7 +149,6 @@ org.apache.openjpa com.springsource.org.apache.openjpa 1.1.0 - true From 4bf4f8e3d33355e21cd539291c76a0b55011fd4c Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 4 Feb 2010 19:40:47 +0000 Subject: [PATCH 063/887] + add aspects jar back to the war --- pom.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c2df70380..36cd8d29c 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,11 @@ org.springframework.web.servlet ${spring.version} - + + org.springframework + org.springframework.aspects + ${spring.version} + org.aspectj From 973c45ba2d722260e5ea71985f3b3bee028faba4 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 18 Feb 2010 22:11:04 +0000 Subject: [PATCH 064/887] date picker --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 36cd8d29c..f0c6167f6 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ org.junit com.springsource.org.junit - 4.5.0 + 4.7.0 test From 0b9d98ba1ce8f18b63a80123b86426bae7ac175b Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Mon, 19 Jul 2010 14:20:39 +0000 Subject: [PATCH 065/887] disable welcome files (for Servlet 3 compatibility) --- src/main/webapp/WEB-INF/web.xml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 4d7a09ab9..768329b1b 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -147,16 +147,16 @@ / - - httpMethodFilter - org.springframework.web.filter.HiddenHttpMethodFilter - + + httpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + + httpMethodFilter + petclinic + - - httpMethodFilter - petclinic - - 10 @@ -167,6 +167,12 @@ /WEB-INF/jsp/uncaughtException.jsp + + + + + + - + \ No newline at end of file From 7cbfaf1726cd9d7e1620538d4bfbd005e3a2f20e Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Thu, 2 Sep 2010 07:51:24 +0000 Subject: [PATCH 066/887] Fix Petclinic case-sensitivity problems against MySQL (SPR-7512) With thanks to Rob Winch for patch submission. --- src/main/resources/META-INF/orm.xml | 14 +++++++------- .../samples/petclinic/AbstractClinicTests.java | 4 ++-- .../petclinic/jpa/AbstractJpaClinicTests.java | 4 ++-- .../petclinic/AbstractClinicTests-context.xml | 9 ++++++--- .../petclinic/jpa/applicationContext-jpaCommon.xml | 12 ++++++++---- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/main/resources/META-INF/orm.xml b/src/main/resources/META-INF/orm.xml index d7c8f7040..7ea243ecf 100644 --- a/src/main/resources/META-INF/orm.xml +++ b/src/main/resources/META-INF/orm.xml @@ -42,10 +42,10 @@ - +
    - + @@ -56,11 +56,11 @@ -
    +
    -
    +
    @@ -75,7 +75,7 @@ -
    +
    @@ -101,11 +101,11 @@ -
    +
    -
    +
    diff --git a/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java b/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java index a69869186..63010dc34 100644 --- a/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java @@ -92,7 +92,7 @@ public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4Spr Collection vets = this.clinic.getVets(); // Use the inherited countRowsInTable() convenience method (from // AbstractTransactionalJUnit4SpringContextTests) to verify the results. - assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("VETS"), vets.size()); + assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("vets"), vets.size()); Vet v1 = EntityUtils.getById(vets, Vet.class, 2); assertEquals("Leary", v1.getLastName()); assertEquals(1, v1.getNrOfSpecialties()); @@ -107,7 +107,7 @@ public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4Spr @Test public void getPetTypes() { Collection petTypes = this.clinic.getPetTypes(); - assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("TYPES"), + assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("types"), petTypes.size()); PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1); assertEquals("cat", t1.getName()); diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java index d8adc9183..335297d90 100644 --- a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java @@ -83,7 +83,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { // Use the inherited countRowsInTable() convenience method (from // AbstractTransactionalDataSourceSpringContextTests) to verify the // results. - assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("VETS"), vets.size()); + assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("vets"), vets.size()); Vet v1 = EntityUtils.getById(vets, Vet.class, 2); assertEquals("Leary", v1.getLastName()); assertEquals(1, v1.getNrOfSpecialties()); @@ -97,7 +97,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { public void testGetPetTypes() { Collection petTypes = this.clinic.getPetTypes(); - assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("TYPES"), + assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("types"), petTypes.size()); PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1); assertEquals("cat", t1.getName()); diff --git a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml index a0bc4bd00..d048d8ae0 100644 --- a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml +++ b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml @@ -16,9 +16,12 @@ - + + + - - + diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml index f5fbe563f..3202f94c5 100644 --- a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml +++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml @@ -14,11 +14,16 @@ - + + + - - + + + @@ -30,5 +35,4 @@ - From 52d4b20d08a6041ffb8bd613e647504b4f5f11cb Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 19 Mar 2012 16:32:05 +0000 Subject: [PATCH 067/887] Apply patch from SPR-7894 --- .classpath | 4 ++-- .project | 4 ++-- src/main/webapp/WEB-INF/jsp/owners/form.jsp | 6 +++--- src/main/webapp/WEB-INF/jsp/pets/form.jsp | 8 ++++---- src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.classpath b/.classpath index 5e7d5199b..8122bbbe4 100644 --- a/.classpath +++ b/.classpath @@ -5,11 +5,11 @@ - + - \ No newline at end of file + diff --git a/.project b/.project index 87137c12c..239f04e3c 100644 --- a/.project +++ b/.project @@ -32,18 +32,18 @@ - org.maven.ide.eclipse.maven2Builder + org.eclipse.m2e.core.maven2Builder org.eclipse.jem.workbench.JavaEMFNature - org.maven.ide.eclipse.maven2Nature org.springframework.ide.eclipse.core.springnature org.eclipse.jdt.core.javanature org.eclipse.wst.common.project.facet.core.nature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.wst.jsdt.core.jsNature + org.eclipse.m2e.core.maven2Nature diff --git a/src/main/webapp/WEB-INF/jsp/owners/form.jsp b/src/main/webapp/WEB-INF/jsp/owners/form.jsp index 1670a7c1b..b4c2b2100 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/form.jsp @@ -1,11 +1,11 @@ <%@ include file="/WEB-INF/jsp/includes.jsp" %> <%@ include file="/WEB-INF/jsp/header.jsp" %> - + -

    New Owner:

    +

    New Owner:

    @@ -46,7 +46,7 @@
    - +

    diff --git a/src/main/webapp/WEB-INF/jsp/pets/form.jsp b/src/main/webapp/WEB-INF/jsp/pets/form.jsp index 459ec63b3..12f503db5 100644 --- a/src/main/webapp/WEB-INF/jsp/pets/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/pets/form.jsp @@ -1,11 +1,11 @@ <%@ include file="/WEB-INF/jsp/includes.jsp" %> <%@ include file="/WEB-INF/jsp/header.jsp" %> - + -

    New Pet

    +

    New Pet

    Owner: ${pet.owner.firstName} ${pet.owner.lastName}
    @@ -35,7 +35,7 @@
    - +

    @@ -47,7 +47,7 @@
    - +

    diff --git a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp index b1207a00f..97183f46c 100644 --- a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp @@ -1,7 +1,7 @@ <%@ include file="/WEB-INF/jsp/includes.jsp" %> <%@ include file="/WEB-INF/jsp/header.jsp" %> -

    New Visit:

    +

    New Visit:

    Pet: @@ -56,7 +56,7 @@ Description - + ${visit.description} From b5867402420f99ae4d91fc81e5a7ab4b9d050759 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 9 Jan 2013 17:12:37 +0800 Subject: [PATCH 068/887] removing authors --- authors.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 authors.txt diff --git a/authors.txt b/authors.txt new file mode 100644 index 000000000..f4edb9f56 --- /dev/null +++ b/authors.txt @@ -0,0 +1,25 @@ +aclement = Andy Clement +aemruli = Agim Emruli +apoutsma = Arjen Poutsma +bhale = Ben Hale +cbeams = Chris Beams +cdupuis = Christian Dupuis +cleau = Costin Leau +csampaleanu = Colin Sampaleanu +dsyer = David Syer +jgrelle = Jeremy Grelle +jhickey = Jennifer Hickey +jhoeller = Juergen Hoeller +kdonald = Keith Donald +ltaylor = Luke Taylor +mfisher = Mark Fisher +micha.kiener = Micha Kiener +misvy = Michael Isvy +mpollack = Mark Pollack +ogierke = Oliver Gierke +rharrop = Rob Harrop +rladdad = Ramnivas Laddad +rstoyanchev = Rossen Stoyanchev +sandrews = Scott Andrews +sbrannen = Sam Brannen +trisberg = Thomas Risberg \ No newline at end of file From 5f25d7483d6f3e5b296f32f408e44a4d6d59a61a Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 9 Jan 2013 17:12:47 +0800 Subject: [PATCH 069/887] removing authors --- authors.txt | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 authors.txt diff --git a/authors.txt b/authors.txt deleted file mode 100644 index f4edb9f56..000000000 --- a/authors.txt +++ /dev/null @@ -1,25 +0,0 @@ -aclement = Andy Clement -aemruli = Agim Emruli -apoutsma = Arjen Poutsma -bhale = Ben Hale -cbeams = Chris Beams -cdupuis = Christian Dupuis -cleau = Costin Leau -csampaleanu = Colin Sampaleanu -dsyer = David Syer -jgrelle = Jeremy Grelle -jhickey = Jennifer Hickey -jhoeller = Juergen Hoeller -kdonald = Keith Donald -ltaylor = Luke Taylor -mfisher = Mark Fisher -micha.kiener = Micha Kiener -misvy = Michael Isvy -mpollack = Mark Pollack -ogierke = Oliver Gierke -rharrop = Rob Harrop -rladdad = Ramnivas Laddad -rstoyanchev = Rossen Stoyanchev -sandrews = Scott Andrews -sbrannen = Sam Brannen -trisberg = Thomas Risberg \ No newline at end of file From 87ccf9fea13cc6b290d70fd82ef5974dba42d677 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 9 Jan 2013 17:24:48 +0800 Subject: [PATCH 070/887] first step of migration to Spring 3.2 (still in process) --- .classpath | 34 ++- .project | 15 +- .settings/.jsdtscope | 2 + .settings/org.eclipse.jdt.core.prefs | 12 +- ...clipse.jst.common.project.facet.core.prefs | 3 - .settings/org.eclipse.m2e.core.prefs | 4 + .settings/org.eclipse.m2e.wtp.prefs | 2 + .settings/org.eclipse.wst.common.component | 15 +- ....eclipse.wst.common.project.facet.core.xml | 8 +- README.md | 4 - .../.classpath | 14 - .../.project | 42 --- .../com.springsource.server.ide.jdt.core.xml | 2 - .../.settings/org.eclipse.jdt.core.prefs | 12 - ...clipse.jst.common.project.facet.core.prefs | 3 - .../org.eclipse.wst.common.component | 10 - ....eclipse.wst.common.project.facet.core.xml | 7 - .../org.eclipse.wst.validation.prefs | 6 - .../.settings/org.maven.ide.eclipse.prefs | 9 - ...ringframework.ide.eclipse.beans.core.prefs | 3 - ...org.springframework.ide.eclipse.core.prefs | 67 ----- .../.springBeans | 13 - org.springframework.samples.petclinic/pom.xml | 149 ----------- .../samples/petclinic/HomeController.java | 15 -- .../petclinic/appointments/Appointment.java | 37 --- .../appointments/AppointmentBook.java | 13 - .../appointments/AppointmentForm.java | 67 ----- .../petclinic/appointments/Appointments.java | 15 -- .../appointments/AppointmentsController.java | 42 --- .../appointments/StubAppointmentBook.java | 23 -- .../samples/petclinic/owners/Owner.java | 69 ----- .../petclinic/owners/OwnerController.java | 39 --- .../petclinic/owners/OwnerRepository.java | 13 - .../petclinic/owners/OwnerSearchForm.java | 15 -- .../petclinic/owners/OwnersController.java | 43 --- .../petclinic/owners/StubOwnerRepository.java | 22 -- .../samples/petclinic/owners/pets/Gender.java | 5 - .../samples/petclinic/owners/pets/Pet.java | 25 -- .../petclinic/owners/pets/PetController.java | 41 --- .../petclinic/owners/pets/PetRepository.java | 9 - .../owners/pets/StubPetRepository.java | 15 -- .../petclinic/util/ExternalContext.java | 22 -- .../samples/petclinic/util/Measurement.java | 10 - .../samples/petclinic/util/Unit.java | 5 - .../src/main/resources/log4j.xml | 42 --- .../WEB-INF/appointments/addNewForm.jsp | 31 --- .../webapp/WEB-INF/appointments/calendar.jsp | 2 - .../webapp/WEB-INF/appointments/content.jsp | 11 - .../src/main/webapp/WEB-INF/home.jsp | 6 - .../src/main/webapp/WEB-INF/layouts/page.jsp | 43 --- .../main/webapp/WEB-INF/owners/addNewForm.jsp | 15 -- .../main/webapp/WEB-INF/owners/content.jsp | 11 - .../src/main/webapp/WEB-INF/owners/owner.jsp | 2 - .../main/webapp/WEB-INF/owners/searchForm.jsp | 12 - .../webapp/WEB-INF/owners/searchResults.jsp | 2 - .../main/webapp/WEB-INF/spring/app-config.xml | 14 - .../main/webapp/WEB-INF/spring/mvc-config.xml | 37 --- .../src/main/webapp/WEB-INF/tiles.xml | 85 ------ .../src/main/webapp/WEB-INF/urlrewrite.xml | 16 -- .../src/main/webapp/WEB-INF/web.xml | 49 ---- .../src/main/webapp/styles/main.css | 0 .../src/test/resources/log4j.xml | 42 --- pom.xml | 252 +++++++----------- .../petclinic/jdbc/SimpleJdbcClinic.java | 6 +- ...entialsHSQLPlatformWithNativeSequence.java | 56 ---- .../petclinic/toplink/package-info.java | 10 - src/main/resources/log4j.dtd | 166 ++++++++++++ src/main/resources/log4j.properties | 18 -- src/main/resources/log4j.xml | 27 ++ src/main/webapp/WEB-INF/jsp/footer.jsp | 6 +- src/main/webapp/WEB-INF/jsp/header.jsp | 5 +- src/main/webapp/WEB-INF/jsp/owners/search.jsp | 54 ++-- src/main/webapp/WEB-INF/jsp/owners/show.jsp | 20 +- src/main/webapp/WEB-INF/jsp/welcome.jsp | 23 +- src/main/webapp/WEB-INF/petclinic-servlet.xml | 35 ++- .../spring/applicationContext-hibernate.xml | 6 +- src/main/webapp/images/banner-graphic.png | Bin 13773 -> 0 bytes src/main/webapp/images/pets.png | Bin 55318 -> 0 bytes src/main/webapp/images/springsource-logo.png | Bin 4974 -> 0 bytes .../webapp/{ => resources}/html/tutorial.html | 0 .../resources}/images/banner-graphic.png | Bin .../{ => resources}/images/bullet-arrow.png | Bin .../main/webapp/resources}/images/pets.png | Bin .../resources}/images/springsource-logo.png | Bin .../{ => resources}/images/submit-bg.png | Bin .../{ => resources}/styles/petclinic.css | 0 .../petclinic/AbstractClinicTests.java | 12 +- .../hibernate/HibernateClinicTests.java | 3 + .../petclinic/jpa/AbstractJpaClinicTests.java | 73 +++-- .../jpa/EntityManagerClinicTests.java | 24 +- .../HibernateEntityManagerClinicTests.java | 16 +- .../jpa/OpenJpaEntityManagerClinicTests.java | 27 -- .../HibernateClinicTests-context.xml | 13 +- .../jpa/applicationContext-openJpaAdapter.xml | 9 - .../jpa/applicationContext-toplinkAdapter.xml | 9 - 95 files changed, 507 insertions(+), 1764 deletions(-) delete mode 100644 .settings/org.eclipse.jst.common.project.facet.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 .settings/org.eclipse.m2e.wtp.prefs delete mode 100644 README.md delete mode 100644 org.springframework.samples.petclinic/.classpath delete mode 100644 org.springframework.samples.petclinic/.project delete mode 100644 org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml delete mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs delete mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs delete mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component delete mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml delete mode 100644 org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs delete mode 100644 org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs delete mode 100644 org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs delete mode 100644 org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs delete mode 100644 org.springframework.samples.petclinic/.springBeans delete mode 100644 org.springframework.samples.petclinic/pom.xml delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java delete mode 100644 org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java delete mode 100644 org.springframework.samples.petclinic/src/main/resources/log4j.xml delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml delete mode 100644 org.springframework.samples.petclinic/src/main/webapp/styles/main.css delete mode 100644 org.springframework.samples.petclinic/src/test/resources/log4j.xml delete mode 100644 src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/toplink/package-info.java create mode 100755 src/main/resources/log4j.dtd delete mode 100644 src/main/resources/log4j.properties create mode 100755 src/main/resources/log4j.xml delete mode 100644 src/main/webapp/images/banner-graphic.png delete mode 100644 src/main/webapp/images/pets.png delete mode 100644 src/main/webapp/images/springsource-logo.png rename src/main/webapp/{ => resources}/html/tutorial.html (100%) rename {org.springframework.samples.petclinic/src/main/webapp => src/main/webapp/resources}/images/banner-graphic.png (100%) rename src/main/webapp/{ => resources}/images/bullet-arrow.png (100%) rename {org.springframework.samples.petclinic/src/main/webapp => src/main/webapp/resources}/images/pets.png (100%) rename {org.springframework.samples.petclinic/src/main/webapp => src/main/webapp/resources}/images/springsource-logo.png (100%) rename src/main/webapp/{ => resources}/images/submit-bg.png (100%) rename src/main/webapp/{ => resources}/styles/petclinic.css (100%) delete mode 100644 src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java delete mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml delete mode 100644 src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml diff --git a/.classpath b/.classpath index 8122bbbe4..c99cf8646 100644 --- a/.classpath +++ b/.classpath @@ -1,15 +1,37 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/.project b/.project index 239f04e3c..7d7f5c1eb 100644 --- a/.project +++ b/.project @@ -1,9 +1,8 @@ - org.springframework.samples.petclinic - + spring-petclinic + NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. - Servers @@ -38,12 +37,12 @@ - org.eclipse.jem.workbench.JavaEMFNature org.springframework.ide.eclipse.core.springnature - org.eclipse.jdt.core.javanature - org.eclipse.wst.common.project.facet.core.nature - org.eclipse.wst.common.modulecore.ModuleCoreNature - org.eclipse.wst.jsdt.core.jsNature org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.jsdt.core.jsNature diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope index bbb8e68be..b72a6a47b 100644 --- a/.settings/.jsdtscope +++ b/.settings/.jsdtscope @@ -1,5 +1,7 @@ + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 9ec44e3e6..69c31cd49 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,8 @@ -#Tue Mar 17 10:00:21 EDT 2009 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.eclipse.jst.common.project.facet.core.prefs b/.settings/org.eclipse.jst.common.project.facet.core.prefs deleted file mode 100644 index 763a1503d..000000000 --- a/.settings/org.eclipse.jst.common.project.facet.core.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Tue Mar 17 09:59:19 EDT 2009 -classpath.helper/org.eclipse.jdt.launching.JRE_CONTAINER\:\:org.eclipse.jdt.internal.launching.macosx.MacOSXType\:\:JVM\ 1.5.0\ (MacOS\ X\ Default)/owners=jst.java\:5.0 -eclipse.preferences.version=1 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.m2e.wtp.prefs b/.settings/org.eclipse.m2e.wtp.prefs new file mode 100644 index 000000000..ef8608962 --- /dev/null +++ b/.settings/org.eclipse.m2e.wtp.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 89d4f2ab5..256741333 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,10 +1,11 @@ - - - - - - - + + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index d24a733bd..97d312c6a 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,7 +1,7 @@ - - - - + + + + diff --git a/README.md b/README.md deleted file mode 100644 index 560aaaa5e..000000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -spring-petclinic -================ - -sample application for the Spring framework \ No newline at end of file diff --git a/org.springframework.samples.petclinic/.classpath b/org.springframework.samples.petclinic/.classpath deleted file mode 100644 index 5c40e0b3f..000000000 --- a/org.springframework.samples.petclinic/.classpath +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/org.springframework.samples.petclinic/.project b/org.springframework.samples.petclinic/.project deleted file mode 100644 index ed4ca5e5a..000000000 --- a/org.springframework.samples.petclinic/.project +++ /dev/null @@ -1,42 +0,0 @@ - - - org.springframework.samples.petclinic - - - Servers - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.wst.common.project.facet.core.builder - - - - - org.eclipse.wst.validation.validationbuilder - - - - - org.springframework.ide.eclipse.core.springbuilder - - - - - org.maven.ide.eclipse.maven2Builder - - - - - - org.maven.ide.eclipse.maven2Nature - org.springframework.ide.eclipse.core.springnature - org.eclipse.jdt.core.javanature - org.eclipse.wst.common.project.facet.core.nature - org.eclipse.wst.common.modulecore.ModuleCoreNature - - diff --git a/org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml b/org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml deleted file mode 100644 index 0a4413c52..000000000 --- a/org.springframework.samples.petclinic/.settings/com.springsource.server.ide.jdt.core.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs b/org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 9ec44e3e6..000000000 --- a/org.springframework.samples.petclinic/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -#Tue Mar 17 10:00:21 EDT 2009 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs b/org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs deleted file mode 100644 index 763a1503d..000000000 --- a/org.springframework.samples.petclinic/.settings/org.eclipse.jst.common.project.facet.core.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Tue Mar 17 09:59:19 EDT 2009 -classpath.helper/org.eclipse.jdt.launching.JRE_CONTAINER\:\:org.eclipse.jdt.internal.launching.macosx.MacOSXType\:\:JVM\ 1.5.0\ (MacOS\ X\ Default)/owners=jst.java\:5.0 -eclipse.preferences.version=1 diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component deleted file mode 100644 index 89d4f2ab5..000000000 --- a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.component +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index d24a733bd..000000000 --- a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs b/org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs deleted file mode 100644 index 75abca5ce..000000000 --- a/org.springframework.samples.petclinic/.settings/org.eclipse.wst.validation.prefs +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 06 17:00:12 BST 2008 -DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator; -USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.common.componentcore.internal.ModuleCoreValidator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator; -USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.common.componentcore.internal.ModuleCoreValidator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator; -USER_PREFERENCE=overrideGlobalPreferencesfalse -eclipse.preferences.version=1 diff --git a/org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs b/org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs deleted file mode 100644 index 0b751087c..000000000 --- a/org.springframework.samples.petclinic/.settings/org.maven.ide.eclipse.prefs +++ /dev/null @@ -1,9 +0,0 @@ -#Tue Mar 17 14:28:16 EDT 2009 -activeProfiles= -eclipse.preferences.version=1 -fullBuildGoals=process-test-resources -includeModules=false -resolveWorkspaceProjects=true -resourceFilterGoals=process-resources resources\:testResources -skipCompilerPlugin=true -version=1 diff --git a/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs b/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs deleted file mode 100644 index a7eb2b337..000000000 --- a/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.beans.core.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Wed Dec 17 01:09:03 EST 2008 -eclipse.preferences.version=1 -org.springframework.ide.eclipse.beans.core.ignoreMissingNamespaceHandler=false diff --git a/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs b/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs deleted file mode 100644 index e096d67b6..000000000 --- a/org.springframework.samples.petclinic/.settings/org.springframework.ide.eclipse.core.prefs +++ /dev/null @@ -1,67 +0,0 @@ -#Tue Mar 17 10:00:21 EDT 2009 -eclipse.preferences.version=1 -org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true -org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=false -org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=true -org.springframework.ide.eclipse.core.enable.project.preferences=false -org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false -org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true -org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/org.springframework.samples.petclinic/.springBeans b/org.springframework.samples.petclinic/.springBeans deleted file mode 100644 index 24e2d6593..000000000 --- a/org.springframework.samples.petclinic/.springBeans +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - - - - - - - - - - diff --git a/org.springframework.samples.petclinic/pom.xml b/org.springframework.samples.petclinic/pom.xml deleted file mode 100644 index df94a059a..000000000 --- a/org.springframework.samples.petclinic/pom.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - 4.0.0 - org.springframework.samples - org.springframework.samples.petclinic - org.springframework.samples.petclinic - war - 1.0.0-SNAPSHOT - - 3.0.0.M3 - - - - - javax.servlet - jstl - 1.2 - - - log4j - log4j - 1.2.14 - - - commons-fileupload - commons-fileupload - 1.2.1 - - - - commons-io - commons-io - 1.3.2 - - - - hsqldb - hsqldb - 1.8.0.7 - - - - org.apache.tiles - tiles-core - 2.0.7 - - - org.apache.tiles - tiles-jsp - 2.0.7 - - - - org.tuckey - urlrewritefilter - 3.1.0 - - - - org.springframework - spring-core - ${spring.version} - - - org.springframework - spring-beans - ${spring.version} - - - org.springframework - spring-context - ${spring.version} - - - org.springframework - spring-web - ${spring.version} - - - org.springframework - spring-webmvc - ${spring.version} - - - org.springframework - spring-jdbc - ${spring.version} - - - - org.springframework.webflow - spring-js - 2.0.7.RELEASE - - - - javax.servlet - servlet-api - 2.5 - provided - - - javax.servlet.jsp - jsp-api - 2.1 - provided - - - - junit - junit - 4.5 - test - - - - - org.springsource.maven.snapshot - SpringSource Maven Central-compatible Milestone Repository - http://maven.springframework.org/milestone - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.5 - 1.5 - - - - org.apache.maven.plugins - maven-dependency-plugin - - - install - install - - sources - - - - - - - diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java deleted file mode 100644 index 797ca81e0..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/HomeController.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.springframework.samples.petclinic; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@Controller -public class HomeController { - - @RequestMapping(value="/", method = RequestMethod.GET) - public String get() { - return "home"; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java deleted file mode 100644 index d193117e0..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointment.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.springframework.samples.petclinic.appointments; - -import java.util.Date; - -public class Appointment { - - private String owner; - - private String ownerPhone; - - private String pet; - - private String notes; - - private Date dateTime; - - public String getOwner() { - return owner; - } - - public String getOwnerPhone() { - return ownerPhone; - } - - public String getPet() { - return pet; - } - - public Date getDateTime() { - return dateTime; - } - - public String getNotes() { - return notes; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java deleted file mode 100644 index 55ebd488b..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentBook.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.springframework.samples.petclinic.appointments; - -import java.util.Date; - -public interface AppointmentBook { - - Appointments getAppointmentsForToday(); - - Appointments getAppointmentsForDay(Date day); - - Long createAppointment(AppointmentForm form); - -} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java deleted file mode 100644 index d3d7abaaf..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentForm.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.springframework.samples.petclinic.appointments; - -import java.util.Date; - -public class AppointmentForm { - - private Long doctor; - - private Long owner; - - private String pet; - - private Date date; - - private Date time; - - private String notes; - - public Long getDoctor() { - return doctor; - } - - public void setDoctor(Long doctor) { - this.doctor = doctor; - } - - public Long getOwner() { - return owner; - } - - public void setOwner(Long owner) { - this.owner = owner; - } - - public String getPet() { - return pet; - } - - public void setPet(String pet) { - this.pet = pet; - } - - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - public String getNotes() { - return notes; - } - - public void setNotes(String notes) { - this.notes = notes; - } - -} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java deleted file mode 100644 index f2aa85e68..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/Appointments.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.springframework.samples.petclinic.appointments; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public class Appointments { - - private Map> vetAppointments = new LinkedHashMap>(); - - public Map> getAllByVet() { - return vetAppointments; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java deleted file mode 100644 index e3c786017..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/AppointmentsController.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.springframework.samples.petclinic.appointments; - -import java.util.Date; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@Controller -@RequestMapping("/appointments") -public class AppointmentsController { - - private AppointmentBook appointmentBook; - - @Autowired - public AppointmentsController(AppointmentBook appointmentBook) { - this.appointmentBook = appointmentBook; - } - - @RequestMapping(method = RequestMethod.GET) - public Appointments get() { - return appointmentBook.getAppointmentsForToday(); - } - - @RequestMapping(value="/{day}", method = RequestMethod.GET) - public Appointments getForDay(@PathVariable Date day) { - return appointmentBook.getAppointmentsForDay(day); - } - - @RequestMapping(value="/new", method = RequestMethod.GET) - public AppointmentForm getNewForm() { - return new AppointmentForm(); - } - - @RequestMapping(method = RequestMethod.POST) - public String post(AppointmentForm form) { - appointmentBook.createAppointment(form); - return "redirect:/appointments"; - } -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java deleted file mode 100644 index 92525a365..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/appointments/StubAppointmentBook.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.springframework.samples.petclinic.appointments; - -import java.util.Date; - -import org.springframework.stereotype.Repository; - -@Repository -public class StubAppointmentBook implements AppointmentBook { - - public Appointments getAppointmentsForDay(Date day) { - return new Appointments(); - } - - public Appointments getAppointmentsForToday() { - return new Appointments(); - } - - public Long createAppointment(AppointmentForm form) { - return 1L; - } - - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java deleted file mode 100644 index 9841482b5..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/Owner.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.springframework.samples.petclinic.owners; - -public class Owner { - - private Long id; - - private String firstName; - - private String lastName; - - private String address; - - private String city; - - private String phone; - - public Owner() { - - } - - public Owner(Long id) { - this.id = id; - } - - public Long getId() { - return id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - -} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java deleted file mode 100644 index d357c0471..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerController.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.springframework.samples.petclinic.owners; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.util.ExternalContext; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@Controller -@RequestMapping(value="/owners/{owner}") -public class OwnerController { - - private final OwnerRepository repository; - - @Autowired - public OwnerController(OwnerRepository repository) { - this.repository = repository; - } - - @RequestMapping(method=RequestMethod.GET) - public String get(@PathVariable Long owner, Model model) { - model.addAttribute(repository.getOwner(owner)); - return "owner"; - } - - @RequestMapping(value="/edit", method=RequestMethod.GET) - public Owner getEditForm(@PathVariable Long owner) { - return repository.getOwner(owner); - } - - @RequestMapping(method = RequestMethod.PUT) - public void put(Owner owner, ExternalContext response) { - repository.saveOwner(owner); - response.redirect(owner.getId()); - } - -} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java deleted file mode 100644 index 10702243d..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.springframework.samples.petclinic.owners; - -import java.util.Collection; - -public interface OwnerRepository { - - Collection findOwnersByLastName(String lastName); - - Owner getOwner(Long id); - - Long saveOwner(Owner owner); - -} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java deleted file mode 100644 index c9c589607..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnerSearchForm.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.springframework.samples.petclinic.owners; - -public class OwnerSearchForm { - - private String lastName; - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java deleted file mode 100644 index f24cd0745..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/OwnersController.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.springframework.samples.petclinic.owners; - -import java.util.Collection; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -@Controller -@RequestMapping("/owners") -public class OwnersController { - - private final OwnerRepository repository; - - @Autowired - public OwnersController(OwnerRepository repository) { - this.repository = repository; - } - - @RequestMapping(method = RequestMethod.GET) - public OwnerSearchForm get() { - return new OwnerSearchForm(); - } - - @RequestMapping(value="/search", method = RequestMethod.GET) - public Collection getSearchResults(@RequestParam String lastName) { - return repository.findOwnersByLastName(lastName); - } - - @RequestMapping(value="/new", method = RequestMethod.GET) - public Owner getNewForm() { - return new Owner(); - } - - @RequestMapping(method = RequestMethod.POST) - public String post(Owner owner) { - Long ownerId = repository.saveOwner(owner); - return "redirect:/owners/" + ownerId; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java deleted file mode 100644 index d442ee994..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/StubOwnerRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.springframework.samples.petclinic.owners; - -import java.util.Collection; - -import org.springframework.stereotype.Repository; - -@Repository -public class StubOwnerRepository implements OwnerRepository { - - public Collection findOwnersByLastName(String lastName) { - return null; - } - - public Owner getOwner(Long id) { - return new Owner(id); - } - - public Long saveOwner(Owner owner) { - return 1L; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java deleted file mode 100644 index 6691f557e..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Gender.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.samples.petclinic.owners.pets; - -public enum Gender { - MALE, FEMALE -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java deleted file mode 100644 index 63f189d3a..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/Pet.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.springframework.samples.petclinic.owners.pets; - -import java.util.Date; - -import org.springframework.samples.petclinic.util.Measurement; - -public class Pet { - - private String name; - - private String species; - - private String breed; - - private Gender gender; - - private Date birthDate; - - private Measurement weight; - - public String getName() { - return name; - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java deleted file mode 100644 index a0a7e74e8..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetController.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.springframework.samples.petclinic.owners.pets; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.util.ExternalContext; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@Controller -@RequestMapping(value="/owners/{owner}/pets/{pet}") -public class PetController { - - private final PetRepository repository; - - @Autowired - public PetController(PetRepository repository) { - this.repository = repository; - } - - @RequestMapping(method=RequestMethod.GET) - public Pet get(Long owner, String pet) { - return repository.getPet(owner, pet); - } - - @RequestMapping(value="/edit", method=RequestMethod.GET) - public Pet getEditForm(Long owner, String pet) { - return repository.getPet(owner, pet); - } - - @RequestMapping(method = RequestMethod.PUT) - public void put(Pet pet, ExternalContext response) { - repository.savePet(pet); - response.redirect(pet.getName()); - } - - @RequestMapping(method = RequestMethod.DELETE) - public void delete(Long owner, String pet, ExternalContext context) { - context.forResource("owners").redirect(owner); - } - -} \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java deleted file mode 100644 index 76afff837..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/PetRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.springframework.samples.petclinic.owners.pets; - -public interface PetRepository { - - Pet getPet(Long owner, String name); - - void savePet(Pet pet); - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java deleted file mode 100644 index 0dae2f563..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/owners/pets/StubPetRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.springframework.samples.petclinic.owners.pets; - -import org.springframework.stereotype.Repository; - -@Repository -public class StubPetRepository implements PetRepository { - - public Pet getPet(Long owner, String name) { - return null; - } - - public void savePet(Pet pet) { - } - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java deleted file mode 100644 index 5f4fc1e3e..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/ExternalContext.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.springframework.samples.petclinic.util; - -import org.springframework.ui.Model; - -// This is an idea as a context object to make avail to @Controller methods to interact with Dispatcher -public interface ExternalContext { - - Model getModel(); - - void selectView(String viewName); - - void renderFragment(String fragment); - - void redirect(Object resource); - - ExternalContext forResource(Object resource); - - Object getNativeRequest(); - - Object getNativeResponse(); - -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java deleted file mode 100644 index 9120e5838..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Measurement.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.springframework.samples.petclinic.util; - -import java.math.BigDecimal; - -public class Measurement { - - private BigDecimal amount; - - private Unit unit; -} diff --git a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java b/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java deleted file mode 100644 index 6bcf4e2e7..000000000 --- a/org.springframework.samples.petclinic/src/main/java/org/springframework/samples/petclinic/util/Unit.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.samples.petclinic.util; - -public enum Unit { - POUNDS -} diff --git a/org.springframework.samples.petclinic/src/main/resources/log4j.xml b/org.springframework.samples.petclinic/src/main/resources/log4j.xml deleted file mode 100644 index e09edc3bf..000000000 --- a/org.springframework.samples.petclinic/src/main/resources/log4j.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp deleted file mode 100644 index 997640df0..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/addNewForm.jsp +++ /dev/null @@ -1,31 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -

    Add New Appointment

    - - - - Doctor - - - - Owner - - - - Pet - - - - Date - - - - Time - - - - Notes - - - - \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp deleted file mode 100644 index 692d0bb0d..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/calendar.jsp +++ /dev/null @@ -1,2 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -

    Appointment Calendar

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp deleted file mode 100644 index b171fb5ad..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/appointments/content.jsp +++ /dev/null @@ -1,11 +0,0 @@ -<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> - -
    -
    - -
    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp deleted file mode 100644 index 08ab75826..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/home.jsp +++ /dev/null @@ -1,6 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -

    Welcome to the Spring 3 Petclinic

    - -

    - This sample application demonstrates many of the features Spring provides for web application development. -

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp deleted file mode 100644 index b92d0ffa1..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/layouts/page.jsp +++ /dev/null @@ -1,43 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> -<%@ page session="false" %> - - - <tiles:insertAttribute name="title"/> - - - -
    - -
    - -
    - -
    - - \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp deleted file mode 100644 index 68ad9dd6f..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/addNewForm.jsp +++ /dev/null @@ -1,15 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -

    Add New Owner

    - - - - First Name - - - - Last Name - - - - \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp deleted file mode 100644 index c0dae0e50..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/content.jsp +++ /dev/null @@ -1,11 +0,0 @@ -<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> - - -
    - -
    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp deleted file mode 100644 index 85dcec17b..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/owner.jsp +++ /dev/null @@ -1,2 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -

    Owner Details

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp deleted file mode 100644 index 1a5830d29..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchForm.jsp +++ /dev/null @@ -1,12 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> - -

    Search Owners

    - - - - Last Name - - - - \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp deleted file mode 100644 index c01fd8abb..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/owners/searchResults.jsp +++ /dev/null @@ -1,2 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -

    Search Results

    \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml deleted file mode 100644 index 63165f80e..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/app-config.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml deleted file mode 100644 index 8f2b7f1d2..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/spring/mvc-config.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml deleted file mode 100644 index e87543e73..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/tiles.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml deleted file mode 100644 index 9e3a4589b..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/urlrewrite.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - /resources/** - /resources/$1 - - - /** - /app/$1 - - - /app/** - /$1 - - diff --git a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml b/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 8238f5100..000000000 --- a/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - UrlRewriteFilter - org.tuckey.web.filters.urlrewrite.UrlRewriteFilter - - - - UrlRewriteFilter - /* - - - - - Spring MVC Dispatcher Servlet - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - - /WEB-INF/spring/*.xml - - - 1 - - - - - Spring MVC Dispatcher Servlet - /app/* - - - - - Resources Servlet - org.springframework.js.resource.ResourceServlet - 0 - - - - - Resources Servlet - /resources/* - - - diff --git a/org.springframework.samples.petclinic/src/main/webapp/styles/main.css b/org.springframework.samples.petclinic/src/main/webapp/styles/main.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/org.springframework.samples.petclinic/src/test/resources/log4j.xml b/org.springframework.samples.petclinic/src/test/resources/log4j.xml deleted file mode 100644 index f2c798d46..000000000 --- a/org.springframework.samples.petclinic/src/test/resources/log4j.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index f0c6167f6..a60fcf2ce 100644 --- a/pom.xml +++ b/pom.xml @@ -3,98 +3,89 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.springframework.samples - org.springframework.samples.petclinic + spring-petclinic petclinic war 1.0.0-SNAPSHOT - 3.0.0.RELEASE - 1.5.6 + 3.2.0.RELEASE + 1.7.0 + 1.2.17 + 4.1.4.Final + 1.7.1 - + org.springframework - org.springframework.context + spring-context ${spring.version} org.apache.commons - com.springsource.org.apache.commons.logging + commons-logging org.springframework - org.springframework.orm + spring-orm ${spring.version} org.springframework - org.springframework.oxm + spring-oxm ${spring.version} org.springframework - org.springframework.web.servlet - ${spring.version} - - - org.springframework - org.springframework.aspects - ${spring.version} - - - - org.aspectj - com.springsource.org.aspectj.weaver - 1.6.8.RELEASE + spring-webmvc + ${spring.version} - org.slf4j - com.springsource.slf4j.api - ${slf4j.version} - - - org.slf4j - com.springsource.slf4j.org.apache.commons.logging - ${slf4j.version} - runtime - - - org.slf4j - com.springsource.slf4j.log4j - ${slf4j.version} - runtime - - - org.apache.log4j - com.springsource.org.apache.log4j - 1.2.15 - runtime - + org.slf4j + jcl-over-slf4j + ${slf4j.version} + runtime + + + + org.slf4j + slf4j-api + ${slf4j.version} + runtime + + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + runtime + + + + log4j + log4j + ${log4j.version} + runtime + - org.apache.commons - com.springsource.org.apache.commons.dbcp - 1.2.2.osgi - runtime - - - org.apache.commons - com.springsource.org.apache.commons.pool - 1.5.3 + commons-dbcp + commons-dbcp + 1.4 runtime + org.hsqldb - com.springsource.org.hsqldb - 1.8.0.9 + hsqldb + 1.8.0.10 runtime @@ -103,153 +94,87 @@ com.springsource.com.mysql.jdbc 5.1.6 --> + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + + org.aspectj + aspectjweaver + ${aspectj.version} + - - org.hibernate - com.springsource.org.hibernate - 3.3.2.GA - - - javax.persistence - com.springsource.javax.persistence - 1.0.0 - - - - com.oracle.toplink.essentials - com.springsource.oracle.toplink.essentials - 2.0.0.b41-beta2 - org.hibernate - com.springsource.org.hibernate.ejb - 3.4.0.GA - - - - org.apache.commons - com.springsource.org.apache.commons.logging - - - - - org.hibernate - com.springsource.org.hibernate.annotations - 3.4.0.GA - - - - org.apache.commons - com.springsource.org.apache.commons.logging - - - - - - org.apache.openjpa - com.springsource.org.apache.openjpa - 1.1.0 - - - - org.apache.commons - com.springsource.org.apache.commons.logging - - + hibernate-entitymanager + ${hibernate.version} + javax.servlet - com.springsource.javax.servlet - 2.5.0 + servlet-api + 2.5 provided javax.servlet - com.springsource.javax.servlet.jsp - 2.1.0 - provided - - - javax.servlet - com.springsource.javax.servlet.jsp.jstl - 1.2.0 - - - org.apache.taglibs - com.springsource.org.apache.taglibs.standard - 1.1.2 + jstl + 1.2 - com.sun.syndication - com.springsource.com.sun.syndication - 1.0.0 + rome + rome + 1.0 + org.jdom - com.springsource.org.jdom - 1.1.0 + jdom + 2.0.2 runtime - javax.xml.bind - com.springsource.javax.xml.bind - 2.1.7 + com.sun.xml.bind + jaxb-impl + 2.2.6 provided - org.junit - com.springsource.org.junit - 4.7.0 + junit + junit + 4.10 test org.springframework - org.springframework.test + spring-test ${spring.version} test javax.transaction - com.springsource.javax.transaction - 1.1.0 + jta + 1.1 test - - - com.springsource.repository.bundles.release - SpringSource Enterprise Bundle Repository - SpringSource Releases - http://repository.springsource.com/maven/bundles/release - - - com.springsource.repository.bundles.external - SpringSource Enterprise Bundle Repository - External Releases - http://repository.springsource.com/maven/bundles/external - - - com.springsource.repository.bundles.milestone - SpringSource Enterprise Bundle Repository - SpringSource Milestones - http://repository.springsource.com/maven/bundles/milestone - - - com.springsource.repository.bundles.snapshot - SpringSource Enterprise Bundle Repository - Snapshot Releases - http://repository.springsource.com/maven/bundles/snapshot - - @@ -257,8 +182,8 @@ maven-compiler-plugin true - 1.5 - 1.5 + 1.6 + 1.6 true @@ -278,6 +203,19 @@ petclinic + + org.apache.maven.plugins + maven-eclipse-plugin + 2.8 + + true + true + 2.0 + + **/*.* + + + org.apache.maven.plugins maven-dependency-plugin diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java index 1d9894d38..cc2633875 100644 --- a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java +++ b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java @@ -18,7 +18,7 @@ import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper; import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.orm.ObjectRetrievalFailureException; @@ -58,7 +58,7 @@ public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean { private final Logger logger = LoggerFactory.getLogger(getClass()); - private SimpleJdbcTemplate simpleJdbcTemplate; + private JdbcTemplate simpleJdbcTemplate; private SimpleJdbcInsert insertOwner; private SimpleJdbcInsert insertPet; @@ -69,7 +69,7 @@ public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean { @Autowired public void init(DataSource dataSource) { - this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.simpleJdbcTemplate = new JdbcTemplate(dataSource); this.insertOwner = new SimpleJdbcInsert(dataSource) .withTableName("owners") diff --git a/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java b/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java deleted file mode 100644 index 1086591de..000000000 --- a/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.springframework.samples.petclinic.toplink; - -import java.io.IOException; -import java.io.Writer; - -import oracle.toplink.essentials.exceptions.ValidationException; -import oracle.toplink.essentials.platform.database.HSQLPlatform; -import oracle.toplink.essentials.queryframework.ValueReadQuery; - -/** - * Subclass of the TopLink Essentials default HSQLPlatform class, using native - * HSQLDB identity columns for id generation. - * - *

    Necessary for PetClinic's default data model, which relies on identity - * columns: this is uniformly used across all persistence layer implementations - * (JDBC, Hibernate, and JPA). - * - * @author Juergen Hoeller - * @author James Clark - * @since 1.2 - */ -public class EssentialsHSQLPlatformWithNativeSequence extends HSQLPlatform { - - private static final long serialVersionUID = -55658009691346735L; - - - public EssentialsHSQLPlatformWithNativeSequence() { - // setUsesNativeSequencing(true); - } - - @Override - public boolean supportsNativeSequenceNumbers() { - return true; - } - - @Override - public boolean shouldNativeSequenceAcquireValueAfterInsert() { - return true; - } - - @Override - public ValueReadQuery buildSelectQueryForNativeSequence() { - return new ValueReadQuery("CALL IDENTITY()"); - } - - @Override - public void printFieldIdentityClause(Writer writer) throws ValidationException { - try { - writer.write(" IDENTITY"); - } - catch (IOException ex) { - throw ValidationException.fileError(ex); - } - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java b/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java deleted file mode 100644 index 3bcc9add7..000000000 --- a/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ - -/** - * - * The classes in this package provide support for using the TopLink - * implementation with PetClinic's EntityManagerClinic. - * - * - */ -package org.springframework.samples.petclinic.toplink; - diff --git a/src/main/resources/log4j.dtd b/src/main/resources/log4j.dtd new file mode 100755 index 000000000..d92a6e7bc --- /dev/null +++ b/src/main/resources/log4j.dtd @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties deleted file mode 100644 index ebee551aa..000000000 --- a/src/main/resources/log4j.properties +++ /dev/null @@ -1,18 +0,0 @@ -# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml! -# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J. -log4j.rootLogger=INFO, stdout, logfile - -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n - -log4j.appender.logfile=org.apache.log4j.RollingFileAppender -log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log -log4j.appender.logfile.MaxFileSize=512KB -# Keep three backup files. -log4j.appender.logfile.MaxBackupIndex=3 -# Pattern to output: date priority [category] - message -log4j.appender.logfile.layout=org.apache.log4j.PatternLayout -log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n - -log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml new file mode 100755 index 000000000..13330e6ff --- /dev/null +++ b/src/main/resources/log4j.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/footer.jsp b/src/main/webapp/WEB-INF/jsp/footer.jsp index 52aaffc47..486957def 100644 --- a/src/main/webapp/WEB-INF/jsp/footer.jsp +++ b/src/main/webapp/WEB-INF/jsp/footer.jsp @@ -1,12 +1,10 @@ +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> - + -

    - - diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp index 49393d364..1cdc67061 100644 --- a/src/main/webapp/WEB-INF/jsp/header.jsp +++ b/src/main/webapp/WEB-INF/jsp/header.jsp @@ -1,7 +1,8 @@ +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> + - @@ -9,6 +10,4 @@ PetClinic :: a Spring Framework demonstration - -
    diff --git a/src/main/webapp/WEB-INF/jsp/owners/search.jsp b/src/main/webapp/WEB-INF/jsp/owners/search.jsp index b972390a1..7b6b5c880 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/search.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/search.jsp @@ -1,26 +1,38 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + -

    Find Owners:

    + - - - - - - - - - -
    - Last Name: -
    - -

    -
    + -
    -Add Owner +
    -<%@ include file="/WEB-INF/jsp/footer.jsp" %> +

    Find Owners:

    + + + +
    + +
    + + +
    +
    + +
    +
    +
    + +
    + Add Owner + + + +
    + + + diff --git a/src/main/webapp/WEB-INF/jsp/owners/show.jsp b/src/main/webapp/WEB-INF/jsp/owners/show.jsp index 9767c18ae..cd7334db1 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/show.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/show.jsp @@ -1,7 +1,16 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + +
    +

    Owner Information

    @@ -105,4 +114,9 @@
    -<%@ include file="/WEB-INF/jsp/footer.jsp" %> + + +
    + + + diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp index 308581897..9b431e482 100644 --- a/src/main/webapp/WEB-INF/jsp/welcome.jsp +++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp @@ -1,16 +1,29 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -" align="right" style="position:relative;right:30px;"> + + + + + + + +
    +" align="right" style="position:relative;right:30px;">

     

     

    -<%@ include file="/WEB-INF/jsp/footer.jsp" %> + + +
    + + + diff --git a/src/main/webapp/WEB-INF/petclinic-servlet.xml b/src/main/webapp/WEB-INF/petclinic-servlet.xml index e55766ac4..345a2da8a 100644 --- a/src/main/webapp/WEB-INF/petclinic-servlet.xml +++ b/src/main/webapp/WEB-INF/petclinic-servlet.xml @@ -3,11 +3,12 @@ - DispatcherServlet application context for PetClinic's web tier. --> + xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" + xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:mvc="http://www.springframework.org/schema/mvc" + xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd + http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - + @@ -58,15 +59,21 @@ - BeanNameViewResolver. Note the use of the expression language to refer to the contentType - property of the vets view bean, setting it to 'application/vnd.springsource.samples.petclinic+xml'. --> - - - - - - - - + + + + + + + + + + atom=application/atom+xml + xml=#{vets.contentType} + + + - @@ -32,14 +32,14 @@ - + - diff --git a/src/main/webapp/images/banner-graphic.png b/src/main/webapp/images/banner-graphic.png deleted file mode 100644 index e6d01d5885266efbf4dc99431576a13dee5725e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13773 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 diff --git a/src/main/webapp/images/springsource-logo.png b/src/main/webapp/images/springsource-logo.png deleted file mode 100644 index e170f8abf778b24ed1de11dad6f1444e849269ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4974 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 @@ -81,18 +82,16 @@ import org.springframework.test.context.junit4.AbstractTransactionalJUnit4Spring * @author Sam Brannen */ @ContextConfiguration -public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4SpringContextTests { +public abstract class AbstractClinicTests { @Autowired protected Clinic clinic; - @Test + @Test @Transactional public void getVets() { Collection vets = this.clinic.getVets(); - // Use the inherited countRowsInTable() convenience method (from - // AbstractTransactionalJUnit4SpringContextTests) to verify the results. - assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("vets"), vets.size()); + Vet v1 = EntityUtils.getById(vets, Vet.class, 2); assertEquals("Leary", v1.getLastName()); assertEquals(1, v1.getNrOfSpecialties()); @@ -107,8 +106,7 @@ public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4Spr @Test public void getPetTypes() { Collection petTypes = this.clinic.getPetTypes(); - assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("types"), - petTypes.size()); + PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1); assertEquals("cat", t1.getName()); PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4); diff --git a/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java index 4f50d7231..cedbba3c9 100644 --- a/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java @@ -1,8 +1,10 @@ package org.springframework.samples.petclinic.hibernate; +import org.junit.runner.RunWith; import org.springframework.samples.petclinic.AbstractClinicTests; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** *

    @@ -17,6 +19,7 @@ import org.springframework.test.context.ContextConfiguration; */ @ContextConfiguration @DirtiesContext +@RunWith(SpringJUnit4ClassRunner.class) public class HibernateClinicTests extends AbstractClinicTests { } diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java index 335297d90..77b08a19b 100644 --- a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java @@ -1,12 +1,18 @@ package org.springframework.samples.petclinic.jpa; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + import java.util.Collection; import java.util.Date; import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.Clinic; import org.springframework.samples.petclinic.Owner; import org.springframework.samples.petclinic.Pet; @@ -14,8 +20,6 @@ import org.springframework.samples.petclinic.PetType; import org.springframework.samples.petclinic.Vet; import org.springframework.samples.petclinic.Visit; import org.springframework.samples.petclinic.util.EntityUtils; -import org.springframework.test.annotation.ExpectedException; -import org.springframework.test.jpa.AbstractJpaTests; /** *

    @@ -35,13 +39,6 @@ import org.springframework.test.jpa.AbstractJpaTests; *

  • Executes each test method in its own transaction, which is automatically * rolled back by default. This means that even if tests insert or otherwise * change database state, there is no need for a teardown or cleanup script.
  • - *
  • Provides useful inherited protected fields, such as a - * {@link SimpleJdbcTemplate} that can be used to verify database state after - * test operations, or verify the results of queries performed by application - * code. Alternatively, you can use protected convenience methods such as - * {@link #countRowsInTable(String)}, {@link #deleteFromTables(String[])}, - * etc. An ApplicationContext is also inherited, and can be used for explicit - * lookup if necessary.
  • * *

    * {@link AbstractJpaTests} and related classes are shipped in @@ -52,38 +49,30 @@ import org.springframework.test.jpa.AbstractJpaTests; * @author Sam Brannen * @see AbstractJpaTests */ -public abstract class AbstractJpaClinicTests extends AbstractJpaTests { +public abstract class AbstractJpaClinicTests { + + @PersistenceContext + private EntityManager entityManager; + @Autowired protected Clinic clinic; - /** - * This method is provided to set the Clinic instance being tested by the - * Dependency Injection injection behaviour of the superclass from the - * org.springframework.test package. - * - * @param clinic clinic to test - */ - public void setClinic(Clinic clinic) { - this.clinic = clinic; - } - - @ExpectedException(IllegalArgumentException.class) + @Test public void testBogusJpql() { - this.sharedEntityManager.createQuery("SELECT RUBBISH FROM RUBBISH HEAP").executeUpdate(); + try { + this.entityManager.createQuery("SELECT RUBBISH FROM RUBBISH HEAP").executeUpdate(); + fail("exception was expected because of incorrect SQL statement"); + } catch (Exception e) { + // expected + } } - public void testApplicationManaged() { - EntityManager appManaged = this.entityManagerFactory.createEntityManager(); - appManaged.joinTransaction(); - } + @Test public void testGetVets() { Collection vets = this.clinic.getVets(); - // Use the inherited countRowsInTable() convenience method (from - // AbstractTransactionalDataSourceSpringContextTests) to verify the - // results. - assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("vets"), vets.size()); + Vet v1 = EntityUtils.getById(vets, Vet.class, 2); assertEquals("Leary", v1.getLastName()); assertEquals(1, v1.getNrOfSpecialties()); @@ -95,16 +84,17 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals("surgery", (v2.getSpecialties().get(1)).getName()); } + @Test public void testGetPetTypes() { Collection petTypes = this.clinic.getPetTypes(); - assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("types"), - petTypes.size()); + PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1); assertEquals("cat", t1.getName()); PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4); assertEquals("snake", t4.getName()); } + @Test public void testFindOwners() { Collection owners = this.clinic.findOwners("Davis"); assertEquals(2, owners.size()); @@ -112,21 +102,15 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals(0, owners.size()); } + @Test public void testLoadOwner() { Owner o1 = this.clinic.loadOwner(1); assertTrue(o1.getLastName().startsWith("Franklin")); Owner o10 = this.clinic.loadOwner(10); assertEquals("Carlos", o10.getFirstName()); - - // Check lazy loading, by ending the transaction - endTransaction(); - - // Now Owners are "disconnected" from the data store. - // We might need to touch this collection if we switched to lazy loading - // in mapping files, but this test would pick this up. - o1.getPets(); } + @Test public void testInsertOwner() { Collection owners = this.clinic.findOwners("Schultz"); int found = owners.size(); @@ -138,6 +122,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals(found + 1, owners.size()); } + @Test public void testUpdateOwner() throws Exception { Owner o1 = this.clinic.loadOwner(1); String old = o1.getLastName(); @@ -147,6 +132,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals(old + "X", o1.getLastName()); } + @Test public void testLoadPet() { Collection types = this.clinic.getPetTypes(); Pet p7 = this.clinic.loadPet(7); @@ -159,6 +145,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals("Peter", p6.getOwner().getFirstName()); } + @Test public void testInsertPet() { Owner o6 = this.clinic.loadOwner(6); int found = o6.getPets().size(); @@ -175,6 +162,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals(found + 1, o6.getPets().size()); } + @Test public void testUpdatePet() throws Exception { Pet p7 = this.clinic.loadPet(7); String old = p7.getName(); @@ -184,6 +172,7 @@ public abstract class AbstractJpaClinicTests extends AbstractJpaTests { assertEquals(old + "X", p7.getName()); } + @Test public void testInsertVisit() { Pet p7 = this.clinic.loadPet(7); int found = p7.getVisits().size(); diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java index 67c472fde..669cdcd94 100644 --- a/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java @@ -2,7 +2,14 @@ package org.springframework.samples.petclinic.jpa; import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.aspects.UsageLogAspect; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.assertFalse; /** *

    @@ -17,23 +24,16 @@ import org.springframework.samples.petclinic.aspects.UsageLogAspect; * @author Rod Johnson * @author Juergen Hoeller */ +@ContextConfiguration(locations={"applicationContext-jpaCommon.xml", "applicationContext-hibernateAdapter.xml", + "applicationContext-entityManager.xml"}) +@RunWith(SpringJUnit4ClassRunner.class) public class EntityManagerClinicTests extends AbstractJpaClinicTests { + @Autowired private UsageLogAspect usageLogAspect; - public void setUsageLogAspect(UsageLogAspect usageLogAspect) { - this.usageLogAspect = usageLogAspect; - } - - @Override - protected String[] getConfigPaths() { - return new String[] { - "applicationContext-jpaCommon.xml", - "applicationContext-toplinkAdapter.xml", - "applicationContext-entityManager.xml" - }; - } + @Test public void testUsageLogAspectIsInvoked() { String name1 = "Schuurman"; String name2 = "Greenwood"; diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java index d95b452e1..d5dac397e 100644 --- a/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java +++ b/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java @@ -1,5 +1,9 @@ package org.springframework.samples.petclinic.jpa; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + /** *

    * Tests for the DAO variant based on the shared EntityManager approach, using @@ -12,15 +16,9 @@ package org.springframework.samples.petclinic.jpa; * * @author Juergen Hoeller */ +@ContextConfiguration(locations={"applicationContext-jpaCommon.xml", "applicationContext-hibernateAdapter.xml", +"applicationContext-entityManager.xml"}) +@RunWith(SpringJUnit4ClassRunner.class) public class HibernateEntityManagerClinicTests extends EntityManagerClinicTests { - @Override - protected String[] getConfigPaths() { - return new String[] { - "applicationContext-jpaCommon.xml", - "applicationContext-hibernateAdapter.xml", - "applicationContext-entityManager.xml" - }; - } - } diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java deleted file mode 100644 index 98e38ed61..000000000 --- a/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java +++ /dev/null @@ -1,27 +0,0 @@ - -package org.springframework.samples.petclinic.jpa; - -/** - *

    - * Tests for the DAO variant based on the shared EntityManager approach, using - * Apache OpenJPA for testing instead of the reference implementation. - *

    - *

    - * Specifically tests usage of an orm.xml file, loaded by the - * persistence provider through the Spring-provided persistence unit root URL. - *

    - * - * @author Juergen Hoeller - */ -public class OpenJpaEntityManagerClinicTests extends EntityManagerClinicTests { - - @Override - protected String[] getConfigPaths() { - return new String[] { - "applicationContext-jpaCommon.xml", - "applicationContext-openJpaAdapter.xml", - "applicationContext-entityManager.xml" - }; - } - -} diff --git a/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml index 7320035ce..bcf48e75c 100644 --- a/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml +++ b/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml @@ -1,13 +1,13 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - @@ -15,16 +15,9 @@ ${hibernate.show_sql} - - - - - - - - diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml deleted file mode 100644 index 8f6f7c442..000000000 --- a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml deleted file mode 100644 index ac031de8e..000000000 --- a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - From 6dd1acd4b1ed392756c246ffc165a94177a3ef34 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 9 Jan 2013 17:28:20 +0800 Subject: [PATCH 071/887] adding gitignore file --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..3189638f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +target/* +.settings/* +.classpath + From c690c9d05c07c28d03d7c15ccd544ecdad6225f2 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 9 Jan 2013 21:23:44 +0800 Subject: [PATCH 072/887] removed static inclusion of jsp --- .../webapp/WEB-INF/jsp/dataAccessFailure.jsp | 39 ++-- src/main/webapp/WEB-INF/jsp/includes.jsp | 5 - src/main/webapp/WEB-INF/jsp/owners/form.jsp | 134 ++++++----- src/main/webapp/WEB-INF/jsp/owners/list.jsp | 77 ++++--- src/main/webapp/WEB-INF/jsp/owners/show.jsp | 210 +++++++++--------- src/main/webapp/WEB-INF/jsp/pets/form.jsp | 118 +++++----- .../webapp/WEB-INF/jsp/pets/visitForm.jsp | 143 ++++++------ .../webapp/WEB-INF/jsp/uncaughtException.jsp | 97 ++++---- src/main/webapp/WEB-INF/jsp/vets.jsp | 74 +++--- src/main/webapp/WEB-INF/jsp/welcome.jsp | 32 +-- .../spring/applicationContext-jdbc.xml | 2 +- 11 files changed, 518 insertions(+), 413 deletions(-) delete mode 100644 src/main/webapp/WEB-INF/jsp/includes.jsp diff --git a/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp b/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp index 256cca177..5674cabab 100644 --- a/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp +++ b/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp @@ -1,19 +1,30 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<% -Exception ex = (Exception) request.getAttribute("exception"); -%> -

    Data access failure: <%= ex.getMessage() %>

    -

    + -<% -ex.printStackTrace(new java.io.PrintWriter(out)); -%> + -

    -
    -
    ">Home + +

    + <% + Exception ex = (Exception) request.getAttribute("exception"); + %> + +

    Data access failure: <%= ex.getMessage() %>

    +

    + + <% + ex.printStackTrace(new java.io.PrintWriter(out)); + %> + +

    +
    + ">Home + +

    + -<%@ include file="/WEB-INF/jsp/footer.jsp" %> + + + diff --git a/src/main/webapp/WEB-INF/jsp/includes.jsp b/src/main/webapp/WEB-INF/jsp/includes.jsp deleted file mode 100644 index 96c3e304c..000000000 --- a/src/main/webapp/WEB-INF/jsp/includes.jsp +++ /dev/null @@ -1,5 +0,0 @@ -<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> diff --git a/src/main/webapp/WEB-INF/jsp/owners/form.jsp b/src/main/webapp/WEB-INF/jsp/owners/form.jsp index b4c2b2100..208f521f4 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/form.jsp @@ -1,61 +1,77 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> - - - - +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -

    New Owner:

    - - - - - - - - - - - - - - - - - - - - -
    - First Name: -
    - -
    - Last Name: -
    - -
    - Address: -
    - -
    - City: -
    - -
    - Telephone: -
    - -
    - - -

    -
    - -

    -
    -
    -
    -
    -<%@ include file="/WEB-INF/jsp/footer.jsp" %> + + + + + + +
    + + + + + +

    New Owner:

    + + + + + + + + + + + + + + + + + + + + +
    + First Name: +
    + +
    + Last Name: +
    + +
    + Address: +
    + +
    + City: +
    + +
    + Telephone: +
    + +
    + + +

    +
    + +

    +
    +
    +
    +
    + +
    + + + + diff --git a/src/main/webapp/WEB-INF/jsp/owners/list.jsp b/src/main/webapp/WEB-INF/jsp/owners/list.jsp index 44fc3cac0..b28ce6b6b 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/list.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/list.jsp @@ -1,34 +1,51 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + + + + + + + +

    Owners:

    - - - - - - - - - - - - - - - - - -
    NameAddressCityTelephonePets
    - - - - ${owner.firstName} ${owner.lastName} - ${owner.address}${owner.city}${owner.telephone} - - ${pet.name}   - -
    + + + + + + + + + + + + + + + + + + + +
    NameAddressCityTelephonePets
    + + + + ${owner.firstName} ${owner.lastName} + ${owner.address}${owner.city}${owner.telephone} + + ${pet.name}   + +
    -<%@ include file="/WEB-INF/jsp/footer.jsp" %> +
    + + + + diff --git a/src/main/webapp/WEB-INF/jsp/owners/show.jsp b/src/main/webapp/WEB-INF/jsp/owners/show.jsp index cd7334db1..077d8cff5 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/show.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/show.jsp @@ -11,112 +11,114 @@
    -

    Owner Information

    - - - - - - - - - - - - - - - - - - -
    Name${owner.firstName} ${owner.lastName}
    Address${owner.address}
    City${owner.city}
    Telephone ${owner.telephone}
    - - - - - -
    - - - - Edit Owner - - - - - Add New Pet -
    - -

    Pets and Visits

    - - - - - - - -
    - - - - - - - - - - - - - -
    Name${pet.name}
    Birth Date
    Type${pet.type.name}
    -
    - - - - - - - - - - - -
    Visit DateDescription
    ${visit.description}
    -
    - - - - - - - - -
    - - - - - Edit Pet - - - - - - Add Visit - - - - - - Atom Feed -
    -
    +

    Owner Information

    + + + + + + + + + + + + + + + + + + +
    Name${owner.firstName} ${owner.lastName}
    Address${owner.address}
    City${owner.city}
    Telephone ${owner.telephone}
    + + + + + +
    + + + + Edit Owner + + + + + Add New Pet +
    + +

    Pets and Visits

    + + + + + + + +
    + + + + + + + + + + + + + +
    Name${pet.name}
    Birth Date
    Type${pet.type.name}
    +
    + + + + + + + + + + + + + +
    Visit DateDescription
    ${visit.description}
    +
    + + + + + + + + +
    + + + + + Edit Pet + + + + + + Add Visit + + + + + + Atom Feed +
    +
    - +
    -
    + diff --git a/src/main/webapp/WEB-INF/jsp/pets/form.jsp b/src/main/webapp/WEB-INF/jsp/pets/form.jsp index 12f503db5..ec06dc162 100644 --- a/src/main/webapp/WEB-INF/jsp/pets/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/pets/form.jsp @@ -1,56 +1,70 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> - - - - +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -

    New Pet

    -Owner: ${pet.owner.firstName} ${pet.owner.lastName} -
    - - - - - - - - - - - - - - -
    - Name: -
    - -
    - Birth Date: -
    - (yyyy-mm-dd) -
    - Type: -
    - -
    - - -

    -
    - -

    -
    -
    -
    -
    + - - -

    -
    -
    + -<%@ include file="/WEB-INF/jsp/footer.jsp" %> + + +
    + + + + + +

    New Pet

    + + Owner: ${pet.owner.firstName} ${pet.owner.lastName} +
    + + + + + + + + + + + + + + +
    + Name: +
    + +
    + Birth Date: +
    + (yyyy-mm-dd) +
    + Type: +
    + +
    + + +

    +
    + +

    +
    +
    +
    +
    + + + +

    +
    +
    + +
    + + + + diff --git a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp index 97183f46c..08dda8e81 100644 --- a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp @@ -1,68 +1,85 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -

    New Visit:

    - - Pet: - - - - - - - - - - - - - -
    NameBirth DateTypeOwner
    ${visit.pet.name}${visit.pet.type.name}${visit.pet.owner.firstName} ${visit.pet.owner.lastName}
    + - - - - - - - - - - - - -
    - Date: -
    -
    - (yyyy-mm-dd) -
    - Description: -
    -
    - -
    - -

    -
    -
    + -
    -Previous Visits: - - - - - - - - - - - - - -
    DateDescription
    ${visit.description}
    + -<%@ include file="/WEB-INF/jsp/footer.jsp" %> +
    + +

    New Visit:

    + + + Pet: + + + + + + + + + + + + + + + +
    NameBirth DateTypeOwner
    ${visit.pet.name}${visit.pet.type.name}${visit.pet.owner.firstName} ${visit.pet.owner.lastName}
    + + + + + + + + + + + + + +
    + Date: +
    +
    + (yyyy-mm-dd) +
    + Description: +
    +
    + +
    + +

    +
    +
    + +
    + Previous Visits: + + + + + + + + + + + + + +
    DateDescription
    ${visit.description}
    + +
    + + + + diff --git a/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp b/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp index e97fdf378..236a7b9b3 100644 --- a/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp +++ b/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp @@ -1,49 +1,64 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -

    Internal error

    -

    + -<% -try { - // The Servlet spec guarantees this attribute will be available - Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); + - if (exception != null) { - if (exception instanceof ServletException) { - // It's a ServletException: we should extract the root cause - ServletException sex = (ServletException) exception; - Throwable rootCause = sex.getRootCause(); - if (rootCause == null) - rootCause = sex; - out.println("** Root cause is: "+ rootCause.getMessage()); - rootCause.printStackTrace(new java.io.PrintWriter(out)); - } - else { - // It's not a ServletException, so we'll just show it - exception.printStackTrace(new java.io.PrintWriter(out)); - } - } - else { - out.println("No error information available"); - } - - // Display cookies - out.println("\nCookies:\n"); - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (int i = 0; i < cookies.length; i++) { - out.println(cookies[i].getName() + "=[" + cookies[i].getValue() + "]"); + + +

    + +

    Internal error

    +

    + + <% + try { + // The Servlet spec guarantees this attribute will be available + Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); + + if (exception != null) { + if (exception instanceof ServletException) { + // It's a ServletException: we should extract the root cause + ServletException sex = (ServletException) exception; + Throwable rootCause = sex.getRootCause(); + if (rootCause == null) + rootCause = sex; + out.println("** Root cause is: "+ rootCause.getMessage()); + rootCause.printStackTrace(new java.io.PrintWriter(out)); + } + else { + // It's not a ServletException, so we'll just show it + exception.printStackTrace(new java.io.PrintWriter(out)); + } + } + else { + out.println("No error information available"); + } + + // Display cookies + out.println("\nCookies:\n"); + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + out.println(cookies[i].getName() + "=[" + cookies[i].getValue() + "]"); + } } + + } catch (Exception ex) { + ex.printStackTrace(new java.io.PrintWriter(out)); } - -} catch (Exception ex) { - ex.printStackTrace(new java.io.PrintWriter(out)); -} -%> + %> -

    -
    +

    +
    -<%@ include file="/WEB-INF/jsp/footer.jsp" %> +

    + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/vets.jsp b/src/main/webapp/WEB-INF/jsp/vets.jsp index cff2154f2..81f3fdfe3 100644 --- a/src/main/webapp/WEB-INF/jsp/vets.jsp +++ b/src/main/webapp/WEB-INF/jsp/vets.jsp @@ -1,31 +1,49 @@ -<%@ include file="/WEB-INF/jsp/includes.jsp" %> -<%@ include file="/WEB-INF/jsp/header.jsp" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -

    Veterinarians:

    - - - - - - - - - - - -
    NameSpecialties
    ${vet.firstName} ${vet.lastName} - - ${specialty.name} - - none -
    - - - - -
    - ">View as XML -
    + -<%@ include file="/WEB-INF/jsp/footer.jsp" %> + + + + +
    + +

    Veterinarians:

    + + + + + + + + + + + + + + + + +
    NameSpecialties
    ${vet.firstName} ${vet.lastName} + + ${specialty.name} + + none +
    + + + + +
    + ">View as XML +
    + +
    + + + + diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp index 9b431e482..9cddcd629 100644 --- a/src/main/webapp/WEB-INF/jsp/welcome.jsp +++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp @@ -2,28 +2,28 @@ <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> - + -
    -" align="right" style="position:relative;right:30px;"> -

    +
    + " align="right" style="position:relative;right:30px;"> +

    + + + +

     

    +

     

    + - - -

     

    -

     

    - - - -
    +
    + diff --git a/src/main/webapp/WEB-INF/spring/applicationContext-jdbc.xml b/src/main/webapp/WEB-INF/spring/applicationContext-jdbc.xml index 6819d6db4..a45edac8e 100644 --- a/src/main/webapp/WEB-INF/spring/applicationContext-jdbc.xml +++ b/src/main/webapp/WEB-INF/spring/applicationContext-jdbc.xml @@ -52,7 +52,7 @@ + --> From aeeeace8a2276516960bc9b99a46f13a41bcccd0 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 9 Jan 2013 21:37:28 +0800 Subject: [PATCH 073/887] renaming controllers so they all have 'Controller' suffix --- .../{AddOwnerForm.java => AddOwnerController.java} | 4 ++-- .../web/{AddPetForm.java => AddPetController.java} | 4 ++-- .../{AddVisitForm.java => AddVisitController.java} | 4 ++-- .../{EditOwnerForm.java => EditOwnerController.java} | 4 ++-- .../web/{EditPetForm.java => EditPetController.java} | 4 ++-- ...FindOwnersForm.java => FindOwnersController.java} | 4 ++-- src/main/resources/log4j.xml | 4 ++++ src/main/webapp/resources/html/tutorial.html | 12 ++++++------ 8 files changed, 22 insertions(+), 18 deletions(-) rename src/main/java/org/springframework/samples/petclinic/web/{AddOwnerForm.java => AddOwnerController.java} (95%) rename src/main/java/org/springframework/samples/petclinic/web/{AddPetForm.java => AddPetController.java} (96%) rename src/main/java/org/springframework/samples/petclinic/web/{AddVisitForm.java => AddVisitController.java} (96%) rename src/main/java/org/springframework/samples/petclinic/web/{EditOwnerForm.java => EditOwnerController.java} (96%) rename src/main/java/org/springframework/samples/petclinic/web/{EditPetForm.java => EditPetController.java} (96%) rename src/main/java/org/springframework/samples/petclinic/web/{FindOwnersForm.java => FindOwnersController.java} (96%) diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddOwnerController.java similarity index 95% rename from src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java rename to src/main/java/org/springframework/samples/petclinic/web/AddOwnerController.java index cd830aff6..0f2575c3f 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java +++ b/src/main/java/org/springframework/samples/petclinic/web/AddOwnerController.java @@ -27,13 +27,13 @@ import org.springframework.web.bind.support.SessionStatus; @Controller @RequestMapping("/owners/new") @SessionAttributes(types = Owner.class) -public class AddOwnerForm { +public class AddOwnerController { private final Clinic clinic; @Autowired - public AddOwnerForm(Clinic clinic) { + public AddOwnerController(Clinic clinic) { this.clinic = clinic; } diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddPetController.java similarity index 96% rename from src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java rename to src/main/java/org/springframework/samples/petclinic/web/AddPetController.java index 586cf3d67..314b301b1 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java +++ b/src/main/java/org/springframework/samples/petclinic/web/AddPetController.java @@ -32,13 +32,13 @@ import org.springframework.web.bind.support.SessionStatus; @Controller @RequestMapping("/owners/{ownerId}/pets/new") @SessionAttributes("pet") -public class AddPetForm { +public class AddPetController { private final Clinic clinic; @Autowired - public AddPetForm(Clinic clinic) { + public AddPetController(Clinic clinic) { this.clinic = clinic; } diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddVisitController.java similarity index 96% rename from src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java rename to src/main/java/org/springframework/samples/petclinic/web/AddVisitController.java index 683686440..931256879 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java +++ b/src/main/java/org/springframework/samples/petclinic/web/AddVisitController.java @@ -29,13 +29,13 @@ import org.springframework.web.bind.support.SessionStatus; @Controller @RequestMapping("/owners/*/pets/{petId}/visits/new") @SessionAttributes("visit") -public class AddVisitForm { +public class AddVisitController { private final Clinic clinic; @Autowired - public AddVisitForm(Clinic clinic) { + public AddVisitController(Clinic clinic) { this.clinic = clinic; } diff --git a/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java b/src/main/java/org/springframework/samples/petclinic/web/EditOwnerController.java similarity index 96% rename from src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java rename to src/main/java/org/springframework/samples/petclinic/web/EditOwnerController.java index 0b65de51b..e602f75fd 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java +++ b/src/main/java/org/springframework/samples/petclinic/web/EditOwnerController.java @@ -27,13 +27,13 @@ import org.springframework.web.bind.support.SessionStatus; @Controller @RequestMapping("/owners/{ownerId}/edit") @SessionAttributes(types = Owner.class) -public class EditOwnerForm { +public class EditOwnerController { private final Clinic clinic; @Autowired - public EditOwnerForm(Clinic clinic) { + public EditOwnerController(Clinic clinic) { this.clinic = clinic; } diff --git a/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java b/src/main/java/org/springframework/samples/petclinic/web/EditPetController.java similarity index 96% rename from src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java rename to src/main/java/org/springframework/samples/petclinic/web/EditPetController.java index 1a7fd6ed3..c7703c1e9 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java +++ b/src/main/java/org/springframework/samples/petclinic/web/EditPetController.java @@ -30,13 +30,13 @@ import org.springframework.web.bind.support.SessionStatus; @Controller @RequestMapping("/owners/*/pets/{petId}/edit") @SessionAttributes("pet") -public class EditPetForm { +public class EditPetController { private final Clinic clinic; @Autowired - public EditPetForm(Clinic clinic) { + public EditPetController(Clinic clinic) { this.clinic = clinic; } diff --git a/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java b/src/main/java/org/springframework/samples/petclinic/web/FindOwnersController.java similarity index 96% rename from src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java rename to src/main/java/org/springframework/samples/petclinic/web/FindOwnersController.java index eb93fabad..13d9eb1ca 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java +++ b/src/main/java/org/springframework/samples/petclinic/web/FindOwnersController.java @@ -23,13 +23,13 @@ import org.springframework.web.bind.annotation.RequestMethod; * @author Arjen Poutsma */ @Controller -public class FindOwnersForm { +public class FindOwnersController { private final Clinic clinic; @Autowired - public FindOwnersForm(Clinic clinic) { + public FindOwnersController(Clinic clinic) { this.clinic = clinic; } diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml index 13330e6ff..56c78c7e9 100755 --- a/src/main/resources/log4j.xml +++ b/src/main/resources/log4j.xml @@ -15,6 +15,10 @@ + + + + diff --git a/src/main/webapp/resources/html/tutorial.html b/src/main/webapp/resources/html/tutorial.html index acc261fb1..40652fe46 100644 --- a/src/main/webapp/resources/html/tutorial.html +++ b/src/main/webapp/resources/html/tutorial.html @@ -819,32 +819,32 @@ that is used to handle simple display-oriented URLs.
  • - org.springframework.samples.petclinic.web.FindOwnersForm + org.springframework.samples.petclinic.web.FindOwnersController is an annotation-driven, POJO Form controller that is used to search for Owners by last name.
  • - org.springframework.samples.petclinic.web.AddOwnerForm + org.springframework.samples.petclinic.web.AddOwnerController is an annotation-driven, POJO Form controller that is used to add a new Owner to the system.
  • - org.springframework.samples.petclinic.web.EditOwnerForm + org.springframework.samples.petclinic.web.EditOwnerController is an annotation-driven, POJO Form controller that is used to edit an existing Owner. A copy of the existing Owner is used for editing.
  • - org.springframework.samples.petclinic.web.AddPetForm + org.springframework.samples.petclinic.web.AddPetController is an annotation-driven, POJO Form controller that is used to add a new Pet to an existing Owner.
  • - org.springframework.samples.petclinic.web.EditPetForm + org.springframework.samples.petclinic.web.EditPetController is an annotation-driven, POJO Form controller that is used to edit an existing Pet. A copy of the existing Pet is used for editing.
  • - org.springframework.samples.petclinic.web.AddVisitForm + org.springframework.samples.petclinic.web.AddVisitController is an annotation-driven, POJO Form controller that is used to add a new Visit to an existing Pet.
  • From 58d82e461a7a0b9ad00d3f6eba8d667f6154a73d Mon Sep 17 00:00:00 2001 From: Mic Date: Thu, 10 Jan 2013 16:12:50 +0800 Subject: [PATCH 074/887] handled all exception messages inside Spring config --- .../petclinic/web/ClinicController.java | 8 ++++--- src/main/webapp/WEB-INF/petclinic-servlet.xml | 23 +++++++++++-------- src/main/webapp/WEB-INF/web.xml | 6 ----- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java b/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java index e93ae8f66..fa9f092c1 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java +++ b/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.Clinic; import org.springframework.samples.petclinic.Vets; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -54,10 +55,11 @@ public class ClinicController { * @return a ModelMap with the model attributes for the view */ @RequestMapping("/vets") - public ModelMap vetsHandler() { + public String showVetList(Model model) { Vets vets = new Vets(); vets.getVetList().addAll(this.clinic.getVets()); - return new ModelMap(vets); + model.addAttribute("vets", vets); + return "vets"; } /** @@ -67,7 +69,7 @@ public class ClinicController { * @return a ModelMap with the model attributes for the view */ @RequestMapping("/owners/{ownerId}") - public ModelAndView ownerHandler(@PathVariable("ownerId") int ownerId) { + public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { ModelAndView mav = new ModelAndView("owners/show"); mav.addObject(this.clinic.loadOwner(ownerId)); return mav; diff --git a/src/main/webapp/WEB-INF/petclinic-servlet.xml b/src/main/webapp/WEB-INF/petclinic-servlet.xml index 345a2da8a..4c56a4236 100644 --- a/src/main/webapp/WEB-INF/petclinic-servlet.xml +++ b/src/main/webapp/WEB-INF/petclinic-servlet.xml @@ -5,7 +5,7 @@ @@ -30,7 +30,7 @@ - This bean processes annotated handler methods, applying PetClinic-specific PropertyEditors - for request parameter binding. It overrides the default AnnotationMethodHandlerAdapter. --> - + @@ -50,6 +50,7 @@ dataAccessFailure + - + + @@ -69,7 +71,8 @@ atom=application/atom+xml - xml=#{vets.contentType} + html=text/html + xml=application/xml @@ -77,11 +80,11 @@ - + + p:suffix=".jsp" /> - + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 768329b1b..43c322bd5 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -161,12 +161,6 @@ 10 - - java.lang.Exception - - /WEB-INF/jsp/uncaughtException.jsp - - From 5139c8d3bc661361440732c237682e38e6c23a2f Mon Sep 17 00:00:00 2001 From: Mic Date: Mon, 14 Jan 2013 00:08:37 +0800 Subject: [PATCH 075/887] added header to all JSPs --- src/main/webapp/WEB-INF/jsp/owners/form.jsp | 7 +- src/main/webapp/WEB-INF/jsp/owners/list.jsp | 75 ++++++++++--------- src/main/webapp/WEB-INF/jsp/owners/search.jsp | 6 +- src/main/webapp/WEB-INF/jsp/owners/show.jsp | 4 + src/main/webapp/WEB-INF/jsp/pets/form.jsp | 6 +- .../webapp/WEB-INF/jsp/pets/visitForm.jsp | 6 +- src/main/webapp/WEB-INF/jsp/vets.jsp | 74 +++++++++--------- src/main/webapp/WEB-INF/jsp/welcome.jsp | 4 + 8 files changed, 106 insertions(+), 76 deletions(-) diff --git a/src/main/webapp/WEB-INF/jsp/owners/form.jsp b/src/main/webapp/WEB-INF/jsp/owners/form.jsp index 208f521f4..6ebdf2853 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/form.jsp @@ -10,8 +10,11 @@ - -
    + +
    diff --git a/src/main/webapp/WEB-INF/jsp/owners/list.jsp b/src/main/webapp/WEB-INF/jsp/owners/list.jsp index b28ce6b6b..cb679b019 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/list.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/list.jsp @@ -9,43 +9,46 @@ + +
    -
    - -

    Owners:

    - - - - - - - - - - - - - - - - - - - - -
    NameAddressCityTelephonePets
    - - - - ${owner.firstName} ${owner.lastName} - ${owner.address}${owner.city}${owner.telephone} - - ${pet.name}   - -
    - -
    - +

    Owners:

    + + + + + + + + + + + + + + + + + + + + +
    NameAddressCityTelephonePets
    + + + + ${owner.firstName} ${owner.lastName} + ${owner.address}${owner.city}${owner.telephone} + + ${pet.name}   + +
    + +
    + diff --git a/src/main/webapp/WEB-INF/jsp/owners/search.jsp b/src/main/webapp/WEB-INF/jsp/owners/search.jsp index 7b6b5c880..1a1614f5e 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/search.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/search.jsp @@ -9,7 +9,11 @@ -
    + +

    Find Owners:

    diff --git a/src/main/webapp/WEB-INF/jsp/owners/show.jsp b/src/main/webapp/WEB-INF/jsp/owners/show.jsp index 077d8cff5..60c0c031a 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/show.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/show.jsp @@ -9,6 +9,10 @@ +

    Owner Information

    diff --git a/src/main/webapp/WEB-INF/jsp/pets/form.jsp b/src/main/webapp/WEB-INF/jsp/pets/form.jsp index ec06dc162..c3d942715 100644 --- a/src/main/webapp/WEB-INF/jsp/pets/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/pets/form.jsp @@ -8,8 +8,12 @@ + -
    +
    diff --git a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp index 08dda8e81..0756eedab 100644 --- a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp @@ -9,8 +9,12 @@ + -
    +

    New Visit:

    diff --git a/src/main/webapp/WEB-INF/jsp/vets.jsp b/src/main/webapp/WEB-INF/jsp/vets.jsp index 81f3fdfe3..8c12018f0 100644 --- a/src/main/webapp/WEB-INF/jsp/vets.jsp +++ b/src/main/webapp/WEB-INF/jsp/vets.jsp @@ -8,42 +8,46 @@ - -
    - -

    Veterinarians:

    + - - - - - - - - - - - - - - - -
    NameSpecialties
    ${vet.firstName} ${vet.lastName} - - ${specialty.name} - - none -
    - - - - -
    - ">View as XML -
    +
    -
    - - +

    Veterinarians:

    + + + + + + + + + + + + + + + + +
    NameSpecialties
    ${vet.firstName} ${vet.lastName} + + ${specialty.name} + + none +
    + + + + +
    + ">View as XML +
    + +
    + + diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp index 9cddcd629..95270b8f8 100644 --- a/src/main/webapp/WEB-INF/jsp/welcome.jsp +++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp @@ -7,6 +7,10 @@ +
    " align="right" style="position:relative;right:30px;"> From 9a77b56427760d4b9d602a9846099c3deeeef32c Mon Sep 17 00:00:00 2001 From: Mic Date: Mon, 14 Jan 2013 11:02:08 +0800 Subject: [PATCH 076/887] cleaned up CSS and migrated to Bootstrap --- pom.xml | 9 +- src/main/webapp/WEB-INF/jsp/header.jsp | 12 +- src/main/webapp/WEB-INF/jsp/owners/form.jsp | 105 ++++---- src/main/webapp/WEB-INF/jsp/owners/list.jsp | 11 +- src/main/webapp/WEB-INF/jsp/owners/search.jsp | 16 +- src/main/webapp/WEB-INF/jsp/owners/show.jsp | 15 +- src/main/webapp/WEB-INF/jsp/pets/form.jsp | 6 +- .../webapp/WEB-INF/jsp/pets/visitForm.jsp | 8 +- src/main/webapp/WEB-INF/jsp/vets.jsp | 10 +- src/main/webapp/WEB-INF/jsp/welcome.jsp | 11 +- src/main/webapp/WEB-INF/petclinic-servlet.xml | 3 + .../spring/applicationContext-jdbc.xml | 2 +- src/main/webapp/resources/css/petclinic.css | 5 + .../webapp/resources/styles/petclinic.css | 234 ------------------ 14 files changed, 108 insertions(+), 339 deletions(-) create mode 100644 src/main/webapp/resources/css/petclinic.css delete mode 100644 src/main/webapp/resources/styles/petclinic.css diff --git a/pom.xml b/pom.xml index a60fcf2ce..a5606ea93 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,14 @@ jstl 1.2 - + + + + org.webjars + bootstrap + 2.2.1 + + rome diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp index 1cdc67061..7ca657876 100644 --- a/src/main/webapp/WEB-INF/jsp/header.jsp +++ b/src/main/webapp/WEB-INF/jsp/header.jsp @@ -5,9 +5,15 @@ --> - - " type="text/css"/> - PetClinic :: a Spring Framework demonstration + + PetClinic :: a Spring Framework demonstration + + + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/owners/form.jsp b/src/main/webapp/WEB-INF/jsp/owners/form.jsp index 6ebdf2853..f051703a1 100644 --- a/src/main/webapp/WEB-INF/jsp/owners/form.jsp +++ b/src/main/webapp/WEB-INF/jsp/owners/form.jsp @@ -10,69 +10,66 @@ -